@cyclonedx/cdxgen 10.4.0 → 10.4.2

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
@@ -232,7 +232,7 @@ export function getAllFiles(dirPath, pattern, options = {}) {
232
232
  if (!pattern.includes("package.json")) {
233
233
  ignoreList.push("**/node_modules/**");
234
234
  }
235
- if (options && options.exclude && Array.isArray(options.exclude)) {
235
+ if (options?.exclude && Array.isArray(options.exclude)) {
236
236
  ignoreList = ignoreList.concat(options.exclude);
237
237
  }
238
238
  return getAllFilesWithIgnore(dirPath, pattern, ignoreList);
@@ -280,7 +280,7 @@ function toBase64(hexString) {
280
280
  * @returns {string} ISO formatted timestamp, without milliseconds.
281
281
  */
282
282
  export function getTimestamp() {
283
- return new Date().toISOString().split(".")[0] + "Z";
283
+ return `${new Date().toISOString().split(".")[0]}Z`;
284
284
  }
285
285
 
286
286
  /**
@@ -328,15 +328,13 @@ export function adjustLicenseInformation(licenses) {
328
328
  console.warn("multiple license expressions found", expressions);
329
329
  }
330
330
  return [{ expression: expressions[0].expression }];
331
- } else {
332
- return licenses.map((l) => {
333
- if (typeof l.license === "object") {
334
- return l;
335
- } else {
336
- return { license: l };
337
- }
338
- });
339
331
  }
332
+ return licenses.map((l) => {
333
+ if (typeof l.license === "object") {
334
+ return l;
335
+ }
336
+ return { license: l };
337
+ });
340
338
  }
341
339
 
342
340
  /**
@@ -361,7 +359,7 @@ export function getLicenses(pkg) {
361
359
  })
362
360
  ) {
363
361
  licenseContent.id = l;
364
- licenseContent.url = "https://opensource.org/licenses/" + l;
362
+ licenseContent.url = `https://opensource.org/licenses/${l}`;
365
363
  } else if (l.startsWith("http")) {
366
364
  const knownLicense = getKnownLicense(l, pkg);
367
365
  if (knownLicense) {
@@ -390,11 +388,10 @@ export function getLicenses(pkg) {
390
388
  return licenseContent;
391
389
  }),
392
390
  );
393
- } else {
394
- const knownLicense = getKnownLicense(undefined, pkg);
395
- if (knownLicense) {
396
- return [{ license: knownLicense }];
397
- }
391
+ }
392
+ const knownLicense = getKnownLicense(undefined, pkg);
393
+ if (knownLicense) {
394
+ return [{ license: knownLicense }];
398
395
  }
399
396
  return undefined;
400
397
  }
@@ -407,7 +404,7 @@ export function getLicenses(pkg) {
407
404
  * @return {Object} Objetct with SPDX license id or license name
408
405
  */
409
406
  export function getKnownLicense(licenseUrl, pkg) {
410
- if (licenseUrl && licenseUrl.includes("opensource.org")) {
407
+ if (licenseUrl?.includes("opensource.org")) {
411
408
  const possibleId = licenseUrl
412
409
  .toLowerCase()
413
410
  .replace("https://", "http://")
@@ -417,7 +414,7 @@ export function getKnownLicense(licenseUrl, pkg) {
417
414
  return { id: spdxLicense };
418
415
  }
419
416
  }
420
- } else if (licenseUrl && licenseUrl.includes("apache.org")) {
417
+ } else if (licenseUrl?.includes("apache.org")) {
421
418
  const possibleId = licenseUrl
422
419
  .toLowerCase()
423
420
  .replace("https://", "http://")
@@ -432,15 +429,15 @@ export function getKnownLicense(licenseUrl, pkg) {
432
429
  for (const akLicGroup of knownLicenses) {
433
430
  if (
434
431
  akLicGroup.packageNamespace === "*" ||
435
- (pkg.purl && pkg.purl.startsWith(akLicGroup.packageNamespace))
432
+ pkg.purl?.startsWith(akLicGroup.packageNamespace)
436
433
  ) {
437
434
  for (const akLic of akLicGroup.knownLicenses) {
438
435
  if (akLic.group && akLic.name) {
439
436
  if (akLic.group === "." && akLic.name === pkg.name) {
440
437
  return { id: akLic.license, name: akLic.licenseName };
441
- } else if (
442
- pkg.group &&
443
- pkg.group.includes(akLic.group) &&
438
+ }
439
+ if (
440
+ pkg.group?.includes(akLic.group) &&
444
441
  (akLic.name === pkg.name || akLic.name === "*")
445
442
  ) {
446
443
  return { id: akLic.license, name: akLic.licenseName };
@@ -528,7 +525,7 @@ export function readLicenseText(licenseFilepath, licenseContentType) {
528
525
  export async function getSwiftPackageMetadata(pkgList) {
529
526
  const cdepList = [];
530
527
  for (const p of pkgList) {
531
- if (p.repository && p.repository.url) {
528
+ if (p.repository?.url) {
532
529
  if (p.repository.url.includes("://github.com/")) {
533
530
  try {
534
531
  p.license = await getRepoLicense(p.repository.url, undefined);
@@ -567,9 +564,9 @@ export async function getNpmMetadata(pkgList) {
567
564
  if (p.group && p.group !== "") {
568
565
  let group = p.group;
569
566
  if (!group.startsWith("@")) {
570
- group = "@" + group;
567
+ group = `@${group}`;
571
568
  }
572
- key = group + "/" + p.name;
569
+ key = `${group}/${p.name}`;
573
570
  }
574
571
  let body = {};
575
572
  if (metadata_cache[key]) {
@@ -587,7 +584,7 @@ export async function getNpmMetadata(pkgList) {
587
584
  body.versions?.[p.version]?.license ||
588
585
  body.license ||
589
586
  (await getRepoLicense(body.repository?.url, undefined));
590
- if (body.repository && body.repository.url) {
587
+ if (body.repository?.url) {
591
588
  p.repository = { url: body.repository.url };
592
589
  }
593
590
  if (body.homepage) {
@@ -652,7 +649,7 @@ export async function parsePkgJson(pkgJsonFile, simple = false) {
652
649
  if (pkgData.homepage) {
653
650
  apkg.homepage = { url: pkgData.homepage };
654
651
  }
655
- if (pkgData.repository && pkgData.repository.url) {
652
+ if (pkgData.repository?.url) {
656
653
  apkg.repository = { url: pkgData.repository.url };
657
654
  }
658
655
  if (!simple) {
@@ -742,7 +739,7 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
742
739
  author.url ? ` (${author.url})` : ""
743
740
  }`
744
741
  : author;
745
- if (node == rootNode) {
742
+ if (node === rootNode) {
746
743
  purlString = new PackageURL(
747
744
  "npm",
748
745
  options.projectGroup || "",
@@ -858,7 +855,7 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
858
855
  // this handles the case when a node has ["dependencies"] key in a package-lock.json
859
856
  // for a node. We exclude the root node because it's already been handled
860
857
  const childrenDependsOn = [];
861
- if (node != rootNode) {
858
+ if (node !== rootNode) {
862
859
  for (const child of node.children) {
863
860
  const childNode = child[1];
864
861
  const {
@@ -936,8 +933,8 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
936
933
  for (const child of rootNode.children) {
937
934
  if (
938
935
  edgeToIntegrityOrLocation &&
939
- (child[1].integrity == edgeToIntegrityOrLocation ||
940
- child[1].location == edgeToIntegrityOrLocation)
936
+ (child[1].integrity === edgeToIntegrityOrLocation ||
937
+ child[1].location === edgeToIntegrityOrLocation)
941
938
  ) {
942
939
  targetName = child[0].replace(/node_modules\//g, "");
943
940
  targetVersion = child[1].version;
@@ -1057,7 +1054,7 @@ export function yarnLockToIdentMap(lockData) {
1057
1054
  // "@actions/core@^1.2.6", "@actions/core@^1.6.0":
1058
1055
  if (!l.startsWith(" ") && l.trim().length > 0) {
1059
1056
  const tmpA = l.replace(/["']/g, "").split(", ");
1060
- if (tmpA && tmpA.length) {
1057
+ if (tmpA?.length) {
1061
1058
  for (let s of tmpA) {
1062
1059
  if (!s.startsWith("__")) {
1063
1060
  if (s.endsWith(":")) {
@@ -1079,7 +1076,7 @@ export function yarnLockToIdentMap(lockData) {
1079
1076
  // - npm:@types/ioredis@^4.28.10
1080
1077
  // - npm:strip-ansi@^6.0.1
1081
1078
  // See test cases with yarn3.lock and yarn6.lock
1082
- if (range && range.startsWith("npm:")) {
1079
+ if (range?.startsWith("npm:")) {
1083
1080
  if (range.includes("@")) {
1084
1081
  range = range.split("@").slice(-1)[0];
1085
1082
  } else {
@@ -1236,7 +1233,7 @@ export async function parseYarnLock(yarnLockFile) {
1236
1233
  name = parsedline.name;
1237
1234
  } else {
1238
1235
  let fullName = parsedline.name;
1239
- if (parsedline.group && parsedline.group.length) {
1236
+ if (parsedline.group?.length) {
1240
1237
  fullName = `${parsedline.group}/${parsedline.name}`;
1241
1238
  }
1242
1239
  if (
@@ -1295,14 +1292,15 @@ export async function parseYarnLock(yarnLockFile) {
1295
1292
  // in some cases yarn 4 will add a prefix to the checksum, containing the cachekey and compression level
1296
1293
  // example: 10c0/53c2b231a61a46792b39a0d43bc4f4f77...
1297
1294
  const checksum = parts[1].split("/").pop();
1298
- integrity =
1299
- "sha512-" + Buffer.from(checksum, "hex").toString("base64");
1295
+ integrity = `sha512-${Buffer.from(checksum, "hex").toString(
1296
+ "base64",
1297
+ )}`;
1300
1298
  }
1301
1299
  if (l.startsWith("resolved")) {
1302
1300
  const tmpB = parts[1].split("#");
1303
1301
  if (tmpB.length > 1) {
1304
1302
  const digest = tmpB[1].replace(/"/g, "");
1305
- integrity = "sha256-" + digest;
1303
+ integrity = `sha256-${digest}`;
1306
1304
  }
1307
1305
  }
1308
1306
  }
@@ -1340,7 +1338,7 @@ export async function parseNodeShrinkwrap(swFile) {
1340
1338
  const fullName = pkgKeys[k];
1341
1339
  const integrity = lockData[fullName];
1342
1340
  const parts = fullName.split("@");
1343
- if (parts && parts.length) {
1341
+ if (parts?.length) {
1344
1342
  let name = "";
1345
1343
  let version = "";
1346
1344
  let group = "";
@@ -1406,7 +1404,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
1406
1404
  let pkgList = [];
1407
1405
  const dependenciesList = [];
1408
1406
  let ppurl = "";
1409
- if (parentComponent && parentComponent.name) {
1407
+ if (parentComponent?.name) {
1410
1408
  ppurl =
1411
1409
  parentComponent.purl ||
1412
1410
  new PackageURL(
@@ -1471,7 +1469,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
1471
1469
  const integrity = packages[pkgKeys[k]].resolution.integrity;
1472
1470
  const deps = packages[pkgKeys[k]].dependencies || [];
1473
1471
  const scope = packages[pkgKeys[k]].dev === true ? "optional" : undefined;
1474
- if (parts && parts.length) {
1472
+ if (parts?.length) {
1475
1473
  let name = "";
1476
1474
  let version = "";
1477
1475
  let group = "";
@@ -1669,7 +1667,7 @@ export async function parseMinJs(minJsFile) {
1669
1667
  return;
1670
1668
  }
1671
1669
  const pkgIdentifier = parsePackageJsonName(name);
1672
- if (pkgIdentifier.fullName != "") {
1670
+ if (pkgIdentifier.fullName !== "") {
1673
1671
  pkgList.push({
1674
1672
  name: pkgIdentifier.fullName,
1675
1673
  group: pkgIdentifier.scope || "",
@@ -1728,7 +1726,7 @@ export function parsePom(pomFile) {
1728
1726
  attributesKey: "$",
1729
1727
  commentKey: "value",
1730
1728
  }).project;
1731
- if (project && project.dependencies) {
1729
+ if (project?.dependencies) {
1732
1730
  let dependencies = project.dependencies.dependency;
1733
1731
  // Convert to an array
1734
1732
  if (!dependencies) {
@@ -1739,7 +1737,7 @@ export function parsePom(pomFile) {
1739
1737
  for (const adep of dependencies) {
1740
1738
  const version = adep.version;
1741
1739
  let versionStr = undefined;
1742
- if (version && version._ && version._.indexOf("$") == -1) {
1740
+ if (version?._ && version._.indexOf("$") === -1) {
1743
1741
  versionStr = version._;
1744
1742
  if (includeMavenTestScope || !adep.scope || adep.scope !== "test")
1745
1743
  deps.push({
@@ -1796,7 +1794,7 @@ export function parseMavenTree(rawOutput) {
1796
1794
  }
1797
1795
  let level = 0;
1798
1796
  const tmpline = l.split(" ");
1799
- if (tmpline && tmpline.length) {
1797
+ if (tmpline?.length) {
1800
1798
  if (l.includes(" ")) {
1801
1799
  level = l.replace(tmpline[tmpline.length - 1], "").length / 3;
1802
1800
  }
@@ -1804,10 +1802,10 @@ export function parseMavenTree(rawOutput) {
1804
1802
  const pkgArr = l.split(":");
1805
1803
  if (pkgArr && pkgArr.length > 2) {
1806
1804
  let versionStr = pkgArr[pkgArr.length - 2];
1807
- if (pkgArr.length == 4) {
1805
+ if (pkgArr.length === 4) {
1808
1806
  versionStr = pkgArr[pkgArr.length - 1];
1809
1807
  }
1810
- const key = pkgArr[0] + "-" + pkgArr[1] + "-" + versionStr;
1808
+ const key = `${pkgArr[0]}-${pkgArr[1]}-${versionStr}`;
1811
1809
  if (!keys_cache[key]) {
1812
1810
  keys_cache[key] = key;
1813
1811
  let purlString = new PackageURL(
@@ -1828,7 +1826,7 @@ export function parseMavenTree(rawOutput) {
1828
1826
  if (!level_trees[purlString]) {
1829
1827
  level_trees[purlString] = [];
1830
1828
  }
1831
- if (level == 0 || last_purl === "") {
1829
+ if (level === 0 || last_purl === "") {
1832
1830
  stack.push(purlString);
1833
1831
  } else if (level > last_level) {
1834
1832
  const cnodes = level_trees[last_purl] || [];
@@ -1921,7 +1919,7 @@ export function parseGradleDep(
1921
1919
  level_trees[last_purl] = [];
1922
1920
  let scope = undefined;
1923
1921
  let profileName = undefined;
1924
- if (retMap && retMap.projects) {
1922
+ if (retMap?.projects) {
1925
1923
  const subDependsOn = [];
1926
1924
  for (const sd of retMap.projects) {
1927
1925
  subDependsOn.push(
@@ -2008,7 +2006,7 @@ export function parseGradleDep(
2008
2006
  null,
2009
2007
  ).toString();
2010
2008
  purlString = decodeURIComponent(purlString);
2011
- keys_cache[purlString + "_" + last_purl] = true;
2009
+ keys_cache[`${purlString}_${last_purl}`] = true;
2012
2010
  // Filter duplicates
2013
2011
  if (!deps_keys_cache[purlString]) {
2014
2012
  deps_keys_cache[purlString] = true;
@@ -2036,7 +2034,7 @@ export function parseGradleDep(
2036
2034
  if (!level_trees[purlString]) {
2037
2035
  level_trees[purlString] = [];
2038
2036
  }
2039
- if (level == 0) {
2037
+ if (level === 0) {
2040
2038
  stack = [first_purl];
2041
2039
  stack.push(purlString);
2042
2040
  } else if (last_purl === "") {
@@ -2098,14 +2096,14 @@ export function parseCljDep(rawOutput) {
2098
2096
  l = l.replace(". ", "");
2099
2097
  }
2100
2098
  const tmpArr = l.split(" ");
2101
- if (tmpArr.length == 2) {
2099
+ if (tmpArr.length === 2) {
2102
2100
  let group = dirname(tmpArr[0]);
2103
2101
  if (group === ".") {
2104
2102
  group = "";
2105
2103
  }
2106
2104
  const name = basename(tmpArr[0]);
2107
2105
  const version = tmpArr[1];
2108
- const cacheKey = group + "-" + name + "-" + version;
2106
+ const cacheKey = `${group}-${name}-${version}`;
2109
2107
  if (!keys_cache[cacheKey]) {
2110
2108
  keys_cache[cacheKey] = true;
2111
2109
  deps.push({
@@ -2131,7 +2129,7 @@ export function parseLeinDep(rawOutput) {
2131
2129
  const deps = [];
2132
2130
  const keys_cache = {};
2133
2131
  if (rawOutput.includes("{[") && !rawOutput.startsWith("{[")) {
2134
- rawOutput = "{[" + rawOutput.split("{[")[1];
2132
+ rawOutput = `{[${rawOutput.split("{[")[1]}`;
2135
2133
  }
2136
2134
  const ednData = parseEDNString(rawOutput);
2137
2135
  return parseLeinMap(ednData, keys_cache, deps);
@@ -2151,7 +2149,7 @@ export function parseLeinMap(node, keys_cache, deps) {
2151
2149
  group = "";
2152
2150
  }
2153
2151
  const name = basename(psym);
2154
- const cacheKey = group + "-" + name + "-" + version;
2152
+ const cacheKey = `${group}-${name}-${version}`;
2155
2153
  if (!keys_cache[cacheKey]) {
2156
2154
  keys_cache[cacheKey] = true;
2157
2155
  deps.push({ group, name, version });
@@ -2312,15 +2310,17 @@ export function executeGradleProperties(dir, rootPath, subProject) {
2312
2310
  if (result.stderr) {
2313
2311
  if (result.stderr.includes("does not exist")) {
2314
2312
  return defaultProps;
2315
- } else {
2316
- console.error(result.stdout, result.stderr);
2317
- console.log(
2318
- "1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 21 with gradle 8 which might be incompatible.",
2319
- );
2320
2313
  }
2314
+ console.error(result.stdout, result.stderr);
2315
+ console.log(
2316
+ "1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 21 with gradle 8 which might be incompatible.",
2317
+ );
2318
+ console.log(
2319
+ "2. Try running cdxgen with the unofficial JDK11-based image `ghcr.io/appthreat/cdxgen-java:v10`.",
2320
+ );
2321
2321
  if (result.stderr.includes("not get unknown property")) {
2322
2322
  console.log(
2323
- "2. Check if the SBOM is generated for the correct root project for your application.",
2323
+ "3. Check if the SBOM is generated for the correct root project for your application.",
2324
2324
  );
2325
2325
  }
2326
2326
  }
@@ -2357,7 +2357,7 @@ export function parseBazelActionGraph(rawOutput) {
2357
2357
  ) {
2358
2358
  const matches = Array.from(l.matchAll(mavenPrefixRegex));
2359
2359
 
2360
- if (matches[0] && matches[0][1]) {
2360
+ if (matches[0]?.[1]) {
2361
2361
  const group = matches[0][1].split("/").join(".");
2362
2362
  const name = matches[0][2];
2363
2363
  const version = matches[0][3];
@@ -2399,7 +2399,7 @@ export function parseBazelSkyframe(rawOutput) {
2399
2399
  l = l.split(",")[0];
2400
2400
  }
2401
2401
  const mparts = l.split("external/maven/v1/");
2402
- if (mparts && mparts[mparts.length - 1].endsWith(".jar")) {
2402
+ if (mparts?.[mparts.length - 1].endsWith(".jar")) {
2403
2403
  // Example
2404
2404
  // https/jcenter.bintray.com/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
2405
2405
  // https/repo1.maven.org/maven2/org/simpleflatmapper/sfm-util/8.2.2/header_sfmutil-8.2.2.jar
@@ -2615,12 +2615,11 @@ export async function getMvnMetadata(pkgList, jarNSMapping = {}) {
2615
2615
  );
2616
2616
  }
2617
2617
  const bodyJson = await fetchPomXmlAsJson(pomMetadata);
2618
- p.publisher =
2619
- bodyJson.organization && bodyJson.organization.name
2620
- ? bodyJson.organization.name._
2621
- : "";
2618
+ p.publisher = bodyJson.organization?.name
2619
+ ? bodyJson.organization.name._
2620
+ : "";
2622
2621
  p.description = bodyJson.description ? bodyJson.description._ : "";
2623
- if (bodyJson.scm && bodyJson.scm.url) {
2622
+ if (bodyJson.scm?.url) {
2624
2623
  p.repository = { url: bodyJson.scm.url._ };
2625
2624
  }
2626
2625
  p.license =
@@ -2653,18 +2652,9 @@ export async function getMvnMetadata(pkgList, jarNSMapping = {}) {
2653
2652
  */
2654
2653
  export function composePomXmlUrl({ urlPrefix, group, name, version }) {
2655
2654
  const groupPart = group.replace(/\./g, "/");
2656
- const fullUrl =
2657
- urlPrefix +
2658
- groupPart +
2659
- "/" +
2660
- name +
2661
- "/" +
2662
- version +
2663
- "/" +
2664
- name +
2665
- "-" +
2666
- version +
2667
- ".pom";
2655
+ const fullUrl = `${
2656
+ urlPrefix + groupPart
2657
+ }/${name}/${version}/${name}-${version}.pom`;
2668
2658
  return fullUrl;
2669
2659
  }
2670
2660
 
@@ -2729,7 +2719,8 @@ export function parseLicenseEntryOrArrayFromPomXml(license) {
2729
2719
  return license.map((l) => {
2730
2720
  return findLicenseId(l.name._);
2731
2721
  });
2732
- } else if (Object.keys(license).length) {
2722
+ }
2723
+ if (Object.keys(license).length) {
2733
2724
  return [findLicenseId(license.name._)];
2734
2725
  }
2735
2726
  }
@@ -2753,7 +2744,7 @@ export async function extractLicenseCommentFromPomXml({
2753
2744
  const pom_xml = await fetchPomXml({ urlPrefix, group, name, version });
2754
2745
  const licenseRegex = /<!--([\s\S]*?)-->[\s\n]*<project/m;
2755
2746
  const match = licenseRegex.exec(pom_xml);
2756
- if (match && match[1]) {
2747
+ if (match?.[1]) {
2757
2748
  return findLicenseId(match[1].trim());
2758
2749
  }
2759
2750
  }
@@ -2772,7 +2763,8 @@ export function parsePyRequiresDist(dist_string) {
2772
2763
  let version = "";
2773
2764
  if (!tmpA) {
2774
2765
  return undefined;
2775
- } else if (tmpA.length == 1) {
2766
+ }
2767
+ if (tmpA.length === 1) {
2776
2768
  name = tmpA[0];
2777
2769
  } else if (tmpA.length > 1) {
2778
2770
  name = tmpA[0];
@@ -2840,15 +2832,15 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
2840
2832
  }
2841
2833
  let res = undefined;
2842
2834
  try {
2843
- res = await cdxgenAgent.get(PYPI_URL + p.name + "/json", {
2835
+ res = await cdxgenAgent.get(`${PYPI_URL + p.name}/json`, {
2844
2836
  responseType: "json",
2845
2837
  });
2846
2838
  } catch (err) {
2847
2839
  // retry by prefixing django- to the package name
2848
- res = await cdxgenAgent.get(PYPI_URL + "django-" + p.name + "/json", {
2840
+ res = await cdxgenAgent.get(`${PYPI_URL}django-${p.name}/json`, {
2849
2841
  responseType: "json",
2850
2842
  });
2851
- p.name = "django-" + p.name;
2843
+ p.name = `django-${p.name}`;
2852
2844
  }
2853
2845
  const body = res.body;
2854
2846
  if (body.info.author && body.info.author.trim() !== "") {
@@ -2892,7 +2884,7 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
2892
2884
  // Use the latest version if none specified
2893
2885
  if (!p.version || !p.version.trim().length) {
2894
2886
  let versionSpecifiers = undefined;
2895
- if (p.properties && p.properties.length) {
2887
+ if (p.properties?.length) {
2896
2888
  for (const pprop of p.properties) {
2897
2889
  if (pprop.name === "cdx:pypi:versionSpecifiers") {
2898
2890
  versionSpecifiers = pprop.value;
@@ -2960,16 +2952,12 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
2960
2952
  value: origName,
2961
2953
  });
2962
2954
  }
2963
- if (
2964
- body.releases &&
2965
- body.releases[p.version] &&
2966
- body.releases[p.version].length
2967
- ) {
2955
+ if (body.releases?.[p.version] && body.releases[p.version].length) {
2968
2956
  const digest = body.releases[p.version][0].digests;
2969
2957
  if (digest["sha256"]) {
2970
- p._integrity = "sha256-" + digest["sha256"];
2958
+ p._integrity = `sha256-${digest["sha256"]}`;
2971
2959
  } else if (digest["md5"]) {
2972
- p._integrity = "md5-" + digest["md5"];
2960
+ p._integrity = `md5-${digest["md5"]}`;
2973
2961
  }
2974
2962
  }
2975
2963
  const purlString = new PackageURL(
@@ -3163,7 +3151,7 @@ export async function parsePoetrylockData(lockData, lockFile) {
3163
3151
  ) {
3164
3152
  // Package dependencies starts with this marker
3165
3153
  depsMode = l.includes("[package.dependencies]");
3166
- if (pkg && pkg.name && pkg.version) {
3154
+ if (pkg?.name && pkg.version) {
3167
3155
  const purlString = new PackageURL(
3168
3156
  "pypi",
3169
3157
  "",
@@ -3222,7 +3210,7 @@ export async function parsePoetrylockData(lockData, lockFile) {
3222
3210
  pkg.version = value;
3223
3211
  break;
3224
3212
  case "optional":
3225
- pkg.scope = value == "true" ? "optional" : undefined;
3213
+ pkg.scope = value === "true" ? "optional" : undefined;
3226
3214
  break;
3227
3215
  }
3228
3216
  }
@@ -3236,8 +3224,8 @@ export async function parsePoetrylockData(lockData, lockFile) {
3236
3224
  dependsOnList.push(adep);
3237
3225
  } else if (existingPkgMap[adep]) {
3238
3226
  dependsOnList.push(existingPkgMap[adep]);
3239
- } else if (existingPkgMap["py" + adep]) {
3240
- dependsOnList.push(existingPkgMap["py" + adep]);
3227
+ } else if (existingPkgMap[`py${adep}`]) {
3228
+ dependsOnList.push(existingPkgMap[`py${adep}`]);
3241
3229
  } else if (existingPkgMap[adep.replace(/-/g, "_")]) {
3242
3230
  dependsOnList.push(existingPkgMap[adep.replace(/-/g, "_")]);
3243
3231
  }
@@ -3443,7 +3431,7 @@ export async function getPyModules(src, epkgList, options) {
3443
3431
  PYPI_MODULE_PACKAGE_MAPPING[p.name.toLowerCase()] ||
3444
3432
  PYPI_MODULE_PACKAGE_MAPPING[p.name.replace(/_/g, "-").toLowerCase()] ||
3445
3433
  p.name.replace(/_/g, "-").toLowerCase(),
3446
- version: p.version && p.version.trim().length ? p.version : undefined,
3434
+ version: p.version?.trim().length ? p.version : undefined,
3447
3435
  scope: "required",
3448
3436
  properties: [
3449
3437
  {
@@ -3463,13 +3451,13 @@ export async function getPyModules(src, epkgList, options) {
3463
3451
  pkgList = pkgList.filter(
3464
3452
  (obj, index) => pkgList.findIndex((i) => i.name === obj.name) === index,
3465
3453
  );
3466
- if (epkgList && epkgList.length) {
3454
+ if (epkgList?.length) {
3467
3455
  const pkgMaps = epkgList.map((p) => p.name);
3468
3456
  pkgList = pkgList.filter((p) => !pkgMaps.includes(p.name));
3469
3457
  }
3470
3458
  pkgList = await getPyMetadata(pkgList, true);
3471
3459
  // Populate the imports list after dealiasing
3472
- if (pkgList && pkgList.length) {
3460
+ if (pkgList?.length) {
3473
3461
  pkgList.forEach((p) => {
3474
3462
  allImports[p.name] = true;
3475
3463
  });
@@ -3523,14 +3511,13 @@ export function repoMetadataToGitHubApiUrl(repoMetadata) {
3523
3511
  const group = repoMetadata.group;
3524
3512
  const name = repoMetadata.name;
3525
3513
  let ghUrl = "https://api.github.com/repos";
3526
- if (group && group !== "." && group != "") {
3527
- ghUrl = ghUrl + "/" + group.replace("github.com/", "");
3514
+ if (group && group !== "." && group !== "") {
3515
+ ghUrl = `${ghUrl}/${group.replace("github.com/", "")}`;
3528
3516
  }
3529
- ghUrl = ghUrl + "/" + name;
3517
+ ghUrl = `${ghUrl}/${name}`;
3530
3518
  return ghUrl;
3531
- } else {
3532
- return undefined;
3533
3519
  }
3520
+ return undefined;
3534
3521
  }
3535
3522
 
3536
3523
  /**
@@ -3560,12 +3547,11 @@ export function toGitHubApiUrl(repoUrl, repoMetadata) {
3560
3547
  const parts = getGithubUrlParts(repoUrl);
3561
3548
  if (parts.length < 5 || parts[2] !== "github.com") {
3562
3549
  return undefined; // Not a valid GitHub repo URL
3563
- } else {
3564
- return repoMetadataToGitHubApiUrl({
3565
- group: parts[3],
3566
- name: parts[4],
3567
- });
3568
3550
  }
3551
+ return repoMetadataToGitHubApiUrl({
3552
+ group: parts[3],
3553
+ name: parts[4],
3554
+ });
3569
3555
  }
3570
3556
 
3571
3557
  /**
@@ -3579,17 +3565,17 @@ export async function getRepoLicense(repoUrl, repoMetadata) {
3579
3565
  const apiUrl = toGitHubApiUrl(repoUrl, repoMetadata);
3580
3566
  // Perform github lookups
3581
3567
  if (apiUrl && get_repo_license_errors < MAX_GET_REPO_LICENSE_ERRORS) {
3582
- const licenseUrl = apiUrl + "/license";
3568
+ const licenseUrl = `${apiUrl}/license`;
3583
3569
  const headers = {};
3584
3570
  if (process.env.GITHUB_TOKEN) {
3585
- headers["Authorization"] = "Bearer " + process.env.GITHUB_TOKEN;
3571
+ headers["Authorization"] = `Bearer ${process.env.GITHUB_TOKEN}`;
3586
3572
  }
3587
3573
  try {
3588
3574
  const res = await cdxgenAgent.get(licenseUrl, {
3589
3575
  responseType: "json",
3590
3576
  headers: headers,
3591
3577
  });
3592
- if (res && res.body) {
3578
+ if (res?.body) {
3593
3579
  const license = res.body.license;
3594
3580
  let licenseId = license.spdx_id;
3595
3581
  const licObj = {
@@ -3614,7 +3600,7 @@ export async function getRepoLicense(repoUrl, repoMetadata) {
3614
3600
  }
3615
3601
  }
3616
3602
  } catch (err) {
3617
- if (err && err.message) {
3603
+ if (err?.message) {
3618
3604
  if (
3619
3605
  err.message.includes("rate limit exceeded") &&
3620
3606
  !process.env.GITHUB_TOKEN
@@ -3645,16 +3631,16 @@ export async function getGoPkgLicense(repoMetadata) {
3645
3631
  const name = repoMetadata.name;
3646
3632
  let pkgUrlPrefix = "https://pkg.go.dev/";
3647
3633
  if (group && group !== "." && group !== name) {
3648
- pkgUrlPrefix = pkgUrlPrefix + group + "/";
3634
+ pkgUrlPrefix = `${pkgUrlPrefix + group}/`;
3649
3635
  }
3650
- pkgUrlPrefix = pkgUrlPrefix + name + "?tab=licenses";
3636
+ pkgUrlPrefix = `${pkgUrlPrefix + name}?tab=licenses`;
3651
3637
  // Check the metadata cache first
3652
3638
  if (metadata_cache[pkgUrlPrefix]) {
3653
3639
  return metadata_cache[pkgUrlPrefix];
3654
3640
  }
3655
3641
  try {
3656
3642
  const res = await cdxgenAgent.get(pkgUrlPrefix);
3657
- if (res && res.body) {
3643
+ if (res?.body) {
3658
3644
  const $ = load(res.body);
3659
3645
  let licenses = $("#LICENSE > h2").text().trim();
3660
3646
  if (licenses === "") {
@@ -3745,10 +3731,12 @@ export async function parseGoModData(goModData, gosumMap) {
3745
3731
  if (l.includes("require (")) {
3746
3732
  isModReplacement = false;
3747
3733
  continue;
3748
- } else if (l.includes("replace (")) {
3734
+ }
3735
+ if (l.includes("replace (")) {
3749
3736
  isModReplacement = true;
3750
3737
  continue;
3751
- } else if (l.includes("replace ")) {
3738
+ }
3739
+ if (l.includes("replace ")) {
3752
3740
  // If this is an inline replacement, drop the word replace
3753
3741
  // (eg; "replace google.golang.org/grpc => google.golang.org/grpc v1.21.0" becomes " google.golang.org/grpc => google.golang.org/grpc v1.21.0")
3754
3742
  l = l.replace("replace", "");
@@ -3811,7 +3799,7 @@ export async function parseGoListDep(rawOutput, gosumMap) {
3811
3799
  const verArr = l.trim().replace(/[\"']/g, "").split(" ");
3812
3800
 
3813
3801
  if (verArr && verArr.length >= 5) {
3814
- const key = verArr[0] + "-" + verArr[1];
3802
+ const key = `${verArr[0]}-${verArr[1]}`;
3815
3803
  // Filter duplicates
3816
3804
  if (!keys_cache[key]) {
3817
3805
  keys_cache[key] = key;
@@ -3915,8 +3903,8 @@ export async function parseGoModGraph(
3915
3903
  const tmpA = l.replace("\r", "").split(" ");
3916
3904
  if (tmpA && tmpA.length === 2) {
3917
3905
  try {
3918
- const sourcePurl = PackageURL.fromString("pkg:golang/" + tmpA[0]);
3919
- const dependsPurl = PackageURL.fromString("pkg:golang/" + tmpA[1]);
3906
+ const sourcePurl = PackageURL.fromString(`pkg:golang/${tmpA[0]}`);
3907
+ const dependsPurl = PackageURL.fromString(`pkg:golang/${tmpA[1]}`);
3920
3908
  const sourceRefString = decodeURIComponent(sourcePurl.toString());
3921
3909
  const dependsRefString = decodeURIComponent(dependsPurl.toString());
3922
3910
  // Since go mod graph over-reports direct dependencies we use the existing list
@@ -3933,7 +3921,7 @@ export async function parseGoModGraph(
3933
3921
  if (!addedPkgs[tmpA[0]]) {
3934
3922
  const component = await getGoPkgComponent(
3935
3923
  "",
3936
- `${sourcePurl.namespace ? sourcePurl.namespace + "/" : ""}${
3924
+ `${sourcePurl.namespace ? `${sourcePurl.namespace}/` : ""}${
3937
3925
  sourcePurl.name
3938
3926
  }`,
3939
3927
  sourcePurl.version,
@@ -3945,7 +3933,7 @@ export async function parseGoModGraph(
3945
3933
  if (!addedPkgs[tmpA[1]]) {
3946
3934
  const component = await getGoPkgComponent(
3947
3935
  "",
3948
- `${dependsPurl.namespace ? dependsPurl.namespace + "/" : ""}${
3936
+ `${dependsPurl.namespace ? `${dependsPurl.namespace}/` : ""}${
3949
3937
  dependsPurl.name
3950
3938
  }`,
3951
3939
  dependsPurl.version,
@@ -4062,7 +4050,7 @@ export async function parseGopkgData(gopkgData) {
4062
4050
  switch (key) {
4063
4051
  case "digest":
4064
4052
  digestStr = value.replace("1:", "");
4065
- pkg._integrity = "sha256-" + toBase64(digestStr);
4053
+ pkg._integrity = `sha256-${toBase64(digestStr)}`;
4066
4054
  break;
4067
4055
  case "name":
4068
4056
  pkg.group = "";
@@ -4104,7 +4092,7 @@ export async function parseGoVersionData(buildInfoData) {
4104
4092
  }
4105
4093
  const name = tmpA[1].trim();
4106
4094
  let hash = "";
4107
- if (tmpA.length == 4) {
4095
+ if (tmpA.length === 4) {
4108
4096
  hash = tmpA[tmpA.length - 1].replace("h1:", "sha256-");
4109
4097
  }
4110
4098
  const component = await getGoPkgComponent("", name, tmpA[2].trim(), hash);
@@ -4171,7 +4159,7 @@ export async function getRubyGemsMetadata(pkgList) {
4171
4159
  : `${RUBYGEMS_V1_URL}${p.name}.json`;
4172
4160
  const res = await cdxgenAgent.get(fullUrl, apiOptions);
4173
4161
  let body = res.body;
4174
- if (body && body.length) {
4162
+ if (body?.length) {
4175
4163
  body = body[0];
4176
4164
  }
4177
4165
  p.description = body.description || body.summary || "";
@@ -4193,7 +4181,7 @@ export async function getRubyGemsMetadata(pkgList) {
4193
4181
  }
4194
4182
  }
4195
4183
  if (body.sha) {
4196
- p._integrity = "sha256-" + body.sha;
4184
+ p._integrity = `sha256-${body.sha}`;
4197
4185
  }
4198
4186
  if (body.authors) {
4199
4187
  p.author = body.authors;
@@ -4222,13 +4210,13 @@ export async function getRubyGemsMetadata(pkgList) {
4222
4210
  if (body.yanked) {
4223
4211
  p.properties.push({
4224
4212
  name: "cdx:gem:yanked",
4225
- value: "" + body.yanked,
4213
+ value: `${body.yanked}`,
4226
4214
  });
4227
4215
  }
4228
4216
  if (body.prerelease) {
4229
4217
  p.properties.push({
4230
4218
  name: "cdx:gem:prerelease",
4231
- value: "" + body.prerelease,
4219
+ value: `${body.prerelease}`,
4232
4220
  });
4233
4221
  }
4234
4222
  // Use the latest version if none specified
@@ -4279,9 +4267,8 @@ export async function parseGemspecData(gemspecData) {
4279
4267
  pkgList = [pkg];
4280
4268
  if (FETCH_LICENSE) {
4281
4269
  return await getRubyGemsMetadata(pkgList);
4282
- } else {
4283
- return pkgList;
4284
4270
  }
4271
+ return pkgList;
4285
4272
  }
4286
4273
 
4287
4274
  /**
@@ -4309,7 +4296,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
4309
4296
  l = l.replace("\r", "");
4310
4297
  if (specsFound) {
4311
4298
  const tmpA = l.split(" ");
4312
- if (tmpA && tmpA.length == 2) {
4299
+ if (tmpA && tmpA.length === 2) {
4313
4300
  const name = tmpA[0];
4314
4301
  if (name === "remote:") {
4315
4302
  return;
@@ -4375,7 +4362,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
4375
4362
  if (l.trim().startsWith("tag:")) {
4376
4363
  lastTag = l.trim().split(" ")[1];
4377
4364
  }
4378
- if (l.trim() == l.trim().toUpperCase()) {
4365
+ if (l.trim() === l.trim().toUpperCase()) {
4379
4366
  specsFound = false;
4380
4367
  lastRemote = undefined;
4381
4368
  lastRevision = undefined;
@@ -4586,7 +4573,7 @@ export async function getDartMetadata(pkgList) {
4586
4573
  const RESPONSE_TYPE = "json";
4587
4574
  const HEADER_ACCEPT = "application/vnd.pub.v2+json";
4588
4575
  const PUB_DEV_URL = process.env.PUB_DEV_URL || "https://pub.dev";
4589
- const PUB_PACKAGES_URL = PUB_DEV_URL + "/api/packages/";
4576
+ const PUB_PACKAGES_URL = `${PUB_DEV_URL}/api/packages/`;
4590
4577
  const PUB_LICENSE_REGEX = /^license:/i;
4591
4578
  const cdepList = [];
4592
4579
 
@@ -4601,7 +4588,7 @@ export async function getDartMetadata(pkgList) {
4601
4588
  Accept: HEADER_ACCEPT,
4602
4589
  },
4603
4590
  });
4604
- if (res && res.body) {
4591
+ if (res?.body) {
4605
4592
  const version = res.body.versions.find((v) => p.version === v.version);
4606
4593
  if (version) {
4607
4594
  const pubspec = version.pubspec;
@@ -4613,7 +4600,7 @@ export async function getDartMetadata(pkgList) {
4613
4600
  p.homepage = { url: pubspec.homepage };
4614
4601
  }
4615
4602
  const res2 = await cdxgenAgent.get(
4616
- PUB_PACKAGES_URL + p.name + "/score",
4603
+ `${PUB_PACKAGES_URL + p.name}/score`,
4617
4604
  {
4618
4605
  responseType: RESPONSE_TYPE,
4619
4606
  headers: {
@@ -4621,7 +4608,7 @@ export async function getDartMetadata(pkgList) {
4621
4608
  },
4622
4609
  },
4623
4610
  );
4624
- if (res2 && res2.body) {
4611
+ if (res2?.body) {
4625
4612
  const tags = res2.body.tags;
4626
4613
  const license = tags.find((tag) => PUB_LICENSE_REGEX.test(tag));
4627
4614
  if (license) {
@@ -4760,7 +4747,7 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
4760
4747
  value = tmpA[1].trim().replace(/"/g, "");
4761
4748
  switch (key) {
4762
4749
  case "checksum":
4763
- pkg._integrity = "sha384-" + value;
4750
+ pkg._integrity = `sha384-${value}`;
4764
4751
  break;
4765
4752
  case "name":
4766
4753
  value = value.split(" ")[0];
@@ -4803,9 +4790,9 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
4803
4790
  } else if (l.includes("git =")) {
4804
4791
  tmpB = l.split(" { git = ");
4805
4792
  if (tmpB && tmpB.length > 1) {
4806
- version = "git+" + tmpB[1].split(" }")[0];
4793
+ version = `git+${tmpB[1].split(" }")[0]}`;
4807
4794
  }
4808
- } else if (l.indexOf("path =") == -1 && tmpA.length > 1) {
4795
+ } else if (l.indexOf("path =") === -1 && tmpA.length > 1) {
4809
4796
  version = tmpA[1];
4810
4797
  }
4811
4798
  if (name && version) {
@@ -4821,9 +4808,8 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
4821
4808
  }
4822
4809
  if (!simple && FETCH_LICENSE) {
4823
4810
  return await getCratesMetadata(pkgList);
4824
- } else {
4825
- return pkgList;
4826
4811
  }
4812
+ return pkgList;
4827
4813
  }
4828
4814
 
4829
4815
  /**
@@ -4952,9 +4938,8 @@ export async function parseCargoData(cargoLockFile, simple = false) {
4952
4938
  }
4953
4939
  if (FETCH_LICENSE && !simple) {
4954
4940
  return await getCratesMetadata(pkgList);
4955
- } else {
4956
- return pkgList;
4957
4941
  }
4942
+ return pkgList;
4958
4943
  }
4959
4944
 
4960
4945
  export function parseCargoDependencyData(cargoLockData) {
@@ -5119,9 +5104,8 @@ export async function parseCargoAuditableData(cargoData) {
5119
5104
  });
5120
5105
  if (FETCH_LICENSE) {
5121
5106
  return await getCratesMetadata(pkgList);
5122
- } else {
5123
- return pkgList;
5124
5107
  }
5108
+ return pkgList;
5125
5109
  }
5126
5110
 
5127
5111
  export async function parsePubLockData(pubLockData) {
@@ -5159,9 +5143,8 @@ export async function parsePubLockData(pubLockData) {
5159
5143
  });
5160
5144
  if (FETCH_LICENSE) {
5161
5145
  return await getDartMetadata(pkgList);
5162
- } else {
5163
- return pkgList;
5164
5146
  }
5147
+ return pkgList;
5165
5148
  }
5166
5149
 
5167
5150
  export function parsePubYamlData(pubYamlData) {
@@ -5238,7 +5221,7 @@ export function parseHelmYamlData(helmData) {
5238
5221
  pkg["homepage"] = { url: hd.home };
5239
5222
  }
5240
5223
  if (hd.digest) {
5241
- pkg._integrity = "sha256-" + hd.digest;
5224
+ pkg._integrity = `sha256-${hd.digest}`;
5242
5225
  }
5243
5226
 
5244
5227
  pkgList.push(pkg);
@@ -5269,7 +5252,12 @@ export function recurseImageNameLookup(keyValueObj, pkgList, imgList) {
5269
5252
  keyValueObj.packImage ||
5270
5253
  keyValueObj.koImage ||
5271
5254
  keyValueObj.kanikoImage;
5272
- if (keyValueObj.name && keyValueObj.name.includes("/")) {
5255
+ if (
5256
+ !imageLike &&
5257
+ keyValueObj.name &&
5258
+ typeof keyValueObj.name === "string" &&
5259
+ keyValueObj.name.includes("/")
5260
+ ) {
5273
5261
  imageLike = keyValueObj.name;
5274
5262
  }
5275
5263
  if (
@@ -5384,16 +5372,15 @@ export function parseBitbucketPipelinesFile(fileContents) {
5384
5372
  if (imageName === "") {
5385
5373
  privateImageBlockFound = true;
5386
5374
  continue;
5387
- } else {
5388
- /**
5389
- * Assume this is a public build image
5390
- * See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-public-build-images
5391
- */
5392
-
5393
- imgList.push({
5394
- image: imageName,
5395
- });
5396
5375
  }
5376
+ /**
5377
+ * Assume this is a public build image
5378
+ * See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-public-build-images
5379
+ */
5380
+
5381
+ imgList.push({
5382
+ image: imageName,
5383
+ });
5397
5384
  }
5398
5385
 
5399
5386
  // Pipe usage
@@ -5544,13 +5531,13 @@ export function parsePrivadoFile(f) {
5544
5531
  });
5545
5532
  }
5546
5533
  // Capture processing
5547
- if (jsonData.processing && jsonData.processing.length) {
5534
+ if (jsonData.processing?.length) {
5548
5535
  aservice.data = aservice.data.concat(
5549
5536
  convertProcessing(jsonData.processing),
5550
5537
  );
5551
5538
  }
5552
5539
  // Capture sink processing
5553
- if (jsonData.sinkProcessing && jsonData.sinkProcessing.length) {
5540
+ if (jsonData.sinkProcessing?.length) {
5554
5541
  aservice.data = aservice.data.concat(
5555
5542
  convertProcessing(jsonData.sinkProcessing),
5556
5543
  );
@@ -5579,11 +5566,7 @@ export function parsePrivadoFile(f) {
5579
5566
  }
5580
5567
  }
5581
5568
  // If there are third party libraries detected, then there are cross boundary calls happening
5582
- if (
5583
- jsonData.dataFlow &&
5584
- jsonData.dataFlow.third_parties &&
5585
- jsonData.dataFlow.third_parties.length
5586
- ) {
5569
+ if (jsonData.dataFlow?.third_parties?.length) {
5587
5570
  aservice["x-trust-boundary"] = true;
5588
5571
  }
5589
5572
  servlist.push(aservice);
@@ -5606,12 +5589,10 @@ export function parseOpenapiSpecData(oaData) {
5606
5589
  return servlist;
5607
5590
  }
5608
5591
 
5609
- const name =
5610
- oaData.info && oaData.info.title
5611
- ? oaData.info.title.replace(/ /g, "-")
5612
- : "default-name";
5613
- const version =
5614
- oaData.info && oaData.info.version ? oaData.info.version : "latest";
5592
+ const name = oaData.info?.title
5593
+ ? oaData.info.title.replace(/ /g, "-")
5594
+ : "default-name";
5595
+ const version = oaData.info?.version ? oaData.info.version : "latest";
5615
5596
  const aservice = {
5616
5597
  "bom-ref": `urn:service:${name}:${version}`,
5617
5598
  name,
@@ -5619,10 +5600,10 @@ export function parseOpenapiSpecData(oaData) {
5619
5600
  version,
5620
5601
  };
5621
5602
  let serverName = [];
5622
- if (oaData.servers && oaData.servers.length && oaData.servers[0].url) {
5603
+ if (oaData.servers?.length && oaData.servers[0].url) {
5623
5604
  serverName = oaData.servers[0].url;
5624
5605
  if (!serverName.startsWith("http") || !serverName.includes("//")) {
5625
- serverName = "http://" + serverName;
5606
+ serverName = `http://${serverName}`;
5626
5607
  }
5627
5608
  }
5628
5609
  if (oaData.paths) {
@@ -5637,7 +5618,7 @@ export function parseOpenapiSpecData(oaData) {
5637
5618
  aservice.endpoints = endpoints;
5638
5619
  }
5639
5620
  let authenticated = false;
5640
- if (oaData.components && oaData.components.securitySchemes) {
5621
+ if (oaData.components?.securitySchemes) {
5641
5622
  authenticated = true;
5642
5623
  }
5643
5624
  aservice.authenticated = authenticated;
@@ -5721,11 +5702,11 @@ export function parseGitHubWorkflowData(ghwData) {
5721
5702
  let group = "";
5722
5703
  const version = tmpA[1];
5723
5704
  const tmpB = groupName.split("/");
5724
- if (tmpB.length == 2) {
5705
+ if (tmpB.length === 2) {
5725
5706
  name = tmpB[1];
5726
5707
  group = tmpB[0];
5727
5708
  }
5728
- const key = group + "-" + name + "-" + version;
5709
+ const key = `${group}-${name}-${version}`;
5729
5710
  if (!keys_cache[key] && name && version) {
5730
5711
  keys_cache[key] = key;
5731
5712
  pkgList.push({
@@ -5763,7 +5744,7 @@ export function parseCloudBuildData(cbwData) {
5763
5744
  group = "";
5764
5745
  }
5765
5746
  const version = tmpA[1];
5766
- const key = group + "-" + name + "-" + version;
5747
+ const key = `${group}-${name}-${version}`;
5767
5748
  if (!keys_cache[key] && name && version) {
5768
5749
  keys_cache[key] = key;
5769
5750
  pkgList.push({
@@ -5881,7 +5862,7 @@ export function parseLeiningenData(leinData) {
5881
5862
  }
5882
5863
  const tmpArr = leinData.split("(defproject");
5883
5864
  if (tmpArr.length > 1) {
5884
- leinData = "(defproject" + tmpArr[1];
5865
+ leinData = `(defproject${tmpArr[1]}`;
5885
5866
  }
5886
5867
  const ednData = parseEDNString(leinData);
5887
5868
  for (const k of Object.keys(ednData)) {
@@ -5939,7 +5920,7 @@ export function parseEdnData(rawEdnData) {
5939
5920
  group = "";
5940
5921
  }
5941
5922
  const name = basename(psym);
5942
- const cacheKey = group + "-" + name + "-" + version;
5923
+ const cacheKey = `${group}-${name}-${version}`;
5943
5924
  if (!pkgCache[cacheKey]) {
5944
5925
  pkgList.push({ group, name, version });
5945
5926
  pkgCache[cacheKey] = true;
@@ -6037,7 +6018,7 @@ export function parseCsPkgData(pkgData) {
6037
6018
  attributesKey: "$",
6038
6019
  commentKey: "value",
6039
6020
  }).packages;
6040
- if (!packages || packages.length == 0) {
6021
+ if (!packages || packages.length === 0) {
6041
6022
  return pkgList;
6042
6023
  }
6043
6024
  packages = packages[0].package;
@@ -6064,11 +6045,11 @@ export function parseCsProjData(csProjData, projFile) {
6064
6045
  attributesKey: "$",
6065
6046
  commentKey: "value",
6066
6047
  }).Project;
6067
- if (!projects || projects.length == 0) {
6048
+ if (!projects || projects.length === 0) {
6068
6049
  return pkgList;
6069
6050
  }
6070
6051
  const project = projects[0];
6071
- if (project.ItemGroup && project.ItemGroup.length) {
6052
+ if (project.ItemGroup?.length) {
6072
6053
  for (const i in project.ItemGroup) {
6073
6054
  const item = project.ItemGroup[i];
6074
6055
  // .net core use PackageReference
@@ -6156,9 +6137,8 @@ export function parseCsProjAssetsData(csProjData, assetsJsonFile) {
6156
6137
  operator: match[2],
6157
6138
  version: match[3],
6158
6139
  };
6159
- } else {
6160
- return null;
6161
6140
  }
6141
+ return null;
6162
6142
  }
6163
6143
 
6164
6144
  const pkgList = [];
@@ -6256,9 +6236,9 @@ export function parseCsProjAssetsData(csProjData, assetsJsonFile) {
6256
6236
  };
6257
6237
  if (lib[rootDep]) {
6258
6238
  if (lib[rootDep].sha512) {
6259
- pkg["_integrity"] = "sha512-" + lib[rootDep].sha512;
6239
+ pkg["_integrity"] = `sha512-${lib[rootDep].sha512}`;
6260
6240
  } else if (lib[rootDep].sha256) {
6261
- pkg["_integrity"] = "sha256-" + lib[rootDep].sha256;
6241
+ pkg["_integrity"] = `sha256-${lib[rootDep].sha256}`;
6262
6242
  }
6263
6243
  if (lib[rootDep].files && Array.isArray(lib[rootDep].files)) {
6264
6244
  const dllFiles = new Set();
@@ -6393,7 +6373,7 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
6393
6373
  purl,
6394
6374
  "bom-ref": decodeURIComponent(purl),
6395
6375
  _integrity: libData.contentHash
6396
- ? "sha512-" + libData.contentHash
6376
+ ? `sha512-${libData.contentHash}`
6397
6377
  : undefined,
6398
6378
  properties: [
6399
6379
  {
@@ -6425,11 +6405,7 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
6425
6405
  let adepResolvedVersion = libData.dependencies[adep];
6426
6406
  const aversionNoRuntime = aversion.split("/")[0];
6427
6407
  // Try to get the resolved version of the dependency. See #930 and #937
6428
- if (
6429
- assetData.dependencies[aversion] &&
6430
- assetData.dependencies[aversion][adep] &&
6431
- assetData.dependencies[aversion][adep].resolved
6432
- ) {
6408
+ if (assetData.dependencies[aversion]?.[adep]?.resolved) {
6433
6409
  adepResolvedVersion =
6434
6410
  assetData.dependencies[aversion][adep].resolved;
6435
6411
  } else if (
@@ -6441,12 +6417,10 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
6441
6417
  adepResolvedVersion =
6442
6418
  assetData.dependencies[aversionNoRuntime][adep].resolved;
6443
6419
  } else if (
6444
- (assetData.dependencies[aversion] &&
6445
- assetData.dependencies[aversion][adep.toLowerCase()] &&
6420
+ (assetData.dependencies[aversion]?.[adep.toLowerCase()] &&
6446
6421
  assetData.dependencies[aversion][adep.toLowerCase()].type ===
6447
6422
  "Project") ||
6448
- (assetData.dependencies[aversionNoRuntime] &&
6449
- assetData.dependencies[aversionNoRuntime][adep.toLowerCase()] &&
6423
+ (assetData.dependencies[aversionNoRuntime]?.[adep.toLowerCase()] &&
6450
6424
  assetData.dependencies[aversionNoRuntime][adep.toLowerCase()]
6451
6425
  .type === "Project")
6452
6426
  ) {
@@ -6827,7 +6801,7 @@ export function parseSbtTree(sbtTreeFile) {
6827
6801
  if (!level_trees[purlString]) {
6828
6802
  level_trees[purlString] = [];
6829
6803
  }
6830
- if (level == 0) {
6804
+ if (level === 0) {
6831
6805
  first_purl = purlString;
6832
6806
  stack = [first_purl];
6833
6807
  stack.push(purlString);
@@ -6878,11 +6852,11 @@ export function parseSbtLock(pkgLockFile) {
6878
6852
  const lockData = JSON.parse(
6879
6853
  readFileSync(pkgLockFile, { encoding: "utf-8" }),
6880
6854
  );
6881
- if (lockData && lockData.dependencies) {
6855
+ if (lockData?.dependencies) {
6882
6856
  for (const pkg of lockData.dependencies) {
6883
6857
  const artifacts = pkg.artifacts || undefined;
6884
6858
  let integrity = "";
6885
- if (artifacts && artifacts.length) {
6859
+ if (artifacts?.length) {
6886
6860
  integrity = artifacts[0].hash.replace("sha1:", "sha1-");
6887
6861
  }
6888
6862
  let compScope = undefined;
@@ -7028,7 +7002,7 @@ export function convertOSQueryResults(
7028
7002
  enhance = false,
7029
7003
  ) {
7030
7004
  const pkgList = [];
7031
- if (results && results.length) {
7005
+ if (results?.length) {
7032
7006
  for (const res of results) {
7033
7007
  const version =
7034
7008
  res.version ||
@@ -7083,7 +7057,7 @@ export function convertOSQueryResults(
7083
7057
  name = queryObj.name;
7084
7058
  }
7085
7059
  let qualifiers = undefined;
7086
- if (res.identifying_number && res.identifying_number.length) {
7060
+ if (res.identifying_number?.length) {
7087
7061
  qualifiers = {
7088
7062
  tag_id: res.identifying_number.replace("{", "").replace("}", ""),
7089
7063
  };
@@ -7163,24 +7137,24 @@ export function convertOSQueryResults(
7163
7137
  }
7164
7138
 
7165
7139
  function purlFromUrlString(type, repoUrl, version) {
7166
- let namespace = "",
7167
- name;
7168
- if (repoUrl && repoUrl.startsWith("http")) {
7140
+ let namespace = "";
7141
+ let name;
7142
+ if (repoUrl?.startsWith("http")) {
7169
7143
  const url = new URL(repoUrl);
7170
7144
  const pathnameParts = url.pathname.split("/");
7171
7145
  const pathnameLastElement = pathnameParts.pop(); // pop() returns last element and removes it from pathnameParts
7172
7146
  name = pathnameLastElement.replace(".git", "");
7173
7147
  const urlpath = pathnameParts.join("/");
7174
7148
  namespace = url.hostname + urlpath;
7175
- } else if (repoUrl && repoUrl.startsWith("git@")) {
7149
+ } else if (repoUrl?.startsWith("git@")) {
7176
7150
  const parts = repoUrl.split(":");
7177
7151
  const hostname = parts[0].split("@")[1];
7178
7152
  const pathnameParts = parts[1].split("/");
7179
7153
  const pathnameLastElement = pathnameParts.pop();
7180
7154
  name = pathnameLastElement.replace(".git", "");
7181
7155
  const urlpath = pathnameParts.join("/");
7182
- namespace = hostname + "/" + urlpath;
7183
- } else if (repoUrl && repoUrl.startsWith("ssh://git@bitbucket")) {
7156
+ namespace = `${hostname}/${urlpath}`;
7157
+ } else if (repoUrl?.startsWith("ssh://git@bitbucket")) {
7184
7158
  repoUrl = repoUrl.replace("ssh://git@", "");
7185
7159
  const parts = repoUrl.split(":");
7186
7160
  const hostname = parts[0];
@@ -7188,8 +7162,8 @@ function purlFromUrlString(type, repoUrl, version) {
7188
7162
  const pathnameLastElement = pathnameParts.pop();
7189
7163
  name = pathnameLastElement.replace(".git", "");
7190
7164
  const urlpath = pathnameParts.join("/");
7191
- namespace = hostname + "/" + urlpath;
7192
- } else if (repoUrl && repoUrl.startsWith("/")) {
7165
+ namespace = `${hostname}/${urlpath}`;
7166
+ } else if (repoUrl?.startsWith("/")) {
7193
7167
  const parts = repoUrl.split("/");
7194
7168
  name = parts[parts.length - 1];
7195
7169
  } else {
@@ -7303,7 +7277,7 @@ export function parseSwiftResolved(resolvedFile) {
7303
7277
  let resolvedList = [];
7304
7278
  if (pkgData.pins) {
7305
7279
  resolvedList = pkgData.pins;
7306
- } else if (pkgData.object && pkgData.object.pins) {
7280
+ } else if (pkgData.object?.pins) {
7307
7281
  resolvedList = pkgData.object.pins;
7308
7282
  }
7309
7283
  for (const adep of resolvedList) {
@@ -7374,8 +7348,8 @@ export async function collectMvnDependencies(
7374
7348
  "-Dmdep.copyPom=true",
7375
7349
  "-Dmdep.useRepositoryLayout=true",
7376
7350
  "-Dmdep.includeScope=compile",
7377
- "-Dmdep.prependGroupId=" + (process.env.MAVEN_PREPEND_GROUP || "false"),
7378
- "-Dmdep.stripVersion=" + (process.env.MAVEN_STRIP_VERSION || "false"),
7351
+ `-Dmdep.prependGroupId=${process.env.MAVEN_PREPEND_GROUP || "false"}`,
7352
+ `-Dmdep.stripVersion=${process.env.MAVEN_STRIP_VERSION || "false"}`,
7379
7353
  ];
7380
7354
  if (process.env.MVN_ARGS) {
7381
7355
  const addArgs = process.env.MVN_ARGS.split(" ");
@@ -7477,7 +7451,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
7477
7451
  }
7478
7452
  // Parse jar files to get class names
7479
7453
  const jarFiles = getAllFiles(jarPath, "**/*.jar");
7480
- if (jarFiles && jarFiles.length) {
7454
+ if (jarFiles?.length) {
7481
7455
  for (const jf of jarFiles) {
7482
7456
  const jarname = jf;
7483
7457
  let pomname =
@@ -7515,7 +7489,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
7515
7489
  // Let's try our best to construct a purl for .m2 cache entries of the form
7516
7490
  // .m2/repository/org/apache/logging/log4j/log4j-web/3.0.0-SNAPSHOT/log4j-web-3.0.0-SNAPSHOT.jar
7517
7491
  const tmpA = jf.split(join(".m2", "repository", ""));
7518
- if (tmpA && tmpA.length) {
7492
+ if (tmpA?.length) {
7519
7493
  const tmpJarPath = tmpA[tmpA.length - 1];
7520
7494
  // This would yield log4j-web-3.0.0-SNAPSHOT.jar
7521
7495
  const jarFileName = basename(tmpJarPath).replace(".jar", "");
@@ -7561,7 +7535,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
7561
7535
  // Let's try our best to construct a purl for gradle cache entries of the form
7562
7536
  // .gradle/caches/modules-2/files-2.1/org.xmlresolver/xmlresolver/4.2.0/f4dbdaa83d636dcac91c9003ffa7fb173173fe8d/xmlresolver-4.2.0-data.jar
7563
7537
  const tmpA = jf.split(join("files-2.1", ""));
7564
- if (tmpA && tmpA.length) {
7538
+ if (tmpA?.length) {
7565
7539
  const tmpJarPath = tmpA[tmpA.length - 1];
7566
7540
  // This would yield xmlresolver-4.2.0-data.jar
7567
7541
  const jarFileName = basename(tmpJarPath).replace(".jar", "");
@@ -7574,7 +7548,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
7574
7548
  // The result would form the group name
7575
7549
  let jarGroupName = tmpDirParts.join(".").replace(/^\./, "");
7576
7550
  if (jarGroupName.includes(pkgName)) {
7577
- jarGroupName = jarGroupName.replace("." + pkgName, "");
7551
+ jarGroupName = jarGroupName.replace(`.${pkgName}`, "");
7578
7552
  }
7579
7553
  const purlObj = new PackageURL(
7580
7554
  "maven",
@@ -7704,7 +7678,7 @@ export function parsePomXml(pomXmlData) {
7704
7678
  version,
7705
7679
  description: project.description ? project.description._ : "",
7706
7680
  url: project.url ? project.url._ : "",
7707
- scm: project.scm && project.scm.url ? project.scm.url._ : "",
7681
+ scm: project.scm?.url ? project.scm.url._ : "",
7708
7682
  };
7709
7683
  }
7710
7684
  return undefined;
@@ -7761,7 +7735,7 @@ export function getPomPropertiesFromMavenDir(mavenDir) {
7761
7735
  let pomProperties = {};
7762
7736
  if (existsSync(mavenDir) && lstatSync(mavenDir).isDirectory()) {
7763
7737
  const pomPropertiesFiles = getAllFiles(mavenDir, "**/pom.properties");
7764
- if (pomPropertiesFiles && pomPropertiesFiles.length) {
7738
+ if (pomPropertiesFiles?.length) {
7765
7739
  const pomPropertiesString = readFileSync(pomPropertiesFiles[0], {
7766
7740
  encoding: "utf-8",
7767
7741
  });
@@ -7866,7 +7840,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7866
7840
  if (DEBUG_MODE) {
7867
7841
  console.log(`List of jars: ${jarFiles}`);
7868
7842
  }
7869
- if (jarFiles && jarFiles.length) {
7843
+ if (jarFiles?.length) {
7870
7844
  for (const jf of jarFiles) {
7871
7845
  // If the jar file doesn't exist at the point of use, skip it
7872
7846
  if (!existsSync(jf)) {
@@ -7914,11 +7888,11 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7914
7888
  // META-INF/maven/${groupId}/${artifactId}/pom.properties
7915
7889
  // see https://maven.apache.org/shared/maven-archiver/index.html
7916
7890
  const pomProperties = getPomPropertiesFromMavenDir(mavenDir);
7917
- let group = pomProperties["groupId"],
7918
- name = pomProperties["artifactId"],
7919
- version = pomProperties["version"],
7920
- confidence = 1,
7921
- technique = "manifest-analysis";
7891
+ let group = pomProperties["groupId"];
7892
+ let name = pomProperties["artifactId"];
7893
+ let version = pomProperties["version"];
7894
+ let confidence = 1;
7895
+ let technique = "manifest-analysis";
7922
7896
  if (
7923
7897
  (!group || !name || !version) &&
7924
7898
  SEARCH_MAVEN_ORG &&
@@ -7926,10 +7900,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7926
7900
  ) {
7927
7901
  try {
7928
7902
  const sha = await checksumFile("sha1", jf);
7929
- const searchurl =
7930
- "https://search.maven.org/solrsearch/select?q=1:%22" +
7931
- sha +
7932
- "%22&rows=20&wt=json";
7903
+ const searchurl = `https://search.maven.org/solrsearch/select?q=1:%22${sha}%22&rows=20&wt=json`;
7933
7904
  const res = await cdxgenAgent.get(searchurl, {
7934
7905
  responseType: "json",
7935
7906
  timeout: {
@@ -7941,8 +7912,8 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7941
7912
  response: 1000,
7942
7913
  },
7943
7914
  });
7944
- const data = res && res.body ? res.body["response"] : undefined;
7945
- if (data && data["numFound"] == 1) {
7915
+ const data = res?.body ? res.body["response"] : undefined;
7916
+ if (data && data["numFound"] === 1) {
7946
7917
  const jarInfo = data["docs"][0];
7947
7918
  group = jarInfo["g"];
7948
7919
  name = jarInfo["a"];
@@ -7950,7 +7921,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7950
7921
  technique = "hash-comparison";
7951
7922
  }
7952
7923
  } catch (err) {
7953
- if (err && err.message && !err.message.includes("404")) {
7924
+ if (err?.message && !err.message.includes("404")) {
7954
7925
  if (err.message.includes("Timeout")) {
7955
7926
  console.log(
7956
7927
  "Maven search appears to be unavailable. Search will be skipped for all remaining packages.",
@@ -7982,7 +7953,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7982
7953
  jarMetadata["Bundle-Version"] ||
7983
7954
  jarMetadata["Implementation-Version"] ||
7984
7955
  jarMetadata["Specification-Version"];
7985
- if (version && version.includes(" ")) {
7956
+ if (version?.includes(" ")) {
7986
7957
  version = version.split(" ")[0];
7987
7958
  }
7988
7959
  // Prefer jar filename to construct name and version
@@ -7998,7 +7969,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
7998
7969
  if (!version || version === "") {
7999
7970
  version = lastPart.replace(".jar", "");
8000
7971
  }
8001
- name = jarname.replace("-" + lastPart, "") || "";
7972
+ name = jarname.replace(`-${lastPart}`, "") || "";
8002
7973
  }
8003
7974
  }
8004
7975
  }
@@ -8018,21 +7989,18 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
8018
7989
  // Sometimes the group might already contain the name
8019
7990
  // Eg: group: org.checkerframework.checker.qual name: checker-qual
8020
7991
  if (name && group && !group.startsWith("javax")) {
8021
- if (group.includes("." + name.toLowerCase().replace(/-/g, "."))) {
7992
+ if (group.includes(`.${name.toLowerCase().replace(/-/g, ".")}`)) {
8022
7993
  group = group.replace(
8023
- new RegExp("." + name.toLowerCase().replace(/-/g, ".") + "$"),
8024
- "",
8025
- );
8026
- } else if (group.includes("." + name.toLowerCase())) {
8027
- group = group.replace(
8028
- new RegExp("." + name.toLowerCase() + "$"),
7994
+ new RegExp(`.${name.toLowerCase().replace(/-/g, ".")}$`),
8029
7995
  "",
8030
7996
  );
7997
+ } else if (group.includes(`.${name.toLowerCase()}`)) {
7998
+ group = group.replace(new RegExp(`.${name.toLowerCase()}$`), "");
8031
7999
  }
8032
8000
  }
8033
8001
  // Patch the group string
8034
8002
  for (const aprefix in vendorAliases) {
8035
- if (name && name.startsWith(aprefix)) {
8003
+ if (name?.startsWith(aprefix)) {
8036
8004
  group = vendorAliases[aprefix];
8037
8005
  break;
8038
8006
  }
@@ -8073,11 +8041,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
8073
8041
  },
8074
8042
  ],
8075
8043
  };
8076
- if (
8077
- jarNSMapping &&
8078
- jarNSMapping[apkg.purl] &&
8079
- jarNSMapping[apkg.purl].namespaces
8080
- ) {
8044
+ if (jarNSMapping?.[apkg.purl] && jarNSMapping[apkg.purl].namespaces) {
8081
8045
  apkg.properties.push({
8082
8046
  name: "Namespaces",
8083
8047
  value: jarNSMapping[apkg.purl].namespaces.join("\n"),
@@ -8148,7 +8112,7 @@ export function addPlugin(projectPath, plugin) {
8148
8112
  const pluginsFile = sbtPluginsPath(projectPath);
8149
8113
  let originalPluginsFile = null;
8150
8114
  if (existsSync(pluginsFile)) {
8151
- originalPluginsFile = pluginsFile + ".cdxgen";
8115
+ originalPluginsFile = `${pluginsFile}.cdxgen`;
8152
8116
  copyFileSync(pluginsFile, originalPluginsFile, constants.COPYFILE_FICLONE);
8153
8117
  }
8154
8118
 
@@ -8170,19 +8134,13 @@ export function cleanupPlugin(projectPath, originalPluginsFile) {
8170
8134
  // just remove the file, it was never there
8171
8135
  unlinkSync(pluginsFile);
8172
8136
  return !existsSync(pluginsFile);
8173
- } else {
8174
- // Bring back the original file
8175
- copyFileSync(
8176
- originalPluginsFile,
8177
- pluginsFile,
8178
- constants.COPYFILE_FICLONE,
8179
- );
8180
- unlinkSync(originalPluginsFile);
8181
- return true;
8182
8137
  }
8183
- } else {
8184
- return false;
8138
+ // Bring back the original file
8139
+ copyFileSync(originalPluginsFile, pluginsFile, constants.COPYFILE_FICLONE);
8140
+ unlinkSync(originalPluginsFile);
8141
+ return true;
8185
8142
  }
8143
+ return false;
8186
8144
  }
8187
8145
 
8188
8146
  /**
@@ -8290,7 +8248,7 @@ export function getGradleCommand(srcPath, rootPath) {
8290
8248
  let gradleCmd = "gradle";
8291
8249
 
8292
8250
  let findGradleFile = "gradlew";
8293
- if (platform() == "win32") {
8251
+ if (platform() === "win32") {
8294
8252
  findGradleFile = "gradlew.bat";
8295
8253
  }
8296
8254
 
@@ -8332,7 +8290,7 @@ export function getMavenCommand(srcPath, rootPath) {
8332
8290
  let isWrapperFound = false;
8333
8291
  let findMavenFile = "mvnw";
8334
8292
  let mavenWrapperCmd = null;
8335
- if (platform() == "win32") {
8293
+ if (platform() === "win32") {
8336
8294
  findMavenFile = "mvnw.bat";
8337
8295
  if (
8338
8296
  !existsSync(join(srcPath, findMavenFile)) &&
@@ -8544,7 +8502,7 @@ export function findAppModules(
8544
8502
  );
8545
8503
  }
8546
8504
  // Clean up
8547
- if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
8505
+ if (tempDir?.startsWith(tmpdir()) && rmSync) {
8548
8506
  rmSync(tempDir, { recursive: true, force: true });
8549
8507
  }
8550
8508
  return retList;
@@ -8642,10 +8600,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
8642
8600
  frozen = false;
8643
8601
  if (DEBUG_MODE) {
8644
8602
  console.log("Virtual env creation has failed");
8645
- if (
8646
- result.stderr &&
8647
- result.stderr.includes("spawnSync python ENOENT")
8648
- ) {
8603
+ if (result.stderr?.includes("spawnSync python ENOENT")) {
8649
8604
  console.log(
8650
8605
  "Install suitable version of python or set the environment variable PYTHON_CMD.",
8651
8606
  );
@@ -8701,7 +8656,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
8701
8656
  shell: isWin,
8702
8657
  });
8703
8658
  if (result.status !== 0 || result.error) {
8704
- if (result.stderr && result.stderr.includes("No module named poetry")) {
8659
+ if (result.stderr?.includes("No module named poetry")) {
8705
8660
  poetryInstallArgs = ["install", "-n", "--no-root"];
8706
8661
  // Attempt to perform poetry install
8707
8662
  result = spawnSync("poetry", poetryInstallArgs, {
@@ -8751,7 +8706,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
8751
8706
  env,
8752
8707
  });
8753
8708
  tempVenvDir = result.stdout.replaceAll(/[\r\n]+/g, "");
8754
- if (tempVenvDir && tempVenvDir.length) {
8709
+ if (tempVenvDir?.length) {
8755
8710
  env.VIRTUAL_ENV = tempVenvDir;
8756
8711
  env.PATH = `${join(
8757
8712
  tempVenvDir,
@@ -8837,10 +8792,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
8837
8792
  }
8838
8793
  }
8839
8794
  // Bug #375. Attempt pip freeze on existing and new virtual environments
8840
- if (
8841
- (env.VIRTUAL_ENV && env.VIRTUAL_ENV.length) ||
8842
- (env.CONDA_PREFIX && env.CONDA_PREFIX.length)
8843
- ) {
8795
+ if (env.VIRTUAL_ENV?.length || env.CONDA_PREFIX?.length) {
8844
8796
  /**
8845
8797
  * At this point, the previous attempt to do a pip install might have failed and we might have an unclean virtual environment with an incomplete list
8846
8798
  * The position taken by cdxgen is "Some SBOM is better than no SBOM", so we proceed to collecting the dependencies that got installed with pip freeze
@@ -8930,7 +8882,7 @@ export function parsePackageJsonName(name) {
8930
8882
  );
8931
8883
  if (match) {
8932
8884
  returnObject.scope =
8933
- (match[1] && name.includes("@") ? "@" + match[1] : match[1]) || null;
8885
+ (match[1] && name.includes("@") ? `@${match[1]}` : match[1]) || null;
8934
8886
  returnObject.fullName = match[2] || match[0];
8935
8887
  returnObject.projectName = match[3] === match[2] ? null : match[3];
8936
8888
  returnObject.moduleName = match[4] || match[2] || null;
@@ -8954,7 +8906,7 @@ export async function addEvidenceForImports(
8954
8906
  const impPkgs = Object.keys(allImports);
8955
8907
  const exportedPkgs = Object.keys(allExports);
8956
8908
  for (const pkg of pkgList) {
8957
- if (impPkgs && impPkgs.length) {
8909
+ if (impPkgs?.length) {
8958
8910
  // Assume that all packages are optional until we see an evidence
8959
8911
  pkg.scope = "optional";
8960
8912
  }
@@ -8963,10 +8915,9 @@ export async function addEvidenceForImports(
8963
8915
  if (group === "@types") {
8964
8916
  continue;
8965
8917
  }
8966
- const aliases =
8967
- group && group.length
8968
- ? [name, `${group}/${name}`, `@${group}/${name}`]
8969
- : [name];
8918
+ const aliases = group?.length
8919
+ ? [name, `${group}/${name}`, `@${group}/${name}`]
8920
+ : [name];
8970
8921
  for (const alias of aliases) {
8971
8922
  const all_includes = impPkgs.filter(
8972
8923
  (find_pkg) =>
@@ -8976,7 +8927,7 @@ export async function addEvidenceForImports(
8976
8927
  const all_exports = exportedPkgs.filter((find_pkg) =>
8977
8928
  find_pkg.startsWith(alias),
8978
8929
  );
8979
- if (all_exports && all_exports.length) {
8930
+ if (all_exports?.length) {
8980
8931
  let exportedModules = new Set(all_exports);
8981
8932
  pkg.properties = pkg.properties || [];
8982
8933
  for (const subevidence of all_exports) {
@@ -9025,7 +8976,7 @@ export async function addEvidenceForImports(
9025
8976
  pkg.evidence.occurrences = pkg.evidence.occurrences || [];
9026
8977
  pkg.evidence.occurrences.push({
9027
8978
  location: `${evidence.fileName}${
9028
- evidence.lineNumber ? "#" + evidence.lineNumber : ""
8979
+ evidence.lineNumber ? `#${evidence.lineNumber}` : ""
9029
8980
  }`,
9030
8981
  });
9031
8982
  importedModules.add(evidence.importedAs);
@@ -9131,7 +9082,7 @@ export function parseCmakeDotFile(dotFile, pkgType, options = {}) {
9131
9082
  } else if (l.includes("// ")) {
9132
9083
  // Indirect dependencies are represented with comments
9133
9084
  const tmpA = l.split("// ");
9134
- if (tmpA && tmpA.length) {
9085
+ if (tmpA?.length) {
9135
9086
  const relationship = tmpA[1];
9136
9087
  if (relationship.includes("->")) {
9137
9088
  const tmpB = relationship.split(" -> ");
@@ -9237,7 +9188,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
9237
9188
  ) {
9238
9189
  if (l.includes("${")) {
9239
9190
  for (const tmplKey of Object.keys(templateValues)) {
9240
- l = l.replace("${" + tmplKey + "}", templateValues[tmplKey] || "");
9191
+ l = l.replace(`\${${tmplKey}}`, templateValues[tmplKey] || "");
9241
9192
  }
9242
9193
  }
9243
9194
  const tmpA = l.replace("project (", "project(").split("project(");
@@ -9257,7 +9208,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
9257
9208
  if (versionIndex > -1 && tmpB.length > versionIndex) {
9258
9209
  parentVersion = tmpB[versionIndex + 1];
9259
9210
  }
9260
- if (parentName && parentName.length && !parentName.includes("$")) {
9211
+ if (parentName?.length && !parentName.includes("$")) {
9261
9212
  parentComponent = {
9262
9213
  group: options.projectGroup || "",
9263
9214
  name: parentName,
@@ -9353,7 +9304,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
9353
9304
  }
9354
9305
  } else if (l.includes("dependency(")) {
9355
9306
  let tmpA = l.split("dependency(");
9356
- if (tmpA && tmpA.length) {
9307
+ if (tmpA?.length) {
9357
9308
  if (!l.includes("_dependency") && !l.includes(".dependency")) {
9358
9309
  tmpA = tmpA[tmpA.length - 1]
9359
9310
  .split(", ")
@@ -9508,7 +9459,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
9508
9459
  let parentComponent = undefined;
9509
9460
  const dependsOn = [];
9510
9461
  (epkgList || []).forEach((p) => {
9511
- epkgMap[p.group + "/" + p.name] = p;
9462
+ epkgMap[`${p.group}/${p.name}`] = p;
9512
9463
  });
9513
9464
  // Let's look for any vcpkg.json file to tell us about the directory we're scanning
9514
9465
  // users can use this file to give us a clue even if they do not use vcpkg library manager
@@ -9553,9 +9504,9 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
9553
9504
  // Is this a dependency we haven't seen before including the all lower and upper case version?
9554
9505
  if (
9555
9506
  avcpkgName &&
9556
- !epkgMap["/" + avcpkgName] &&
9557
- !epkgMap["/" + avcpkgName.toLowerCase()] &&
9558
- !epkgMap["/" + avcpkgName.toUpperCase()]
9507
+ !epkgMap[`/${avcpkgName}`] &&
9508
+ !epkgMap[`/${avcpkgName.toLowerCase()}`] &&
9509
+ !epkgMap[`/${avcpkgName.toUpperCase()}`]
9559
9510
  ) {
9560
9511
  const pkgPurl = new PackageURL(
9561
9512
  pkgType,
@@ -9605,7 +9556,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
9605
9556
  parentComponent = {
9606
9557
  group: options.projectGroup || "",
9607
9558
  name: options.projectName || "",
9608
- version: "" + options.projectVersion || "latest",
9559
+ version: `${options.projectVersion}` || "latest",
9609
9560
  type: "application",
9610
9561
  };
9611
9562
  const parentPurl = new PackageURL(
@@ -9656,7 +9607,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
9656
9607
  // We need to resolve the name to an os package here
9657
9608
  const name = fileName.replace(extn, "");
9658
9609
  let apkg = getOSPackageForFile(afile, osPkgsList) ||
9659
- epkgMap[group + "/" + name] || {
9610
+ epkgMap[`${group}/${name}`] || {
9660
9611
  name,
9661
9612
  group,
9662
9613
  version: "",
@@ -9782,7 +9733,7 @@ export function parseCUsageSlice(sliceData) {
9782
9733
  const slFileName = slice.fileName;
9783
9734
  const allLines = usageData[slFileName] || new Set();
9784
9735
  if (slice.fullName && slice.fullName.length > 3) {
9785
- if (slice.code && slice.code.startsWith("#include")) {
9736
+ if (slice.code?.startsWith("#include")) {
9786
9737
  usageData[slice.fullName] = new Set();
9787
9738
  } else {
9788
9739
  allLines.add(slice.fullName);
@@ -9833,28 +9784,24 @@ async function queryNuget(p, NUGET_URL) {
9833
9784
  Number(tmpVersionArray.slice(-1)) === 0
9834
9785
  ) {
9835
9786
  return upper;
9836
- } else if (upper.split("-").length > 1) {
9787
+ }
9788
+ if (upper.split("-").length > 1) {
9837
9789
  tmpVersionArray[tmpVersionArray.length - 1] = (
9838
9790
  Number(tmpVersionArray.slice(-1)) - 1
9839
9791
  ).toString();
9840
9792
  }
9841
9793
  return tmpVersionArray.join(".");
9842
- } else {
9843
- const tmpVersion = parse(upper);
9844
- let version =
9845
- tmpVersion.major + "." + tmpVersion.minor + "." + tmpVersion.patch;
9846
- if (compare(version, upper) === 1) {
9847
- if (tmpVersion.patch > 0) {
9848
- version =
9849
- tmpVersion.major +
9850
- "." +
9851
- tmpVersion.minor +
9852
- "." +
9853
- (tmpVersion.patch - 1).toString();
9854
- }
9794
+ }
9795
+ const tmpVersion = parse(upper);
9796
+ let version = `${tmpVersion.major}.${tmpVersion.minor}.${tmpVersion.patch}`;
9797
+ if (compare(version, upper) === 1) {
9798
+ if (tmpVersion.patch > 0) {
9799
+ version = `${tmpVersion.major}.${tmpVersion.minor}.${(
9800
+ tmpVersion.patch - 1
9801
+ ).toString()}`;
9855
9802
  }
9856
- return version;
9857
9803
  }
9804
+ return version;
9858
9805
  }
9859
9806
  // Coerce only when missing patch/minor version
9860
9807
  function coerceUp(version) {
@@ -9867,7 +9814,7 @@ async function queryNuget(p, NUGET_URL) {
9867
9814
  const body = [];
9868
9815
  const newBody = [];
9869
9816
  let res = await cdxgenAgent.get(
9870
- NUGET_URL + np.name.toLowerCase() + "/index.json",
9817
+ `${NUGET_URL + np.name.toLowerCase()}/index.json`,
9871
9818
  { responseType: "json" },
9872
9819
  );
9873
9820
  const items = res.body.items;
@@ -9940,7 +9887,7 @@ export async function getNugetMetadata(pkgList, dependencies = undefined) {
9940
9887
  cacheKey = `${p.name}|${p.version}`;
9941
9888
  let body = metadata_cache[cacheKey];
9942
9889
 
9943
- if (body && body.error) {
9890
+ if (body?.error) {
9944
9891
  cdepList.push(p);
9945
9892
  continue;
9946
9893
  }
@@ -9994,12 +9941,7 @@ export async function getNugetMetadata(pkgList, dependencies = undefined) {
9994
9941
  if (body.catalogEntry.projectUrl) {
9995
9942
  p.repository = { url: body.catalogEntry.projectUrl };
9996
9943
  p.homepage = {
9997
- url:
9998
- "https://www.nuget.org/packages/" +
9999
- p.name +
10000
- "/" +
10001
- p.version +
10002
- "/",
9944
+ url: `https://www.nuget.org/packages/${p.name}/${p.version}/`,
10003
9945
  };
10004
9946
  if (
10005
9947
  (!p.license || typeof p.license === "string") &&
@@ -10067,7 +10009,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
10067
10009
  .forEach((aprop) => {
10068
10010
  if (aprop.value) {
10069
10011
  const tmpA = aprop.value.split(", ");
10070
- if (tmpA && tmpA.length) {
10012
+ if (tmpA?.length) {
10071
10013
  tmpA.forEach((dllFile) => {
10072
10014
  pkgFilePurlMap[dllFile] = apkg.purl;
10073
10015
  });
@@ -10080,11 +10022,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
10080
10022
  if (slicesData && Object.keys(slicesData)) {
10081
10023
  if (slicesData.Dependencies) {
10082
10024
  for (const adep of slicesData.Dependencies) {
10083
- if (
10084
- adep.Module &&
10085
- adep.Module.endsWith(".dll") &&
10086
- pkgFilePurlMap[adep.Module]
10087
- ) {
10025
+ if (adep.Module?.endsWith(".dll") && pkgFilePurlMap[adep.Module]) {
10088
10026
  const modPurl = pkgFilePurlMap[adep.Module];
10089
10027
  if (!purlLocationMap[modPurl]) {
10090
10028
  purlLocationMap[modPurl] = new Set();
@@ -10096,8 +10034,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
10096
10034
  if (slicesData.MethodCalls) {
10097
10035
  for (const amethodCall of slicesData.MethodCalls) {
10098
10036
  if (
10099
- amethodCall.Module &&
10100
- amethodCall.Module.endsWith(".dll") &&
10037
+ amethodCall.Module?.endsWith(".dll") &&
10101
10038
  pkgFilePurlMap[amethodCall.Module]
10102
10039
  ) {
10103
10040
  const modPurl = pkgFilePurlMap[amethodCall.Module];