@coana-tech/cli 14.9.30 → 14.9.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cli.mjs +346 -103
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -20127,7 +20127,7 @@ var require_lodash = __commonJS({
20127
20127
  });
20128
20128
  return result2;
20129
20129
  }
20130
- function mapValues(object, iteratee2) {
20130
+ function mapValues2(object, iteratee2) {
20131
20131
  var result2 = {};
20132
20132
  iteratee2 = getIteratee(iteratee2, 3);
20133
20133
  baseForOwn(object, function(value, key, object2) {
@@ -20821,7 +20821,7 @@ var require_lodash = __commonJS({
20821
20821
  lodash16.keysIn = keysIn;
20822
20822
  lodash16.map = map2;
20823
20823
  lodash16.mapKeys = mapKeys;
20824
- lodash16.mapValues = mapValues;
20824
+ lodash16.mapValues = mapValues2;
20825
20825
  lodash16.matches = matches;
20826
20826
  lodash16.matchesProperty = matchesProperty;
20827
20827
  lodash16.memoize = memoize4;
@@ -70978,7 +70978,7 @@ var require_lockfileFormatConverters = __commonJS({
70978
70978
  snapshots,
70979
70979
  packages,
70980
70980
  lockfileVersion: constants_1.LOCKFILE_VERSION,
70981
- importers: mapValues(lockfile.importers, convertProjectSnapshotToInlineSpecifiersFormat)
70981
+ importers: mapValues2(lockfile.importers, convertProjectSnapshotToInlineSpecifiersFormat)
70982
70982
  };
70983
70983
  if (newLockfile.settings?.peersSuffixMaxLength === 1e3) {
70984
70984
  newLockfile.settings = (0, omit_1.default)(["peersSuffixMaxLength"], newLockfile.settings);
@@ -71107,7 +71107,7 @@ var require_lockfileFormatConverters = __commonJS({
71107
71107
  const { importers, ...rest } = convertFromLockfileFileMutable(lockfile);
71108
71108
  const newLockfile = {
71109
71109
  ...rest,
71110
- importers: mapValues(importers ?? {}, revertProjectSnapshot)
71110
+ importers: mapValues2(importers ?? {}, revertProjectSnapshot)
71111
71111
  };
71112
71112
  return newLockfile;
71113
71113
  }
@@ -71210,7 +71210,7 @@ var require_lockfileFormatConverters = __commonJS({
71210
71210
  return {
71211
71211
  ...(0, omit_1.default)(["snapshots"], rest),
71212
71212
  packages,
71213
- importers: mapValues(importers ?? {}, revertProjectSnapshot)
71213
+ importers: mapValues2(importers ?? {}, revertProjectSnapshot)
71214
71214
  };
71215
71215
  }
71216
71216
  exports2.convertLockfileV9ToLockfileObject = convertLockfileV9ToLockfileObject;
@@ -71227,7 +71227,7 @@ var require_lockfileFormatConverters = __commonJS({
71227
71227
  };
71228
71228
  }
71229
71229
  function convertResolvedDependenciesToInlineSpecifiersFormat(resolvedDependencies, { specifiers }) {
71230
- return mapValues(resolvedDependencies, (version3, depName) => ({
71230
+ return mapValues2(resolvedDependencies, (version3, depName) => ({
71231
71231
  specifier: specifiers[depName],
71232
71232
  version: version3
71233
71233
  }));
@@ -71257,7 +71257,7 @@ var require_lockfileFormatConverters = __commonJS({
71257
71257
  optionalDependencies
71258
71258
  };
71259
71259
  }
71260
- function mapValues(obj, mapper) {
71260
+ function mapValues2(obj, mapper) {
71261
71261
  const result = {};
71262
71262
  for (const [key, value] of Object.entries(obj)) {
71263
71263
  result[key] = mapper(value, key);
@@ -204801,7 +204801,7 @@ var OtherModulesCommunicator = class {
204801
204801
  workspacePaths
204802
204802
  );
204803
204803
  }
204804
- async runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, vulnerabilities, reachabilityAnalysisOptions, otherAnalysisOptions) {
204804
+ async runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, reachabilityAnalysisOptions, otherAnalysisOptions) {
204805
204805
  const tmpDir = await this.getTmpDirForSubproject(subprojectPath);
204806
204806
  const inputFileName = `${v4_default()}-runReachabilityAnalysis-input.json`;
204807
204807
  const inputFileThisProcess = join15(tmpDir, inputFileName);
@@ -204817,7 +204817,7 @@ var OtherModulesCommunicator = class {
204817
204817
  );
204818
204818
  return this.runReachabilityAnalyzerCommandWithOutput(
204819
204819
  "runReachabilityAnalysis",
204820
- workspaceData.type,
204820
+ ecosystem,
204821
204821
  subprojectPath,
204822
204822
  workspacePath,
204823
204823
  argt`-i ${inputFileOtherProcess}`,
@@ -206768,8 +206768,9 @@ function shouldIgnoreDir(dir) {
206768
206768
  "obj",
206769
206769
  ".yarn",
206770
206770
  // created by the yarn package manager
206771
- ".bingo"
206771
+ ".bingo",
206772
206772
  // created by the Bingo package manager, which can be used with Go projects
206773
+ "site-packages"
206773
206774
  ];
206774
206775
  return dirsToIgnore.includes(dir);
206775
206776
  }
@@ -221972,7 +221973,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
221972
221973
  }
221973
221974
 
221974
221975
  // dist/version.js
221975
- var version2 = "14.9.30";
221976
+ var version2 = "14.9.32";
221976
221977
 
221977
221978
  // ../../node_modules/.pnpm/axios@1.9.0/node_modules/axios/lib/helpers/bind.js
221978
221979
  function bind2(fn2, thisArg) {
@@ -225308,6 +225309,9 @@ function getAdvisoryEcosystemFromPurl(purl) {
225308
225309
  const [purlSceme, rest] = purl.split(":");
225309
225310
  if (purlSceme !== "pkg") throw Error(`Upsupported purl scheme: ${purlSceme}`);
225310
225311
  const [purlType] = rest.split("/");
225312
+ return getAdvisoryEcosystemFromPurlType(purlType);
225313
+ }
225314
+ function getAdvisoryEcosystemFromPurlType(purlType) {
225311
225315
  switch (purlType) {
225312
225316
  case "npm" /* NPM */:
225313
225317
  return "NPM";
@@ -225362,8 +225366,21 @@ function getNamespaceAndName(ecosystem, packageName) {
225362
225366
  }
225363
225367
  return { namespace: namespace2, name };
225364
225368
  }
225369
+ function getNameFromNamespaceAndName(purlType, namespace2, name) {
225370
+ if (!name) return "";
225371
+ switch (purlType) {
225372
+ case "npm" /* NPM */:
225373
+ return namespace2 ? `${namespace2}/${name}` : name;
225374
+ case "maven" /* MAVEN */:
225375
+ return namespace2 ? `${namespace2}:${name}` : name;
225376
+ case "pypi" /* PYPI */:
225377
+ return name;
225378
+ default:
225379
+ return name;
225380
+ }
225381
+ }
225365
225382
 
225366
- // dist/internal/socket-mode-helpers.js
225383
+ // dist/internal/socket-mode-helpers-coana-dependency-trees.js
225367
225384
  var ROOT_IDENTIFIER = "ROOT";
225368
225385
  async function scanForVulnerabilitiesSocketMode(dependencyTree) {
225369
225386
  if (!dependencyTree.ecosystem)
@@ -225441,7 +225458,7 @@ async function scanForVulnerabilitiesSocketMode(dependencyTree) {
225441
225458
  name: dependencyTreeNode.packageName,
225442
225459
  dependency: dependencyTreeNode.packageName,
225443
225460
  vulnChainDetails: computeVulnChainDetails(dependencyTree, dependencyIdentifier, parentsMap),
225444
- vulnerabilityAccessPaths: vulnerability.reachabilityData?.pattern,
225461
+ vulnerabilityAccessPaths: vulnerability.reachabilityData?.pattern ?? null,
225445
225462
  ecosystem: dependencyTree.ecosystem
225446
225463
  });
225447
225464
  }
@@ -225489,7 +225506,7 @@ function transformToVulnChainNode(dependencyTree) {
225489
225506
  };
225490
225507
  }
225491
225508
 
225492
- // dist/internal/socket-report.js
225509
+ // dist/internal/socket-report-coana-dependency-tree.js
225493
225510
  var MAX_STACKS_TO_SEND = 10;
225494
225511
  function toSocketFacts(report, dependencyTrees, subPjToWsPathToDirectDependencies) {
225495
225512
  const components = [];
@@ -225629,8 +225646,195 @@ function toSocketReachabilitySchema(vulnerability) {
225629
225646
  throw new Error("Unknown codeAwareScanResult type");
225630
225647
  }
225631
225648
 
225649
+ // dist/internal/socket-mode-helpers-socket-dependency-trees.js
225650
+ import { dirname as dirname7 } from "path";
225651
+ var filesToDefineWorkspace = ["package.json"];
225652
+ function inferWorkspaceFromManifestPath(manifestPath) {
225653
+ const dir = dirname7(manifestPath);
225654
+ return dir === "" ? "." : dir;
225655
+ }
225656
+ async function fetchArtifactsFromSocket(manifestsTarHash) {
225657
+ console.log("Fetching artifacts from Socket backend using manifests tar hash", manifestsTarHash);
225658
+ let socketBaseUrl = process.env.SOCKET_CLI_API_BASE_URL ?? "https://api.socket.dev/v0/";
225659
+ if (!socketBaseUrl.endsWith("/"))
225660
+ socketBaseUrl += "/";
225661
+ try {
225662
+ const url3 = `${socketBaseUrl}orgs/${process.env.SOCKET_ORG_SLUG}/compute-artifacts?tarHash=${manifestsTarHash}`;
225663
+ const responseData = (await axios_default2.post(url3, {}, {
225664
+ headers: {
225665
+ "Content-Type": "application/json",
225666
+ Accept: "application/json",
225667
+ Authorization: `Basic ${btoa(`${process.env.SOCKET_CLI_API_TOKEN}:`)}`
225668
+ }
225669
+ })).data;
225670
+ let artifacts;
225671
+ if (typeof responseData === "object") {
225672
+ artifacts = [responseData];
225673
+ } else if (typeof responseData === "string") {
225674
+ artifacts = JSON.parse(`[${responseData.trim().replace(/\n/g, ",")}]`);
225675
+ } else {
225676
+ throw new Error(`Unexpected response type from Socket API: ${typeof responseData}`);
225677
+ }
225678
+ const ecosystemToWorkspaceToAnalysisData = {};
225679
+ const ecosystemToWorkspaceToVulnerabilities = {};
225680
+ for (const artifact of artifacts) {
225681
+ const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
225682
+ if (!ecosystem)
225683
+ continue;
225684
+ const workspaces = /* @__PURE__ */ new Set();
225685
+ if (artifact.manifestFiles) {
225686
+ for (const manifestRef of artifact.manifestFiles) {
225687
+ if (manifestRef.file.endsWith("package.json")) {
225688
+ workspaces.add(inferWorkspaceFromManifestPath(manifestRef.file));
225689
+ }
225690
+ }
225691
+ }
225692
+ if (!artifact.direct && artifact.toplevelAncestors) {
225693
+ for (const ancestorId of artifact.toplevelAncestors) {
225694
+ const ancestor = artifacts.find((a4) => a4.id === ancestorId);
225695
+ if (ancestor && ancestor.manifestFiles) {
225696
+ for (const manifestRef of ancestor.manifestFiles) {
225697
+ if (filesToDefineWorkspace.some((file) => manifestRef.file.endsWith(file))) {
225698
+ workspaces.add(inferWorkspaceFromManifestPath(manifestRef.file));
225699
+ }
225700
+ }
225701
+ }
225702
+ }
225703
+ }
225704
+ if (workspaces.size === 0) {
225705
+ workspaces.add(".");
225706
+ }
225707
+ for (const workspace of workspaces) {
225708
+ if (!ecosystemToWorkspaceToAnalysisData[ecosystem]) {
225709
+ ecosystemToWorkspaceToAnalysisData[ecosystem] = {};
225710
+ }
225711
+ if (!ecosystemToWorkspaceToAnalysisData[ecosystem][workspace]) {
225712
+ ecosystemToWorkspaceToAnalysisData[ecosystem][workspace] = {
225713
+ type: "socket",
225714
+ data: []
225715
+ };
225716
+ }
225717
+ const workspaceData = ecosystemToWorkspaceToAnalysisData[ecosystem][workspace];
225718
+ if (workspaceData.type === "socket") {
225719
+ workspaceData.data.push(artifact);
225720
+ }
225721
+ if (artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
225722
+ for (const vuln of artifact.vulnerabilities) {
225723
+ const vulnerability = {
225724
+ url: vuln.ghsaId,
225725
+ purlType: artifact.type,
225726
+ range: vuln.range,
225727
+ name: artifact.name ?? "",
225728
+ dependency: artifact.name ?? "",
225729
+ vulnChainDetails: computeVulnChainDetails2(artifacts, artifact.id),
225730
+ vulnerabilityAccessPaths: vuln.reachabilityData?.pattern ?? null,
225731
+ ecosystem,
225732
+ artifactId: artifact.id
225733
+ };
225734
+ ((ecosystemToWorkspaceToVulnerabilities[ecosystem] ??= {})[workspace] ??= []).push(vulnerability);
225735
+ }
225736
+ }
225737
+ }
225738
+ }
225739
+ return {
225740
+ artifacts,
225741
+ ecosystemToWorkspaceToAnalysisData,
225742
+ ecosystemToWorkspaceToVulnerabilities
225743
+ };
225744
+ } catch (error) {
225745
+ logger.error("Failed to fetch artifacts from Socket backend", error);
225746
+ throw error;
225747
+ }
225748
+ }
225749
+ function computeVulnChainDetails2(artifacts, vulnerableArtifactId) {
225750
+ const artifactMap = /* @__PURE__ */ new Map();
225751
+ for (const artifact of artifacts) {
225752
+ artifactMap.set(artifact.id, artifact);
225753
+ }
225754
+ const parentsMap = /* @__PURE__ */ new Map();
225755
+ for (const artifact of artifacts) {
225756
+ if (artifact.dependencies) {
225757
+ for (const depId of artifact.dependencies) {
225758
+ if (!parentsMap.has(depId)) {
225759
+ parentsMap.set(depId, []);
225760
+ }
225761
+ parentsMap.get(depId).push(artifact.id);
225762
+ }
225763
+ }
225764
+ }
225765
+ const res = {
225766
+ packageName: "root",
225767
+ version: "0.0.0",
225768
+ children: [],
225769
+ transitiveDependencies: {}
225770
+ };
225771
+ function addNode(currentId, childId, visited) {
225772
+ if (visited.has(currentId))
225773
+ return;
225774
+ const currentArtifact = artifactMap.get(currentId);
225775
+ if (!currentArtifact)
225776
+ return;
225777
+ const parents2 = parentsMap.get(currentId);
225778
+ const newCurrentNode = {
225779
+ packageName: getNameFromNamespaceAndName(currentArtifact.type, currentArtifact.namespace, currentArtifact.name),
225780
+ version: currentArtifact.version ?? void 0,
225781
+ children: []
225782
+ };
225783
+ res.transitiveDependencies[currentId] = newCurrentNode;
225784
+ if (childId && !newCurrentNode.children.includes(childId)) {
225785
+ newCurrentNode.children.push(childId);
225786
+ }
225787
+ if (currentId === vulnerableArtifactId) {
225788
+ newCurrentNode.vulnerable = true;
225789
+ }
225790
+ if (currentArtifact.direct) {
225791
+ if (!res.children.includes(currentId)) {
225792
+ res.children.push(currentId);
225793
+ }
225794
+ }
225795
+ visited.add(currentId);
225796
+ if (parents2) {
225797
+ for (const parentId of parents2) {
225798
+ addNode(parentId, currentId, visited);
225799
+ }
225800
+ }
225801
+ }
225802
+ addNode(vulnerableArtifactId, void 0, /* @__PURE__ */ new Set());
225803
+ return res;
225804
+ }
225805
+
225806
+ // dist/internal/socket-report-socket-dependency-tree.js
225807
+ function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities) {
225808
+ const artifactIdToArtifact = Object.fromEntries(artifacts.map((artifact) => [artifact.id, artifact]));
225809
+ for (const vulnerability of vulnerabilities) {
225810
+ const component = artifactIdToArtifact[vulnerability.artifactId];
225811
+ if (!component) {
225812
+ throw new Error(`Component not found for vulnerability ${vulnerability.purl}`);
225813
+ }
225814
+ if (!component.reachability) {
225815
+ component.reachability = [];
225816
+ }
225817
+ let reachabilityForGHSA = component.reachability?.find((r2) => r2.ghsa_id === vulnerability.vulnerabilityUrl.replace("https://github.com/advisories/", ""));
225818
+ if (!reachabilityForGHSA) {
225819
+ reachabilityForGHSA = {
225820
+ ghsa_id: vulnerability.vulnerabilityUrl.replace("https://github.com/advisories/", ""),
225821
+ reachability: []
225822
+ };
225823
+ component.reachability.push(reachabilityForGHSA);
225824
+ }
225825
+ reachabilityForGHSA.reachability.push({
225826
+ ...toSocketReachabilitySchema(vulnerability),
225827
+ workspacePath: vulnerability.workspacePath,
225828
+ subprojectPath: vulnerability.subprojectPath
225829
+ });
225830
+ }
225831
+ return {
225832
+ components: artifacts
225833
+ };
225834
+ }
225835
+
225632
225836
  // dist/cli-core.js
225633
- var { omit, partition, pick } = import_lodash15.default;
225837
+ var { mapValues, omit, partition, pick } = import_lodash15.default;
225634
225838
  var CliCore = class {
225635
225839
  options;
225636
225840
  spinner;
@@ -225710,6 +225914,9 @@ var CliCore = class {
225710
225914
  throw new Error(`Invalid ecosystem: ${ecosystem}.`);
225711
225915
  }
225712
225916
  });
225917
+ if (this.options.manifestsTarHash && !this.options.socketMode) {
225918
+ throw new Error("The --manifests-tar-hash option is only supported when using --socket-mode");
225919
+ }
225713
225920
  }
225714
225921
  async main() {
225715
225922
  this.coanaLogPath = join20(await createTmpDirectory("coana-cli-"), "coana-log.txt");
@@ -225721,24 +225928,58 @@ var CliCore = class {
225721
225928
  logger.error(e.message);
225722
225929
  process.exit(1);
225723
225930
  }
225931
+ const otherModulesCommunicator = new OtherModulesCommunicator(this.rootWorkingDirectory, {
225932
+ runWithoutDocker: this.options.runWithoutDocker,
225933
+ debug: this.options.debug,
225934
+ silent: this.options.silent,
225935
+ coanaLogPath: this.coanaLogPath,
225936
+ reportId: this.reportId,
225937
+ socketMode: !!this.options.socketMode
225938
+ }, this.apiKey);
225724
225939
  this.spinner.start();
225725
225940
  try {
225941
+ if (this.options.manifestsTarHash) {
225942
+ await this.computeAndOutputReportSocketMode(otherModulesCommunicator);
225943
+ this.spinner.stop();
225944
+ return;
225945
+ }
225726
225946
  if (this.shareWithDashboard && this.apiKey.type === "present") {
225727
225947
  const gitData = await getGitDataToMetadataIfAvailable(this.rootWorkingDirectory);
225728
225948
  this.reportId = await createReport(this.options.repoUrl, this.options.projectName, version2, gitData?.sha, gitData?.branchName, omit(this.options, "apiKey", "print-report", "repoUrl", "projectName", "writeReportToFile"), this.apiKey, this.options.runEnv);
225729
225949
  }
225730
- const { report, subPjToWsPathToDirectDependencies } = await this.computeReport();
225950
+ const { report, subPjToWsPathToDirectDependencies } = await this.computeReport(otherModulesCommunicator);
225731
225951
  logger.info("Report computed successfully");
225732
225952
  await this.outputAndShareReport(report, subPjToWsPathToDirectDependencies);
225733
225953
  this.spinner.stop();
225734
225954
  return report;
225735
225955
  } catch (e) {
225736
225956
  await this.spinner.fail();
225737
- logger.error("CLI failed with error:", e.message);
225957
+ logger.error("CLI failed with error:", e);
225738
225958
  await this.shareErrorLogWithDashboard(e, true);
225739
225959
  process.exit(1);
225740
225960
  }
225741
225961
  }
225962
+ async computeAndOutputReportSocketMode(otherModulesCommunicator) {
225963
+ logger.info("Fetching artifacts from Socket backend");
225964
+ const { artifacts, ecosystemToWorkspaceToAnalysisData, ecosystemToWorkspaceToVulnerabilities } = await fetchArtifactsFromSocket(this.options.manifestsTarHash);
225965
+ const vulnsWithResults = [];
225966
+ for (const [ecosystem, workspaceToAnalysisData] of Object.entries(ecosystemToWorkspaceToAnalysisData)) {
225967
+ vulnsWithResults.push(...Object.values(await this.runReachabilityAnalysisForWorkspaces(
225968
+ workspaceToAnalysisData,
225969
+ ecosystemToWorkspaceToVulnerabilities[ecosystem] ?? {},
225970
+ {},
225971
+ // We do not need the direct dependencies for socket mode
225972
+ otherModulesCommunicator,
225973
+ ".",
225974
+ ecosystem,
225975
+ true
225976
+ )).flat());
225977
+ }
225978
+ const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults);
225979
+ const outputFile = resolve24(this.options.socketMode);
225980
+ await writeFile8(outputFile, JSON.stringify(socketReport, null, 2));
225981
+ logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
225982
+ }
225742
225983
  async getLogContent() {
225743
225984
  await logger.finish();
225744
225985
  let logContent;
@@ -225800,15 +226041,7 @@ var CliCore = class {
225800
226041
  logger.info(JSON.stringify(omit(report, "dependencyTrees"), null, 2));
225801
226042
  }
225802
226043
  }
225803
- async computeReport() {
225804
- const otherModulesCommunicator = new OtherModulesCommunicator(this.rootWorkingDirectory, {
225805
- runWithoutDocker: this.options.runWithoutDocker,
225806
- debug: this.options.debug,
225807
- silent: this.options.silent,
225808
- coanaLogPath: this.coanaLogPath,
225809
- reportId: this.reportId,
225810
- socketMode: !!this.options.socketMode
225811
- }, this.apiKey);
226044
+ async computeReport(otherModulesCommunicator) {
225812
226045
  const startTime = (/* @__PURE__ */ new Date()).toISOString();
225813
226046
  this.sendProgress("CREATE_PROJECT_MANAGER", true);
225814
226047
  const manager = await ProjectManager.create(this.rootWorkingDirectory, otherModulesCommunicator, this.options.ecosystems, this.options.includeDirs, this.options.excludeDirs, this.options.changedFiles);
@@ -225936,93 +226169,95 @@ var CliCore = class {
225936
226169
  }
225937
226170
  async runOnSubproject(otherModulesCommunicator, subProjAndWsPath, reachabilitySupported) {
225938
226171
  try {
225939
- let pruneVulnerablePathsToShortestPathsOnly2 = function(ecosystem2, workspaceToAugmentedVulnerabilities2) {
225940
- const vulnerabilityToWorkspaceToCodeAwareScanSuccess = {};
225941
- for (const [workspacePath, augmentedVulnerabilities] of Object.entries(workspaceToAugmentedVulnerabilities2)) {
225942
- augmentedVulnerabilities.forEach((augmentedVulnerability) => {
225943
- const url3 = augmentedVulnerability.url;
225944
- const results = augmentedVulnerability.results;
225945
- if (results.type === "success") {
225946
- (vulnerabilityToWorkspaceToCodeAwareScanSuccess[url3] ??= {})[workspacePath] = results;
225947
- }
225948
- });
225949
- }
225950
- const serialize3 = (t4) => `${t4.package}#${t4.class}`.toLowerCase();
225951
- for (const workspaceToCodeAwareScanSuccess of Object.values(vulnerabilityToWorkspaceToCodeAwareScanSuccess)) {
225952
- const trie = mkTrie();
225953
- for (const codeAwareScanSuccess of Object.values(workspaceToCodeAwareScanSuccess)) {
225954
- const stacks = Array.isArray(codeAwareScanSuccess.detectedOccurrences) ? codeAwareScanSuccess.detectedOccurrences.flatMap((occ) => occ.affectedAppCodePoints) : codeAwareScanSuccess.detectedOccurrences.stacks;
225955
- stacks.forEach((stack2) => {
225956
- addPathToTrie(trie, stack2.map(serialize3));
225957
- });
225958
- }
225959
- for (const codeAwareScanSuccess of Object.values(workspaceToCodeAwareScanSuccess)) {
225960
- const detectedOccurrences = codeAwareScanSuccess.detectedOccurrences;
225961
- detectedOccurrences.stacks = detectedOccurrences.stacks.filter((stack2) => isShortestPath(trie, stack2.map(serialize3)));
225962
- if (detectedOccurrences.stacks.length === 0)
225963
- detectedOccurrences.affectedPackages = [];
225964
- detectedOccurrences.affectedPackages = detectedOccurrences.affectedPackages.filter((affectedPackage) => {
225965
- if (affectedPackage === ROOT_NODE_STR || affectedPackage === "UNKNOWN")
225966
- return true;
225967
- const [packageName, version3] = affectedPackage.split("@");
225968
- return detectedOccurrences.stacks.some((stack2) => stack2.some((stackElm) => {
225969
- if (ecosystem2 === "MAVEN") {
225970
- const [groupId, artifactId, ...rest] = stackElm.package.split(":");
225971
- const expectedPackageName = `${groupId}:${artifactId}`;
225972
- const expectedVersion = rest[rest.length - 1];
225973
- return expectedPackageName === packageName && expectedVersion === version3;
225974
- }
225975
- if (ecosystem2 === "NUGET") {
225976
- const [expectedPackageName, expectedVersion] = stackElm.package.split("/");
225977
- return expectedPackageName === packageName && expectedVersion === version3;
225978
- }
225979
- return true;
225980
- }));
225981
- });
225982
- }
225983
- }
225984
- };
225985
- var pruneVulnerablePathsToShortestPathsOnly = pruneVulnerablePathsToShortestPathsOnly2;
225986
226172
  const { ecosystem, subprojectPath, workspacePaths } = subProjAndWsPath;
225987
226173
  const { projectInfo, workspaceToVulnerabilities } = await this.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subProjAndWsPath);
225988
- const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(workspacePaths, async (workspacePath) => {
225989
- const dataForAnalysis = projectInfo[workspacePath].dataForAnalysis;
225990
- const vulnerabilities = workspaceToVulnerabilities[workspacePath];
225991
- const augmentedVulnerabilities = reachabilitySupported ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, vulnerabilities) : vulnerabilities.map((v) => ({
225992
- ...v,
225993
- results: {
225994
- type: "otherError",
225995
- message: `Reachability analysis for languages using ${ecosystem} not supported yet`
225996
- }
225997
- }));
225998
- return [workspacePath, augmentedVulnerabilities];
225999
- }));
226000
- if (ecosystem === "MAVEN" || ecosystem === "NUGET" || ecosystem === "RUST") {
226001
- pruneVulnerablePathsToShortestPathsOnly2(ecosystem, workspaceToAugmentedVulnerabilities);
226002
- }
226174
+ const workspacePathToDataForAnalysis = Object.fromEntries(Object.entries(projectInfo).map(([workspacePath, projectInfo2]) => [workspacePath, projectInfo2.dataForAnalysis]));
226175
+ const workspaceToAugmentedVulnerabilities = await this.runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, Object.fromEntries(workspacePaths.map((wsPath) => [wsPath, projectInfo[wsPath].dataForAnalysis.directDependenciesMap ?? {}])), otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported);
226003
226176
  return workspacePaths.map((workspacePath) => {
226004
- const codeAwareScanResultsForAllPackages = [];
226005
- codeAwareScanResultsForAllPackages.push(...this.transformToReportVulnerabilities(workspaceToAugmentedVulnerabilities[workspacePath], projectInfo[workspacePath].directDependenciesMap ?? {}, subprojectPath, workspacePath, this.rootWorkingDirectory));
226006
226177
  return {
226007
226178
  subprojectPath: relative10(this.rootWorkingDirectory, subprojectPath) || ".",
226008
226179
  workspacePath,
226009
- directDependencies: projectInfo[workspacePath].directDependenciesMap ?? {},
226010
- vulnerabilities: codeAwareScanResultsForAllPackages,
226011
- dependencyTree: projectInfo[workspacePath].dataForAnalysis.dependencyTree
226180
+ directDependencies: projectInfo[workspacePath].dataForAnalysis.directDependenciesMap ?? {},
226181
+ vulnerabilities: workspaceToAugmentedVulnerabilities[workspacePath],
226182
+ dependencyTree: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree
226012
226183
  };
226013
226184
  });
226014
226185
  } finally {
226015
226186
  this.sendProgress("RUN_ON_SUBPROJECT", false, subProjAndWsPath.subprojectPath);
226016
226187
  }
226017
226188
  }
226018
- async runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, workspaceData, vulnerabilities) {
226189
+ async runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, workspaceToDirectDependencies, otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported) {
226190
+ const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(Object.keys(workspacePathToDataForAnalysis), async (workspacePath) => {
226191
+ const dataForAnalysis = workspacePathToDataForAnalysis[workspacePath];
226192
+ const vulnerabilities = workspaceToVulnerabilities[workspacePath];
226193
+ const augmentedVulnerabilities = reachabilitySupported ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilities) : vulnerabilities.map((v) => ({
226194
+ ...v,
226195
+ results: {
226196
+ type: "otherError",
226197
+ message: `Reachability analysis for languages using ${ecosystem} not supported yet`
226198
+ }
226199
+ }));
226200
+ return [workspacePath, augmentedVulnerabilities];
226201
+ }));
226202
+ if (ecosystem === "MAVEN" || ecosystem === "NUGET" || ecosystem === "RUST") {
226203
+ pruneVulnerablePathsToShortestPathsOnly(ecosystem, workspaceToAugmentedVulnerabilities);
226204
+ }
226205
+ return mapValues(workspaceToAugmentedVulnerabilities, (augmentedVulnerabilities, workspacePath) => this.transformToReportVulnerabilities(augmentedVulnerabilities, workspaceToDirectDependencies[workspacePath] ?? {}, subprojectPath, workspacePath, this.rootWorkingDirectory));
226206
+ function pruneVulnerablePathsToShortestPathsOnly(ecosystem2, workspaceToAugmentedVulnerabilities2) {
226207
+ const vulnerabilityToWorkspaceToCodeAwareScanSuccess = {};
226208
+ for (const [workspacePath, augmentedVulnerabilities] of Object.entries(workspaceToAugmentedVulnerabilities2)) {
226209
+ augmentedVulnerabilities.forEach((augmentedVulnerability) => {
226210
+ const url3 = augmentedVulnerability.url;
226211
+ const results = augmentedVulnerability.results;
226212
+ if (results.type === "success") {
226213
+ (vulnerabilityToWorkspaceToCodeAwareScanSuccess[url3] ??= {})[workspacePath] = results;
226214
+ }
226215
+ });
226216
+ }
226217
+ const serialize3 = (t4) => `${t4.package}#${t4.class}`.toLowerCase();
226218
+ for (const workspaceToCodeAwareScanSuccess of Object.values(vulnerabilityToWorkspaceToCodeAwareScanSuccess)) {
226219
+ const trie = mkTrie();
226220
+ for (const codeAwareScanSuccess of Object.values(workspaceToCodeAwareScanSuccess)) {
226221
+ const stacks = Array.isArray(codeAwareScanSuccess.detectedOccurrences) ? codeAwareScanSuccess.detectedOccurrences.flatMap((occ) => occ.affectedAppCodePoints) : codeAwareScanSuccess.detectedOccurrences.stacks;
226222
+ stacks.forEach((stack2) => {
226223
+ addPathToTrie(trie, stack2.map(serialize3));
226224
+ });
226225
+ }
226226
+ for (const codeAwareScanSuccess of Object.values(workspaceToCodeAwareScanSuccess)) {
226227
+ const detectedOccurrences = codeAwareScanSuccess.detectedOccurrences;
226228
+ detectedOccurrences.stacks = detectedOccurrences.stacks.filter((stack2) => isShortestPath(trie, stack2.map(serialize3)));
226229
+ if (detectedOccurrences.stacks.length === 0)
226230
+ detectedOccurrences.affectedPackages = [];
226231
+ detectedOccurrences.affectedPackages = detectedOccurrences.affectedPackages.filter((affectedPackage) => {
226232
+ if (affectedPackage === ROOT_NODE_STR || affectedPackage === "UNKNOWN")
226233
+ return true;
226234
+ const [packageName, version3] = affectedPackage.split("@");
226235
+ return detectedOccurrences.stacks.some((stack2) => stack2.some((stackElm) => {
226236
+ if (ecosystem2 === "MAVEN") {
226237
+ const [groupId, artifactId, ...rest] = stackElm.package.split(":");
226238
+ const expectedPackageName = `${groupId}:${artifactId}`;
226239
+ const expectedVersion = rest[rest.length - 1];
226240
+ return expectedPackageName === packageName && expectedVersion === version3;
226241
+ }
226242
+ if (ecosystem2 === "NUGET") {
226243
+ const [expectedPackageName, expectedVersion] = stackElm.package.split("/");
226244
+ return expectedPackageName === packageName && expectedVersion === version3;
226245
+ }
226246
+ return true;
226247
+ }));
226248
+ });
226249
+ }
226250
+ }
226251
+ }
226252
+ }
226253
+ async runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities) {
226019
226254
  const [vulnsWithActualAPIPatterns, result] = partition(vulnerabilities, (v) => Array.isArray(v.vulnerabilityAccessPaths));
226020
226255
  for (const v of result)
226021
226256
  v.results = typeof v.vulnerabilityAccessPaths === "string" ? { type: "noAnalysisCheck", message: v.vulnerabilityAccessPaths } : { type: "missingVulnerabilityPattern" };
226022
226257
  if (!vulnsWithActualAPIPatterns.length)
226023
226258
  return result;
226024
226259
  this.sendProgress("REACHABILITY_ANALYSIS", true, subprojectPath, workspacePath);
226025
- result.push(...await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, vulnerabilities, {
226260
+ result.push(...await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, {
226026
226261
  timeoutInSeconds: this.analysisTimeoutInSeconds,
226027
226262
  memoryLimitInMB: this.analysisMemoryLimitInMb,
226028
226263
  printLogFile: this.options.printAnalysisLogFile,
@@ -226074,7 +226309,8 @@ var CliCore = class {
226074
226309
  dependencyType,
226075
226310
  reachability,
226076
226311
  purl: v.purl,
226077
- purlType: v.purlType
226312
+ purlType: v.purlType,
226313
+ artifactId: v.artifactId
226078
226314
  };
226079
226315
  });
226080
226316
  }
@@ -226087,7 +226323,7 @@ var CliCore = class {
226087
226323
  this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", false, subprojectPath);
226088
226324
  const workspaceToPlainDependencyTree = Object.fromEntries(workspacePaths.map((workspacePath) => [
226089
226325
  workspacePath,
226090
- toPlainDependencyTree(projectInfo[workspacePath].dataForAnalysis.dependencyTree)
226326
+ toPlainDependencyTree(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree)
226091
226327
  ]));
226092
226328
  const dependencyTrees = workspacePaths.map((workspacePath) => ({
226093
226329
  treeType: "v1",
@@ -226096,17 +226332,24 @@ var CliCore = class {
226096
226332
  workspacePath,
226097
226333
  subprojectPath: relative10(rootWorkingDirectory, subprojectPath) || "."
226098
226334
  }));
226099
- if (this.options.socketMode)
226100
- this.reportDependencyTrees = dependencyTrees;
226335
+ if (this.options.socketMode) {
226336
+ this.reportDependencyTrees = workspacePaths.map((workspacePath) => ({
226337
+ treeType: "v1",
226338
+ dependencyTree: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree,
226339
+ ecosystem: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree.ecosystem ?? "NPM",
226340
+ workspacePath,
226341
+ subprojectPath: relative10(rootWorkingDirectory, subprojectPath) || "."
226342
+ }));
226343
+ }
226101
226344
  if (this.shareWithDashboard)
226102
226345
  sendDependencyTreesToDashboard(dependencyTrees, this.reportId, this.apiKey);
226103
226346
  const workspaceToVulnerabilities = Object.fromEntries(await asyncMap(workspacePaths, async (workspacePath, idx) => this.spinner.wrap(`Scanning for vulnerabilities: (${subProjAndWsPath.packageManagerName}) (${idx + 1}/${workspacePaths.length}) ${workspacePath}`, async () => {
226104
- const dependencyTree = projectInfo[workspacePath].dataForAnalysis.dependencyTree;
226347
+ const dependencyTree = projectInfo[workspacePath].dataForAnalysis.data.dependencyTree;
226105
226348
  this.sendProgress("SCAN_FOR_VULNERABILITIES", true, subprojectPath, workspacePath);
226106
226349
  try {
226107
226350
  return [
226108
226351
  workspacePath,
226109
- this.options.socketMode ? await scanForVulnerabilitiesSocketMode(projectInfo[workspacePath].dataForAnalysis.dependencyTree) : (await scanForVulnerabilities(dependencyTree, this.options.offlineDatabase, this.apiKey, Number(this.options.timeout))).vulnerabilities
226352
+ this.options.socketMode ? await scanForVulnerabilitiesSocketMode(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree) : (await scanForVulnerabilities(dependencyTree, this.options.offlineDatabase, this.apiKey, Number(this.options.timeout))).vulnerabilities
226110
226353
  ];
226111
226354
  } catch (e) {
226112
226355
  logger.error(`Scanning for vulnerabilities failed for subproject ${subprojectPath} in workspace ${workspacePath}`);
@@ -226290,7 +226533,7 @@ async function computeInputForComputingFixes(path2, options) {
226290
226533
  }
226291
226534
  const cliCore = new CliCore(path2, { ...defaultCliOptions, socketMode: "true" });
226292
226535
  const results = await asyncMap(supportedSubprojects, async (subproject) => cliCore.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subproject));
226293
- const { artifacts, purlToIndex } = computeSBOMTaskArtifacts(results.flatMap((r2) => Object.values(r2.projectInfo).map((info) => info.dataForAnalysis.dependencyTree)));
226536
+ const { artifacts, purlToIndex } = computeSBOMTaskArtifacts(results.flatMap((r2) => Object.values(r2.projectInfo).map((info) => info.dataForAnalysis.data.dependencyTree)));
226294
226537
  const vulnerableArtifactIdsPerVulnerability = computeVulnerableArtifactIdsPerVulnerability(results.flatMap((r2) => Object.values(r2.workspaceToVulnerabilities).flat()), purlToIndex);
226295
226538
  return { artifacts, vulnerableArtifactIdsPerVulnerability };
226296
226539
  }
@@ -226375,7 +226618,7 @@ async function useSocketComputeFixEndpoint(artifacts, vulnerableArtifactIdsForGh
226375
226618
  // dist/index.js
226376
226619
  var program2 = new Command();
226377
226620
  var run2 = new Command();
226378
- run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <dirs...>", "globs for directories to include from the detection of subprojects (space-separated). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <dirs...>", "globs for directories to exclude from the detection of subprojects (space-separated). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze. Currently NPM, PIP, MAVEN and GO are supported. Default is all supported ecosystems.", (ecosystems) => ecosystems.split(" ").map((e) => e.toUpperCase())).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
226621
+ run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <dirs...>", "globs for directories to include from the detection of subprojects (space-separated). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <dirs...>", "globs for directories to exclude from the detection of subprojects (space-separated). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze. Currently NPM, PIP, MAVEN and GO are supported. Default is all supported ecosystems.", (ecosystems) => ecosystems.split(" ").map((e) => e.toUpperCase())).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
226379
226622
  process.env.DOCKER_IMAGE_TAG ??= version2;
226380
226623
  await new CliCore(path2, options).main();
226381
226624
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.9.30",
3
+ "version": "14.9.32",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {