@coana-tech/cli 14.12.109 → 14.12.111

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/cli.mjs CHANGED
@@ -206525,6 +206525,7 @@ var Spinner = class _Spinner {
206525
206525
  };
206526
206526
 
206527
206527
  // ../utils/src/command-utils.ts
206528
+ var DEFAULT_TIMEOUT_MS = 30 * 60 * 1e3;
206528
206529
  async function execAndLogOnFailure(cmd, dir, options, logLevel = "info") {
206529
206530
  const result = await execNeverFail(cmd, dir, options);
206530
206531
  if (result.error) logCommandOutput(result, cmd, dir, logLevel);
@@ -206549,10 +206550,11 @@ async function execNeverFail(cmd, dir, options) {
206549
206550
  return new Promise((resolve45) => {
206550
206551
  let args2;
206551
206552
  if (typeof cmd !== "string") [cmd, ...args2] = cmd;
206553
+ const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
206552
206554
  const childProcess = execFile(
206553
206555
  cmd,
206554
206556
  args2,
206555
- { ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0 },
206557
+ { ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0, timeout },
206556
206558
  (error, stdout, stderr) => {
206557
206559
  resolve45({ error, stdout, stderr });
206558
206560
  }
@@ -225413,6 +225415,7 @@ var Spinner2 = class _Spinner {
225413
225415
  };
225414
225416
 
225415
225417
  // ../utils/dist/command-utils.js
225418
+ var DEFAULT_TIMEOUT_MS2 = 30 * 60 * 1e3;
225416
225419
  async function execAndLogOnFailure3(cmd, dir, options, logLevel = "info") {
225417
225420
  const result = await execNeverFail3(cmd, dir, options);
225418
225421
  if (result.error)
@@ -225436,7 +225439,8 @@ async function execNeverFail3(cmd, dir, options) {
225436
225439
  let args2;
225437
225440
  if (typeof cmd !== "string")
225438
225441
  [cmd, ...args2] = cmd;
225439
- const childProcess = execFile2(cmd, args2, { ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0 }, (error, stdout, stderr) => {
225442
+ const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS2;
225443
+ const childProcess = execFile2(cmd, args2, { ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0, timeout }, (error, stdout, stderr) => {
225440
225444
  resolve45({ error, stdout, stderr });
225441
225445
  });
225442
225446
  if (options?.pipe) {
@@ -232202,6 +232206,7 @@ var pullDockerImage = memoize(async (image) => {
232202
232206
  }
232203
232207
  return true;
232204
232208
  });
232209
+ var ONE_DAY_IN_MS = 24 * 60 * 60 * 1e3;
232205
232210
  var TMP_DIR_IN_DOCKER = "/coana-tmp";
232206
232211
  var SOCKET_PATH_IN_DOCKER = "/coana.sock";
232207
232212
  var OtherModulesCommunicator = class {
@@ -232268,7 +232273,7 @@ var OtherModulesCommunicator = class {
232268
232273
  succeeded = await execPipeAndLogOnFailure2(
232269
232274
  [await getNodeExecutable(), PACKAGE_MANAGER_SCRIPT_PATH(), commandName, ...finalArgs],
232270
232275
  subprojectPath,
232271
- { env }
232276
+ { env, timeout: ONE_DAY_IN_MS }
232272
232277
  );
232273
232278
  } else {
232274
232279
  finalArgs.push(...extraDockerArgs ?? []);
@@ -232342,7 +232347,7 @@ var OtherModulesCommunicator = class {
232342
232347
  succeeded = await execPipeAndLogOnFailure2(
232343
232348
  [await getNodeExecutable(), scriptPath, commandName, ...finalArgs],
232344
232349
  subprojectPath,
232345
- { env }
232350
+ { env, timeout: ONE_DAY_IN_MS }
232346
232351
  );
232347
232352
  } else {
232348
232353
  const dockerImage = await findReachabilityAnalyzersDockerImage(ecosystem);
@@ -232387,7 +232392,7 @@ var OtherModulesCommunicator = class {
232387
232392
  -v=${this.options.coanaSocketPath}:${SOCKET_PATH_IN_DOCKER}
232388
232393
  ${await getEcosystemSpecificDockerArgs(ecosystem)}
232389
232394
  ${envArgs} ${image} ${entryPoint} ${commandName} ${args2}`;
232390
- return execPipeAndLogOnFailure2(cmd, subprojectPath, { env });
232395
+ return execPipeAndLogOnFailure2(cmd, subprojectPath, { env, timeout: ONE_DAY_IN_MS });
232391
232396
  }
232392
232397
  async getWorkspacePaths(packageManagerName, subprojectPath) {
232393
232398
  return this.runPackageManagerCommandWithOutput("getWorkspacePaths", packageManagerName, subprojectPath);
@@ -235780,7 +235785,7 @@ function toSocketReachabilitySchema(vulnerability) {
235780
235785
  }
235781
235786
 
235782
235787
  // dist/internal/socket-report-socket-dependency-tree.js
235783
- function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1ReachabilityScanId) {
235788
+ function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1ReachabilityScanId, workspaceDiagnostics) {
235784
235789
  const artifactIdToArtifact = Object.fromEntries(artifacts.map((artifact) => [artifact.id, artifact]));
235785
235790
  for (const vulnerability of vulnerabilities) {
235786
235791
  const component = artifactIdToArtifact[vulnerability.artifactId];
@@ -235808,7 +235813,8 @@ function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1Reac
235808
235813
  }
235809
235814
  return {
235810
235815
  components: artifacts,
235811
- tier1ReachabilityScanId
235816
+ tier1ReachabilityScanId,
235817
+ workspaceDiagnostics
235812
235818
  };
235813
235819
  }
235814
235820
 
@@ -250700,7 +250706,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
250700
250706
  }
250701
250707
 
250702
250708
  // dist/version.js
250703
- var version3 = "14.12.109";
250709
+ var version3 = "14.12.111";
250704
250710
 
250705
250711
  // dist/cli-core.js
250706
250712
  var { mapValues, omit, partition, pick } = import_lodash15.default;
@@ -250921,6 +250927,7 @@ var CliCore = class {
250921
250927
  workspaces.forEach((workspace) => logger.info(bold(` ${workspace}`)));
250922
250928
  });
250923
250929
  const vulnsWithResults = [];
250930
+ const allWorkspaceDiagnostics = [];
250924
250931
  const allEcosystems = Object.entries(ecosystemToWorkspaceToAnalysisData);
250925
250932
  const totalEcosystems = allEcosystems.length;
250926
250933
  let currentOverallWorkspace = 0;
@@ -250930,7 +250937,7 @@ var CliCore = class {
250930
250937
  if (!isEcosystemToAnalyze) {
250931
250938
  logger.info(`Skipping reachability analysis for ecosystem ${getPurlType(ecosystem)} since it is not included in the list of ecosystems to analyze.`);
250932
250939
  }
250933
- vulnsWithResults.push(...Object.values(await this.runReachabilityAnalysisForWorkspaces(
250940
+ const { vulnerabilities, diagnostics } = await this.runReachabilityAnalysisForWorkspaces(
250934
250941
  workspaceToAnalysisData,
250935
250942
  ecosystemToWorkspaceToVulnerabilities[ecosystem] ?? {},
250936
250943
  {},
@@ -250943,15 +250950,81 @@ var CliCore = class {
250943
250950
  currentOverallWorkspace++;
250944
250951
  logger.info(bold(`Analyzing ecosystem ${ecosystem} for project ${workspaceName} (${workspaceNumber}/${totalWorkspacesForCurrentEcosystem}) - Overall progress: Project ${currentOverallWorkspace}/${totalWorkspaces}, ecosystem ${ecosystemIndex + 1}/${totalEcosystems}`));
250945
250952
  }
250946
- )).flat());
250953
+ );
250954
+ vulnsWithResults.push(...Object.values(vulnerabilities).flat());
250955
+ for (const [workspacePath, workspaceDiagnostics] of Object.entries(diagnostics)) {
250956
+ allWorkspaceDiagnostics.push({
250957
+ subprojectPath: relative19(this.rootWorkingDirectory, workspacePath) || ".",
250958
+ workspacePath: ".",
250959
+ purl_type: getPurlType(ecosystem),
250960
+ diagnostics: workspaceDiagnostics
250961
+ });
250962
+ }
250947
250963
  this.sendProgress("RUN_ON_SUBPROJECT", false, this.rootWorkingDirectory);
250948
250964
  }
250965
+ this.displayWorkspaceDiagnosticsSummary(allWorkspaceDiagnostics);
250949
250966
  await this.shareLogIfAnalysisError(vulnsWithResults);
250950
- const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults, this.reportId);
250967
+ const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults, this.reportId, allWorkspaceDiagnostics);
250951
250968
  const outputFile = resolve43(this.options.socketMode);
250952
250969
  await writeFile14(outputFile, JSON.stringify(socketReport, null, 2));
250953
250970
  logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
250954
250971
  }
250972
+ displayWorkspaceDiagnosticsSummary(diagnosticsEntries) {
250973
+ const warnings = [];
250974
+ const infos = [];
250975
+ const typeToEntry = /* @__PURE__ */ new Map();
250976
+ for (const entry of diagnosticsEntries) {
250977
+ for (const warning of entry.diagnostics.warnings) {
250978
+ const existing = typeToEntry.get(warning.type);
250979
+ const workspaceLabel = `${entry.subprojectPath} (${entry.purl_type})`;
250980
+ if (existing) {
250981
+ existing.workspaces.push(workspaceLabel);
250982
+ } else {
250983
+ const newEntry = { message: warning.message, workspaces: [workspaceLabel], severity: warning.severity };
250984
+ typeToEntry.set(warning.type, newEntry);
250985
+ if (warning.severity === "warning") {
250986
+ warnings.push(newEntry);
250987
+ } else {
250988
+ infos.push(newEntry);
250989
+ }
250990
+ }
250991
+ }
250992
+ }
250993
+ if (warnings.length === 0 && infos.length === 0) {
250994
+ return;
250995
+ }
250996
+ logger.info("");
250997
+ if (warnings.length > 0) {
250998
+ logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
250999
+ logger.info(bold(kleur_default.red(" REACHABILITY ANALYSIS WARNINGS ")));
251000
+ logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
251001
+ for (const { message: message2, workspaces } of warnings) {
251002
+ logger.info("");
251003
+ logger.info(kleur_default.red(`\u26A0 ${message2}:`));
251004
+ for (const workspace of workspaces) {
251005
+ logger.info(kleur_default.red(` ${workspace}`));
251006
+ }
251007
+ }
251008
+ logger.info("");
251009
+ logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
251010
+ logger.info("");
251011
+ }
251012
+ if (infos.length > 0) {
251013
+ logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
251014
+ logger.info(bold(kleur_default.cyan(" REACHABILITY ANALYSIS INFO ")));
251015
+ logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
251016
+ for (const { message: message2, workspaces } of infos) {
251017
+ logger.info("");
251018
+ logger.info(kleur_default.cyan(`\u2139 ${message2}:`));
251019
+ for (const workspace of workspaces) {
251020
+ logger.info(kleur_default.cyan(` ${workspace}`));
251021
+ }
251022
+ }
251023
+ logger.info("");
251024
+ logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
251025
+ logger.info("");
251026
+ }
251027
+ }
250955
251028
  async shareLogIfAnalysisError(vulns) {
250956
251029
  if (this.dashboardAPI.disableAnalyticsSharing) {
250957
251030
  return;
@@ -251180,7 +251253,7 @@ Subproject: ${subproject}`);
251180
251253
  const { ecosystem, subprojectPath, workspacePaths } = subProjAndWsPath;
251181
251254
  const { projectInfo, workspaceToVulnerabilities } = await this.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subProjAndWsPath);
251182
251255
  const workspacePathToDataForAnalysis = Object.fromEntries(Object.entries(projectInfo).map(([workspacePath, projectInfo2]) => [workspacePath, projectInfo2.dataForAnalysis]));
251183
- const workspaceToAugmentedVulnerabilities = await this.runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, Object.fromEntries(workspacePaths.map((wsPath) => [wsPath, projectInfo[wsPath].dataForAnalysis.directDependenciesMap ?? {}])), otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported);
251256
+ const { vulnerabilities: workspaceToAugmentedVulnerabilities } = await this.runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, Object.fromEntries(workspacePaths.map((wsPath) => [wsPath, projectInfo[wsPath].dataForAnalysis.directDependenciesMap ?? {}])), otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported);
251184
251257
  return workspacePaths.filter((workspacePath) => {
251185
251258
  return workspaceToAugmentedVulnerabilities[workspacePath] !== void 0;
251186
251259
  }).map((workspacePath) => {
@@ -251204,12 +251277,12 @@ Subproject: ${subproject}`);
251204
251277
  let npmAnalysisMutex = Promise.resolve();
251205
251278
  const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(workspaces, async (workspacePath, index2) => {
251206
251279
  analysisStarting?.(workspacePath, index2 + 1, totalWorkspaces);
251207
- const vulnerabilities = workspaceToVulnerabilities[workspacePath] ?? [];
251280
+ const vulnerabilities2 = workspaceToVulnerabilities[workspacePath] ?? [];
251208
251281
  const workspacePrefix = shouldIncludeWorkspaceInLogs ? `[${workspacePath}] ` : "";
251209
- logger.info(`${workspacePrefix}Process workspace ${workspacePath} with ${vulnerabilities.length} ${pluralize(vulnerabilities.length, "vulnerability")}`);
251282
+ logger.info(`${workspacePrefix}Process workspace ${workspacePath} with ${vulnerabilities2.length} ${pluralize(vulnerabilities2.length, "vulnerability")}`);
251210
251283
  try {
251211
251284
  const dataForAnalysis = workspacePathToDataForAnalysis[workspacePath];
251212
- const [vulnsSatisfyingThreshold, vulnerabilitiesBelowThreshold] = this.options.minSeverity ? partition(vulnerabilities, (v) => !v.severity || shouldAnalyzeBasedOnSeverity(v.severity, this.options.minSeverity)) : [vulnerabilities, []];
251285
+ const [vulnsSatisfyingThreshold, vulnerabilitiesBelowThreshold] = this.options.minSeverity ? partition(vulnerabilities2, (v) => !v.severity || shouldAnalyzeBasedOnSeverity(v.severity, this.options.minSeverity)) : [vulnerabilities2, []];
251213
251286
  const [vulnsUnreachableFromPrecomputation, vulnerabilitiesToAnalyze] = this.options.useUnreachableFromPrecomputation ? partition(vulnsSatisfyingThreshold, (v) => "precomputedReachabilityResult" in v && v.precomputedReachabilityResult?.type === "unreachable") : [[], vulnsSatisfyingThreshold];
251214
251287
  const vulnerabilitiesBelowThresholdWithResults = vulnerabilitiesBelowThreshold.map((v) => ({
251215
251288
  ...v,
@@ -251226,25 +251299,33 @@ Subproject: ${subproject}`);
251226
251299
  }
251227
251300
  }));
251228
251301
  if (vulnerabilitiesBelowThreshold.length > 0) {
251229
- logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnerabilitiesBelowThreshold.length} ${pluralize(vulnerabilities.length, "vulnerability")} with severity below the min severity threshold: ${this.options.minSeverity}`);
251302
+ logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnerabilitiesBelowThreshold.length} ${pluralize(vulnerabilities2.length, "vulnerability")} with severity below the min severity threshold: ${this.options.minSeverity}`);
251230
251303
  }
251231
251304
  if (vulnsUnreachableFromPrecomputation.length > 0) {
251232
- logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnsUnreachableFromPrecomputation.length} ${pluralize(vulnerabilities.length, "vulnerability")} that ${vulnerabilities.length !== 1 ? "are" : "is"} already known to be unreachable from precomputed (Tier 2) reachability analysis`);
251305
+ logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnsUnreachableFromPrecomputation.length} ${pluralize(vulnerabilities2.length, "vulnerability")} that ${vulnerabilities2.length !== 1 ? "are" : "is"} already known to be unreachable from precomputed (Tier 2) reachability analysis`);
251233
251306
  }
251234
251307
  if (vulnerabilitiesToAnalyze.length > 0) {
251235
- logger.info(`${workspacePrefix}Running reachability analysis for ${vulnerabilitiesToAnalyze.length} ${pluralize(vulnerabilities.length, "vulnerability")}`);
251308
+ logger.info(`${workspacePrefix}Running reachability analysis for ${vulnerabilitiesToAnalyze.length} ${pluralize(vulnerabilities2.length, "vulnerability")}`);
251236
251309
  }
251237
251310
  let augmentedVulnerabilitiesToAnalyze;
251311
+ let workspaceDiagnostics = {
251312
+ sourceFilesDetected: "UNKNOWN",
251313
+ preinstalledDependencies: "UNKNOWN",
251314
+ warnings: []
251315
+ };
251238
251316
  if (vulnerabilitiesToAnalyze.length === 0) {
251239
251317
  augmentedVulnerabilitiesToAnalyze = [];
251240
251318
  } else if (reachabilitySupported && !this.shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath, workspacePrefix)) {
251319
+ let analysisResult;
251241
251320
  if (ecosystem === "NPM" && concurrency > 1) {
251242
- augmentedVulnerabilitiesToAnalyze = await this.runReachabilityAnalysisWithoutConcurrency(async () => npmAnalysisMutex, (mutex) => {
251321
+ analysisResult = await this.runReachabilityAnalysisWithoutConcurrency(async () => npmAnalysisMutex, (mutex) => {
251243
251322
  npmAnalysisMutex = mutex;
251244
251323
  }, otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
251245
251324
  } else {
251246
- augmentedVulnerabilitiesToAnalyze = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
251325
+ analysisResult = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
251247
251326
  }
251327
+ augmentedVulnerabilitiesToAnalyze = analysisResult.vulnerabilities;
251328
+ workspaceDiagnostics = analysisResult.diagnostics;
251248
251329
  } else {
251249
251330
  augmentedVulnerabilitiesToAnalyze = vulnerabilitiesToAnalyze.map((v) => ({
251250
251331
  ...v,
@@ -251259,26 +251340,32 @@ Subproject: ${subproject}`);
251259
251340
  ...augmentedVulnerabilitiesToAnalyze,
251260
251341
  ...vulnerabilitiesBelowThresholdWithResults
251261
251342
  ];
251262
- return [workspacePath, augmentedVulnerabilities];
251343
+ return [workspacePath, { vulnerabilities: augmentedVulnerabilities, diagnostics: workspaceDiagnostics }];
251263
251344
  } catch (e) {
251264
251345
  logger.error(`${workspacePrefix}Reachability analysis failed for workspace ${workspacePath} in subproject ${subprojectPath}: ${e.message}`);
251265
251346
  return [
251266
251347
  workspacePath,
251267
- vulnerabilities.map((v) => ({
251268
- ...v,
251269
- results: {
251270
- type: "otherError",
251271
- message: e.message || "Unknown error"
251272
- }
251273
- }))
251348
+ {
251349
+ vulnerabilities: vulnerabilities2.map((v) => ({
251350
+ ...v,
251351
+ results: {
251352
+ type: "otherError",
251353
+ message: e.message || "Unknown error"
251354
+ }
251355
+ })),
251356
+ diagnostics: { sourceFilesDetected: "UNKNOWN", preinstalledDependencies: "UNKNOWN", warnings: [] }
251357
+ }
251274
251358
  ];
251275
251359
  }
251276
251360
  }, concurrency));
251277
- const successfulWorkspaceToAugmentedVulnerabilities = Object.fromEntries(Object.entries(workspaceToAugmentedVulnerabilities).filter(([_, vulns]) => vulns !== void 0));
251361
+ const successfulWorkspaceResults = Object.fromEntries(Object.entries(workspaceToAugmentedVulnerabilities).filter(([_, result]) => result !== void 0));
251362
+ const successfulWorkspaceToAugmentedVulnerabilities = mapValues(successfulWorkspaceResults, (result) => result.vulnerabilities);
251278
251363
  if (ecosystem === "MAVEN" || ecosystem === "NUGET") {
251279
251364
  pruneVulnerablePathsToShortestPathsOnly(ecosystem, successfulWorkspaceToAugmentedVulnerabilities);
251280
251365
  }
251281
- return mapValues(successfulWorkspaceToAugmentedVulnerabilities, (augmentedVulnerabilities, workspacePath) => this.transformToReportVulnerabilities(augmentedVulnerabilities, workspaceToDirectDependencies[workspacePath] ?? {}, subprojectPath, workspacePath, this.rootWorkingDirectory));
251366
+ const vulnerabilities = mapValues(successfulWorkspaceToAugmentedVulnerabilities, (augmentedVulnerabilities, workspacePath) => this.transformToReportVulnerabilities(augmentedVulnerabilities, workspaceToDirectDependencies[workspacePath] ?? {}, subprojectPath, workspacePath, this.rootWorkingDirectory));
251367
+ const diagnostics = mapValues(successfulWorkspaceResults, (result) => result.diagnostics);
251368
+ return { vulnerabilities, diagnostics };
251282
251369
  function pruneVulnerablePathsToShortestPathsOnly(ecosystem2, workspaceToAugmentedVulnerabilities2) {
251283
251370
  const vulnerabilityToWorkspaceToStacks = {};
251284
251371
  for (const [workspacePath, augmentedVulnerabilities] of Object.entries(workspaceToAugmentedVulnerabilities2))
@@ -251329,13 +251416,13 @@ Subproject: ${subproject}`);
251329
251416
  resolveCurrentAnalysis = resolve45;
251330
251417
  }));
251331
251418
  await previousAnalysis;
251332
- let augmentedVulnerabilitiesToAnalyze;
251419
+ let analysisResult;
251333
251420
  try {
251334
- augmentedVulnerabilitiesToAnalyze = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
251421
+ analysisResult = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
251335
251422
  } finally {
251336
251423
  resolveCurrentAnalysis();
251337
251424
  }
251338
- return augmentedVulnerabilitiesToAnalyze;
251425
+ return analysisResult;
251339
251426
  }
251340
251427
  shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath, workspacePrefix = "") {
251341
251428
  const shouldExcludeWorkspaceForAnalysis = shouldIgnoreDueToExcludeDirsOrChangedFiles({
@@ -251354,10 +251441,14 @@ Subproject: ${subproject}`);
251354
251441
  for (const v of result)
251355
251442
  v.results = typeof v.vulnerabilityAccessPaths === "string" ? { type: "noAnalysisCheck", message: v.vulnerabilityAccessPaths } : { type: "missingVulnerabilityPattern" };
251356
251443
  logger.info(`${workspacePrefix}Reachability analysis not possible for ${result.length} of the ${pluralize(vulnerabilities.length, "vulnerability")}`);
251357
- if (!vulnsWithActualAPIPatterns.length)
251358
- return result;
251444
+ if (!vulnsWithActualAPIPatterns.length) {
251445
+ return {
251446
+ vulnerabilities: result,
251447
+ diagnostics: { sourceFilesDetected: "UNKNOWN", preinstalledDependencies: "UNKNOWN", warnings: [] }
251448
+ };
251449
+ }
251359
251450
  this.sendProgress("REACHABILITY_ANALYSIS", true, subprojectPath, workspacePath);
251360
- result.push(...await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, {
251451
+ const analysisResult = await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, {
251361
251452
  timeoutSeconds: {
251362
251453
  allVulnRuns: this.analysisTimeoutInSeconds,
251363
251454
  bucketedRuns: bucketedAnalysisTimeoutInSeconds
@@ -251371,9 +251462,10 @@ Subproject: ${subproject}`);
251371
251462
  disableBucketing: !!this.options.disableAnalysisSplitting,
251372
251463
  lightweightReachability: this.options.lightweightReachability,
251373
251464
  skipCacheUsage: this.options.skipCacheUsage
251374
- }));
251465
+ });
251466
+ result.push(...analysisResult.vulnerabilities);
251375
251467
  this.sendProgress("REACHABILITY_ANALYSIS", false, subprojectPath, workspacePath);
251376
- return result;
251468
+ return { vulnerabilities: result, diagnostics: analysisResult.diagnostics };
251377
251469
  }
251378
251470
  async sendProgress(type, isStartEvent, subprojectPath, workspacePath) {
251379
251471
  await this.dashboardAPI.registerCLIProgress({
@@ -251590,7 +251682,7 @@ compareReportsCommand.name("compare-reports").argument("<baselineReportPath>", "
251590
251682
  var findVulnerabilities = new Command();
251591
251683
  findVulnerabilities.name("find-vulnerabilities").requiredOption("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket.").action(async (options) => {
251592
251684
  const { artifacts } = await fetchArtifactsFromManifestsTarHash(options.manifestsTarHash);
251593
- console.log(i(artifacts.flatMap((a4) => a4.vulnerabilities?.map((v) => v.ghsaId) ?? [])));
251685
+ console.log(JSON.stringify(i(artifacts.flatMap((a4) => a4.vulnerabilities?.map((v) => v.ghsaId) ?? []))));
251594
251686
  });
251595
251687
  program2.name("coana-cli").addCommand(run2, { isDefault: true }).addCommand(findVulnerabilities).addCommand(applyFixes).addCommand(compareReportsCommand).addCommand(computeFixesAndUpgradePurlsCmd, { hidden: true }).configureHelp({ sortSubcommands: true }).version(version3);
251596
251688
  program2.parseAsync();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.12.109",
3
+ "version": "14.12.111",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {