@coana-tech/cli 14.11.14 → 14.11.16

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
@@ -197870,6 +197870,41 @@ async function registerAnalysisMetadataSocket(subprojectPath, workspacePath, eco
197870
197870
  handleError(error, "Error registering analysis metadata", false);
197871
197871
  }
197872
197872
  }
197873
+ async function getLatestBucketsSocket(subprojectPath, workspacePath) {
197874
+ try {
197875
+ const url2 = getSocketApiUrl("tier1-reachability-scan/latest-buckets");
197876
+ const params = {
197877
+ workspacePath,
197878
+ subprojectPath,
197879
+ repoName: process.env.SOCKET_REPO_NAME,
197880
+ branchName: process.env.SOCKET_BRANCH_NAME
197881
+ };
197882
+ const response = await axios2.get(url2, {
197883
+ headers: getAuthHeaders(),
197884
+ params
197885
+ });
197886
+ const responseData = response.data;
197887
+ if (responseData.type !== "success") {
197888
+ throw new Error(response.data.reason);
197889
+ }
197890
+ return {
197891
+ cliVersion: responseData.value.coana_cli_version,
197892
+ buckets: responseData.value.buckets.map((b) => ({
197893
+ vulnUrls: b.ghsas,
197894
+ heuristicName: b.heuristicName
197895
+ }))
197896
+ };
197897
+ } catch (error) {
197898
+ if (error?.response?.data?.message === "No successful report found") {
197899
+ return void 0;
197900
+ }
197901
+ logger.warn(
197902
+ "Unable to retrieve cached analysis configuration. Will continue with default configuration.",
197903
+ error?.message
197904
+ );
197905
+ return void 0;
197906
+ }
197907
+ }
197873
197908
  async function useSocketComputeFixEndpoint(artifacts, vulnerableArtifactIdsForGhsas) {
197874
197909
  try {
197875
197910
  const url2 = getSocketApiUrl("fixes/compute-fixes");
@@ -197945,7 +197980,8 @@ function getSocketAPI() {
197945
197980
  sendErrorReportToSocketDashboard,
197946
197981
  registerSubprojectsSocket,
197947
197982
  registerCLIProgressSocket,
197948
- registerAnalysisMetadataSocket
197983
+ registerAnalysisMetadataSocket,
197984
+ getLatestBucketsSocket
197949
197985
  };
197950
197986
  }
197951
197987
 
@@ -205338,7 +205374,7 @@ var getNpmBin = once(async () => {
205338
205374
  return npmBin;
205339
205375
  });
205340
205376
  async function actuallyRunInstall(specificPackagesArgs = [], dir) {
205341
- const installationCommand = cmdt2`${await getNpmBin()} install -f --ignore-scripts --no-fund --no-audit ${specificPackagesArgs}`;
205377
+ const installationCommand = cmdt2`${await getNpmBin()} install -f --ignore-scripts --no-fund --no-audit --no-progress ${specificPackagesArgs}`;
205342
205378
  logger.info(`running installation command: ${installationCommand}`);
205343
205379
  return execAndLogOnFailure2(installationCommand, dir);
205344
205380
  }
@@ -205446,6 +205482,8 @@ var NpmFixingManager = class extends NpmEcosystemFixingManager {
205446
205482
  }
205447
205483
  }
205448
205484
  async finalizeFixes() {
205485
+ logger.info(`Adjusting lock file changes by running a npm install command`);
205486
+ await actuallyRunInstall(void 0, resolve9(this.rootDir, this.subprojectPath));
205449
205487
  }
205450
205488
  };
205451
205489
 
@@ -205454,7 +205492,16 @@ import { readFile as readFile12, writeFile as writeFile4 } from "fs/promises";
205454
205492
  import { resolve as resolve10 } from "path";
205455
205493
  var import_yaml = __toESM(require_dist10(), 1);
205456
205494
  var import_lockfile_file2 = __toESM(require_lib25(), 1);
205495
+ import { existsSync as existsSync9 } from "fs";
205457
205496
  var PnpmFixingManager = class extends NpmEcosystemFixingManager {
205497
+ pnpmMajorVersion;
205498
+ async getPnpmMajorVersion() {
205499
+ if (!this.pnpmMajorVersion) {
205500
+ const pnpmVersion = await runCommandResolveStdOut(cmdt`pnpm -v`);
205501
+ this.pnpmMajorVersion = parseInt(pnpmVersion.trim().split(".")[0]);
205502
+ }
205503
+ return this.pnpmMajorVersion;
205504
+ }
205458
205505
  async installSpecificPackages(workspacePath, isDev, packagesToInstall) {
205459
205506
  try {
205460
205507
  const isInstallingInRootOfWorkspace = workspacePath === "." && (await getWorkspacePathsFromPnpmLockFile(this.rootDir, false)).length > 1;
@@ -205473,7 +205520,7 @@ var PnpmFixingManager = class extends NpmEcosystemFixingManager {
205473
205520
  }
205474
205521
  }
205475
205522
  async actuallyRunInstall(specificPackagesCmd = [], workspacePath = ".") {
205476
- const installationCommand = cmdt`pnpm install --ignore-scripts ${specificPackagesCmd}`;
205523
+ const installationCommand = cmdt`pnpm install --ignore-scripts${await this.getPnpmMajorVersion() >= 9 && specificPackagesCmd.length === 0 ? "--no-frozen-lockfile" : ""} --config.confirmModulesPurge=false ${specificPackagesCmd}`;
205477
205524
  logger.info(`running installation command: ${installationCommand}`);
205478
205525
  await exec(installationCommand, resolve10(this.rootDir, this.subprojectPath, workspacePath));
205479
205526
  }
@@ -205556,6 +205603,11 @@ var PnpmFixingManager = class extends NpmEcosystemFixingManager {
205556
205603
  ])
205557
205604
  );
205558
205605
  const pnpmWorkspaceYamlFile = resolve10(this.rootDir, this.subprojectPath, "pnpm-workspace.yaml");
205606
+ if (!existsSync9(pnpmWorkspaceYamlFile)) {
205607
+ throw new Error(
205608
+ `pnpm-workspace.yaml could not be found in ${pnpmWorkspaceYamlFile}. The lockfile indicates that pnpm catalogs are used and they must be updated, which is not possible without a pnpm-workspace.yaml file`
205609
+ );
205610
+ }
205559
205611
  const yamlAST = await readYamlFile(pnpmWorkspaceYamlFile);
205560
205612
  fixCatalogVersions(yamlAST, catalogFixes);
205561
205613
  await writeYamlFile(yamlAST, pnpmWorkspaceYamlFile);
@@ -205567,7 +205619,7 @@ var PnpmFixingManager = class extends NpmEcosystemFixingManager {
205567
205619
  }
205568
205620
  }
205569
205621
  async finalizeFixes() {
205570
- const cmd = cmdt`pnpm install --ignore-scripts --fix-lockfile`;
205622
+ const cmd = cmdt`pnpm install --ignore-scripts --fix-lockfile --config.confirmModulesPurge=false `;
205571
205623
  logger.info(`Adjusting lock file changes by running '${cmd}'`);
205572
205624
  await exec(cmd, resolve10(this.rootDir, this.subprojectPath));
205573
205625
  }
@@ -205621,7 +205673,7 @@ import { resolve as resolve12 } from "path";
205621
205673
 
205622
205674
  // ../utils/src/package-utils.ts
205623
205675
  import { parse as parse2, join as join7, resolve as resolve11, normalize as normalize3, dirname as dirname4, basename as basename3, relative as relative4 } from "path";
205624
- import { existsSync as existsSync9, readFileSync as readFileSync2, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
205676
+ import { existsSync as existsSync10, readFileSync as readFileSync2, readdirSync as readdirSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
205625
205677
  function setFieldInPackageJson(workspaceRoot, field, value) {
205626
205678
  const packageJSONContentObj = getPackageJsonObject2(workspaceRoot);
205627
205679
  if (!packageJSONContentObj) return void 0;
@@ -205638,7 +205690,7 @@ function writePackageJsonContent(workspaceRoot, packageJsonContent) {
205638
205690
  }
205639
205691
  function getPackageJsonContent2(workspaceRoot) {
205640
205692
  const packageJsonPath = getPackageJSONPath2(workspaceRoot);
205641
- if (existsSync9(packageJsonPath)) return readFileSync2(packageJsonPath, "utf8");
205693
+ if (existsSync10(packageJsonPath)) return readFileSync2(packageJsonPath, "utf8");
205642
205694
  return void 0;
205643
205695
  }
205644
205696
  function getPackageJSONPath2(workspaceRoot) {
@@ -205771,9 +205823,10 @@ var YarnFixingManager = class extends NpmEcosystemFixingManager {
205771
205823
  logger.info(`Failed to install packages: ${installResult.error.message}`);
205772
205824
  logger.info(`stdout`, installResult.stdout);
205773
205825
  logger.info(`stderr`, installResult.stderr);
205774
- logger.info("yarn version", await runCommandResolveStdOut("yarn -v", installDir));
205826
+ logger.info("yarn version", await this.runYarnCommand(cmdt`yarn -v`, installDir));
205775
205827
  throw new Error(`Failed to install packages: ${installResult.error.message}`);
205776
205828
  }
205829
+ logger.info("Installation completed.");
205777
205830
  }
205778
205831
  async getYarnLockObj(filePath) {
205779
205832
  const fileString = await readFile13(filePath, "utf8");
@@ -205875,7 +205928,7 @@ var YarnFixingManager = class extends NpmEcosystemFixingManager {
205875
205928
 
205876
205929
  // ../fixing-management/src/fixing-management/npm/npm-ecosystem-socket-fixing-manager.ts
205877
205930
  import { dirname as dirname5, join as join8, relative as relative5 } from "path";
205878
- import { existsSync as existsSync10 } from "fs";
205931
+ import { existsSync as existsSync11 } from "fs";
205879
205932
  var NpmSocketUpgradeManager = class {
205880
205933
  constructor(rootDir) {
205881
205934
  this.rootDir = rootDir;
@@ -205909,7 +205962,13 @@ var NpmSocketUpgradeManager = class {
205909
205962
  workspaceToSubproject.set(join8(subprojectDir, workspace), subprojectDir);
205910
205963
  }
205911
205964
  }
205912
- const packageJsonFiles = artifact.manifestFiles?.filter((a4) => a4.file.endsWith("package.json"));
205965
+ const packageJsonFiles = artifact.manifestFiles?.filter((a4) => a4.file.endsWith("package.json")) ?? [];
205966
+ for (const lockFile of lockFiles ?? []) {
205967
+ const correspondingPackageJsonFile = join8(dirname5(lockFile.file), "package.json");
205968
+ if (!packageJsonFiles.some((p3) => p3.file === correspondingPackageJsonFile) && existsSync11(correspondingPackageJsonFile)) {
205969
+ packageJsonFiles.push({ file: correspondingPackageJsonFile });
205970
+ }
205971
+ }
205913
205972
  for (const packageJsonFile of packageJsonFiles ?? []) {
205914
205973
  const packageJsonDir = dirname5(packageJsonFile.file);
205915
205974
  const subprojectDir = workspaceToSubproject.get(packageJsonDir) ?? packageJsonDir;
@@ -205961,13 +206020,14 @@ function getFixingManagerFromPackageManager(packageManager, rootDir, subprojectP
205961
206020
  }
205962
206021
  }
205963
206022
  function getPackageMangerForDirectory(directory) {
205964
- if (existsSync10(join8(directory, "pnpm-lock.yaml")) || existsSync10(join8(directory, "pnpm-lock.yml"))) {
206023
+ if (existsSync11(join8(directory, "pnpm-lock.yaml")) || existsSync11(join8(directory, "pnpm-lock.yml"))) {
205965
206024
  return "PNPM";
205966
- } else if (existsSync10(join8(directory, "yarn.lock"))) {
206025
+ } else if (existsSync11(join8(directory, "yarn.lock"))) {
205967
206026
  return "YARN";
205968
- } else {
206027
+ } else if (existsSync11(join8(directory, "package-lock.json"))) {
205969
206028
  return "NPM";
205970
206029
  }
206030
+ throw new Error("Upgrading packages is currently only supported for NPM projects using a lock file.");
205971
206031
  }
205972
206032
 
205973
206033
  // ../fixing-management/src/fixing-management/npm/rush-fixing-manager.ts
@@ -206329,7 +206389,7 @@ async function applySocketUpgrades(ecosystem, rootDir, upgrades, artifacts) {
206329
206389
 
206330
206390
  // dist/cli-apply-fix.js
206331
206391
  var import_lodash12 = __toESM(require_lodash(), 1);
206332
- import { existsSync as existsSync15 } from "fs";
206392
+ import { existsSync as existsSync16 } from "fs";
206333
206393
 
206334
206394
  // ../other-modules-communicator/src/other-modules-communicator.ts
206335
206395
  import { execFileSync } from "child_process";
@@ -206346,7 +206406,7 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
206346
206406
  // ../utils/dist/file-utils.js
206347
206407
  var import_lodash5 = __toESM(require_lodash(), 1);
206348
206408
  var import_micromatch = __toESM(require_micromatch(), 1);
206349
- import { existsSync as existsSync11 } from "fs";
206409
+ import { existsSync as existsSync12 } from "fs";
206350
206410
  import { access as access2, cp, readdir as readdir3, stat as stat2 } from "fs/promises";
206351
206411
  import { basename as basename4, join as join11, relative as relative6, resolve as resolve13 } from "path";
206352
206412
  var { uniq } = import_lodash5.default;
@@ -207076,7 +207136,7 @@ async function detectVariantMaven(projectDir) {
207076
207136
  }
207077
207137
 
207078
207138
  // ../docker-management/src/maven/gradle-version-detector.ts
207079
- import { existsSync as existsSync12 } from "fs";
207139
+ import { existsSync as existsSync13 } from "fs";
207080
207140
  import { join as join13 } from "path";
207081
207141
  import { readFile as readFile15 } from "fs/promises";
207082
207142
  async function detectVariantGradle(projectDir) {
@@ -207084,7 +207144,7 @@ async function detectVariantGradle(projectDir) {
207084
207144
  }
207085
207145
  async function detect(projectDir) {
207086
207146
  const gradleWrapperPropertiesPath = join13(projectDir, "gradle", "wrapper", "gradle-wrapper.properties");
207087
- const gradleWrapperProperties = existsSync12(gradleWrapperPropertiesPath) ? (await readFile15(gradleWrapperPropertiesPath, "utf-8")).split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("#")).filter((line) => line) : void 0;
207147
+ const gradleWrapperProperties = existsSync13(gradleWrapperPropertiesPath) ? (await readFile15(gradleWrapperPropertiesPath, "utf-8")).split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("#")).filter((line) => line) : void 0;
207088
207148
  if (!gradleWrapperProperties) return void 0;
207089
207149
  const distributionUrlRegex = /.*gradle-(\d+(\.\d+(\.\d+)?)?)/;
207090
207150
  for (const prop2 of gradleWrapperProperties) {
@@ -207098,7 +207158,7 @@ async function detect(projectDir) {
207098
207158
  }
207099
207159
 
207100
207160
  // ../docker-management/src/maven/sbt-version-detector.ts
207101
- import { existsSync as existsSync13 } from "fs";
207161
+ import { existsSync as existsSync14 } from "fs";
207102
207162
  import { join as join14 } from "path";
207103
207163
  import { readFile as readFile16 } from "fs/promises";
207104
207164
  async function detectVariantSbt(projectDir) {
@@ -207106,7 +207166,7 @@ async function detectVariantSbt(projectDir) {
207106
207166
  }
207107
207167
  async function detect2(projectDir) {
207108
207168
  const sbtBuildPropertiesPath = join14(projectDir, "project", "build.properties");
207109
- const sbtBuildProperties = existsSync13(sbtBuildPropertiesPath) ? (await readFile16(sbtBuildPropertiesPath, "utf-8")).split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("#")).filter((line) => line) : void 0;
207169
+ const sbtBuildProperties = existsSync14(sbtBuildPropertiesPath) ? (await readFile16(sbtBuildPropertiesPath, "utf-8")).split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("#")).filter((line) => line) : void 0;
207110
207170
  if (!sbtBuildProperties) return void 0;
207111
207171
  for (const prop2 of sbtBuildProperties) {
207112
207172
  const [key, value] = prop2.split("=");
@@ -207227,7 +207287,7 @@ import { join as join17, posix as posix2, relative as relative8, sep as sep3 } f
207227
207287
  // ../utils/src/file-utils.ts
207228
207288
  var import_lodash8 = __toESM(require_lodash(), 1);
207229
207289
  var import_micromatch2 = __toESM(require_micromatch(), 1);
207230
- import { existsSync as existsSync14 } from "fs";
207290
+ import { existsSync as existsSync15 } from "fs";
207231
207291
  import { access as access3, cp as cp2, readdir as readdir4, stat as stat3 } from "fs/promises";
207232
207292
  import { basename as basename5, join as join15, relative as relative7, resolve as resolve16 } from "path";
207233
207293
  var { uniq: uniq2 } = import_lodash8.default;
@@ -208029,6 +208089,28 @@ async function registerAnalysisMetadataCoana(subprojectPath, workspacePath, ecos
208029
208089
  handleError(e, "Unable to create analysis metadata");
208030
208090
  }
208031
208091
  }
208092
+ async function getBucketsForLastReport(subprojectPath, workspacePath, ecosystem, newReportId, apiKey) {
208093
+ if (!newReportId || apiKey.type === "missing") return;
208094
+ try {
208095
+ return (await axios_default.get(coanaAPIUrls.GET_LATEST_BUCKETS, {
208096
+ headers: {
208097
+ "Content-Type": "application/json",
208098
+ apiKey: apiKey.value
208099
+ },
208100
+ params: { newReportId, subprojectPath, workspacePath, ecosystem }
208101
+ })).data;
208102
+ } catch (e) {
208103
+ if (e.response?.data?.message === "No successful report found") return;
208104
+ sendWarningToDashboard(
208105
+ "Unable to get latest buckets",
208106
+ { subprojectPath, workspacePath, newReportId },
208107
+ void 0,
208108
+ newReportId,
208109
+ apiKey
208110
+ );
208111
+ logger.warn("Unable to get latest buckets:", e.message);
208112
+ }
208113
+ }
208032
208114
  async function registerCLIProgressCoana(cliProgressEvent, isStartEvent, reportId, apiKey) {
208033
208115
  if (!reportId || apiKey.type === "missing") return;
208034
208116
  try {
@@ -208148,7 +208230,8 @@ function getCoanaAPI() {
208148
208230
  registerSubprojectsCoana,
208149
208231
  registerAnalysisMetadataCoana,
208150
208232
  registerCLIProgressCoana,
208151
- sendErrorReportToCoanaDashboard
208233
+ sendErrorReportToCoanaDashboard,
208234
+ getBucketsForLastReport
208152
208235
  };
208153
208236
  }
208154
208237
 
@@ -208344,7 +208427,7 @@ async function verifyFixes(fixes, otherModulesCommunicator, rootPath) {
208344
208427
  if (pathsForEachFixIdData.length !== new Set(pathsForEachFixIdData).size) {
208345
208428
  throw new Error("Multiple fix IDs found for the same subproject, workspace and ecosystem");
208346
208429
  }
208347
- const subprojectsNotFound = uniq3(fixes.filter(({ vulnerabilityInstance: v }) => !existsSync15(resolve19(rootPath, v.subprojectPath))).map(({ vulnerabilityInstance: v }) => `${v.subprojectPath}:${v.ecosystem}`));
208430
+ const subprojectsNotFound = uniq3(fixes.filter(({ vulnerabilityInstance: v }) => !existsSync16(resolve19(rootPath, v.subprojectPath))).map(({ vulnerabilityInstance: v }) => `${v.subprojectPath}:${v.ecosystem}`));
208348
208431
  if (subprojectsNotFound.length > 0) {
208349
208432
  throw new Error(`Cannot find the following subprojects: ${subprojectsNotFound.join(", ")}`);
208350
208433
  }
@@ -209150,12 +209233,12 @@ import { readdir as readdir6 } from "fs/promises";
209150
209233
  import { join as join20, relative as relative9, resolve as resolve22 } from "path";
209151
209234
 
209152
209235
  // ../project-management/src/project-management/ecosystem-management/ecosystem-specs.ts
209153
- import { existsSync as existsSync17 } from "fs";
209236
+ import { existsSync as existsSync18 } from "fs";
209154
209237
  import { readdir as readdir5, readFile as readFile20 } from "fs/promises";
209155
209238
  import { join as join19, sep as sep4 } from "path";
209156
209239
 
209157
209240
  // ../utils/src/pip-utils.ts
209158
- import { existsSync as existsSync16 } from "fs";
209241
+ import { existsSync as existsSync17 } from "fs";
209159
209242
  import { readFile as readFile19 } from "fs/promises";
209160
209243
  import { resolve as resolve21 } from "path";
209161
209244
  import util4 from "util";
@@ -209252,7 +209335,7 @@ function getEcosystemSpecs(ecosystems) {
209252
209335
  }
209253
209336
  function packageManagerIfPackageJSONExistsAndValid(packageManager) {
209254
209337
  return async (projectDir) => {
209255
- if (!existsSync17(join19(projectDir, "package.json"))) return void 0;
209338
+ if (!existsSync18(join19(projectDir, "package.json"))) return void 0;
209256
209339
  const packageJSONPath = join19(projectDir, "package.json");
209257
209340
  try {
209258
209341
  JSON.parse(await readFile20(packageJSONPath, "utf-8"));
@@ -209715,6 +209798,19 @@ var DashboardAPI = class {
209715
209798
  );
209716
209799
  }
209717
209800
  }
209801
+ async getBucketsForLastReport(subprojectPath, workspacePath, ecosystem, reportId, apiKey) {
209802
+ if (this.socketMode) {
209803
+ return await this.socketAPI.getLatestBucketsSocket(subprojectPath, workspacePath);
209804
+ } else {
209805
+ return await this.coanaAPI.getBucketsForLastReport(
209806
+ subprojectPath,
209807
+ workspacePath,
209808
+ ecosystem,
209809
+ reportId,
209810
+ apiKey
209811
+ );
209812
+ }
209813
+ }
209718
209814
  };
209719
209815
 
209720
209816
  // ../utils/src/promise-queue.ts
@@ -209927,16 +210023,16 @@ function isVulnChainWithParentsMap(v) {
209927
210023
  var DEFAULT_REPORT_FILENAME_BASE = "coana-report";
209928
210024
 
209929
210025
  // dist/internal/exclude-dirs-from-configuration-files.js
209930
- import { existsSync as existsSync18 } from "fs";
210026
+ import { existsSync as existsSync19 } from "fs";
209931
210027
  import { readFile as readFile21 } from "fs/promises";
209932
210028
  import { basename as basename6, resolve as resolve24 } from "path";
209933
210029
  var import_yaml2 = __toESM(require_dist11(), 1);
209934
210030
  async function inferExcludeDirsFromConfigurationFiles(rootWorkingDir) {
209935
210031
  const socketYmlConfigFile = resolve24(rootWorkingDir, "socket.yml");
209936
- if (existsSync18(socketYmlConfigFile))
210032
+ if (existsSync19(socketYmlConfigFile))
209937
210033
  return inferExcludeDirsFromSocketConfig(socketYmlConfigFile);
209938
210034
  const socketYamlConfigFile = resolve24(rootWorkingDir, "socket.yaml");
209939
- if (existsSync18(socketYamlConfigFile))
210035
+ if (existsSync19(socketYamlConfigFile))
209940
210036
  return inferExcludeDirsFromSocketConfig(socketYamlConfigFile);
209941
210037
  return void 0;
209942
210038
  }
@@ -224025,7 +224121,7 @@ var { root: root2 } = static_exports;
224025
224121
 
224026
224122
  // ../utils/src/maven-utils.ts
224027
224123
  var import_lodash14 = __toESM(require_lodash(), 1);
224028
- import { existsSync as existsSync19, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
224124
+ import { existsSync as existsSync20, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
224029
224125
  import { join as join21 } from "path";
224030
224126
  var { memoize: memoize3 } = import_lodash14.default;
224031
224127
  var memoizedParseShellArgs = memoize3(parseShellArgs);
@@ -225397,7 +225493,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
225397
225493
  }
225398
225494
 
225399
225495
  // dist/version.js
225400
- var version2 = "14.11.14";
225496
+ var version2 = "14.11.16";
225401
225497
 
225402
225498
  // dist/cli-core.js
225403
225499
  var { mapValues, omit, partition, pick } = import_lodash15.default;
@@ -226200,43 +226296,44 @@ ${vulnerabilityFixes.map((fix) => ` ${fix.dependencyName} from ${fix.currentVers
226200
226296
 
226201
226297
  // dist/cli-compute-fixes-and-upgrade-purls.js
226202
226298
  async function computeFixesAndUpgradePurls(path2, options) {
226203
- const { artifacts, vulnerableArtifactIdsPerVulnerability } = await computeInputForComputingFixes(path2, options);
226204
- if (vulnerableArtifactIdsPerVulnerability.size === 0) {
226299
+ const { artifacts, ghsaToVulnerableArtifactIds } = await computeInputForComputingFixes(path2, options);
226300
+ if (Object.keys(ghsaToVulnerableArtifactIds).length === 0) {
226205
226301
  logger.info("No vulnerabilities to compute fixes for");
226206
226302
  return;
226207
226303
  }
226208
226304
  if (options.applyFixesTo.length === 0) {
226209
- logger.info("Vulnerabilities found:", Array.from(vulnerableArtifactIdsPerVulnerability.keys()).join(", "));
226305
+ logger.info("Vulnerabilities found:", Object.keys(ghsaToVulnerableArtifactIds).join(", "));
226210
226306
  logger.info("Run again with --apply-fixes-to GHSA_IDS to fix those vulnerabilities by computing packages to upgrade and apply them");
226211
226307
  return;
226212
226308
  }
226213
- const vulnerableArtifactIdsForGhsas = options.applyFixesTo.includes("all") ? Array.from(vulnerableArtifactIdsPerVulnerability.values()).flatMap((ids) => Array.from(ids)) : options.applyFixesTo.flatMap((ghsa) => [...vulnerableArtifactIdsPerVulnerability.get(ghsa)?.values() ?? []]);
226214
- const computedFix = await useSocketComputeFixEndpoint(artifacts, vulnerableArtifactIdsForGhsas);
226309
+ const ghsaToVulnerableArtifactIdsToApply = options.applyFixesTo.includes("all") ? ghsaToVulnerableArtifactIds : Object.fromEntries(Object.entries(ghsaToVulnerableArtifactIds).filter(([ghsa]) => options.applyFixesTo.includes(ghsa)));
226310
+ const computedFix = await useSocketComputeFixEndpoint(artifacts, ghsaToVulnerableArtifactIdsToApply);
226215
226311
  if (computedFix.type !== "success") {
226216
226312
  throw new Error(`No fix found for the given vulnerabilities`);
226217
226313
  }
226218
- if (computedFix.failedArtifacts) {
226219
- const ghsasFailedToFix = options.applyFixesTo.filter((ghsa) => {
226220
- const artifactIds = vulnerableArtifactIdsPerVulnerability.get(ghsa);
226221
- if (!artifactIds)
226222
- return false;
226223
- return Array.from(artifactIds).some((vuln) => computedFix.failedArtifacts?.includes(vuln));
226224
- });
226314
+ const ghsasFailedToFix = options.applyFixesTo.filter((ghsa) => {
226315
+ const artifactIds = ghsaToVulnerableArtifactIdsToApply[ghsa];
226316
+ if (!artifactIds)
226317
+ return false;
226318
+ return artifactIds.some((artifactId) => computedFix.ghsaToResult[ghsa].failedArtifacts?.includes(artifactId));
226319
+ });
226320
+ if (ghsasFailedToFix.length > 0) {
226225
226321
  logger.info("Failed to compute fixes for the following vulnerabilities:");
226226
- for (const ghsa of ghsasFailedToFix) {
226227
- logger.info(` - ${ghsa} (${Array.from(vulnerableArtifactIdsPerVulnerability.get(ghsa)).map((id) => simplePurl(artifacts[id].type, artifacts[id].namespace ?? null, artifacts[id].name ?? "", artifacts[id].version ?? null)).join(", ")})`);
226228
- }
226229
226322
  }
226323
+ for (const ghsa of ghsasFailedToFix) {
226324
+ logger.info(` - ${ghsa} (${ghsaToVulnerableArtifactIdsToApply[ghsa].map((id) => simplePurl(artifacts[id].type, artifacts[id].namespace ?? null, artifacts[id].name ?? "", artifacts[id].version ?? null)).join(", ")})`);
226325
+ }
226326
+ const combinedFixes = Object.values(computedFix.ghsaToResult).filter((result) => result.failedArtifacts === void 0 || result.failedArtifacts.length === 0).flatMap((result) => result.fixes);
226230
226327
  if (options.dryRun) {
226231
226328
  logger.info("Fixes found:");
226232
- for (const fix of computedFix.fixes) {
226329
+ for (const fix of combinedFixes) {
226233
226330
  logger.info(` - ${fix.purl} -> ${fix.fixedVersion}`);
226234
226331
  }
226235
226332
  logger.info("Run again without --dry-run to apply the fixes");
226236
226333
  return;
226237
226334
  }
226238
226335
  try {
226239
- await upgradePurl(path2, computedFix.fixes.map((fix) => ({ purl: fix.purl, upgradeVersion: fix.fixedVersion })), {
226336
+ await upgradePurl(path2, combinedFixes.map((fix) => ({ purl: fix.purl, upgradeVersion: fix.fixedVersion })), {
226240
226337
  debug: options.debug,
226241
226338
  silent: options.silent,
226242
226339
  runWithoutDocker: options.runWithoutDocker,
@@ -226252,13 +226349,13 @@ async function computeFixesAndUpgradePurls(path2, options) {
226252
226349
  async function computeInputForComputingFixes(path2, options) {
226253
226350
  if (options.manifestsTarHash) {
226254
226351
  const { artifacts: artifacts2 } = await fetchArtifactsFromSocket(path2, options.manifestsTarHash);
226255
- const vulnerableArtifactIdsPerVulnerability2 = /* @__PURE__ */ new Map();
226352
+ const ghsaToVulnerableArtifactIds2 = {};
226256
226353
  for (const [index2, artifact] of artifacts2.entries()) {
226257
- if (artifact.vulnerabilities) {
226258
- for (const vulnerability of artifact.vulnerabilities) {
226259
- if (!vulnerableArtifactIdsPerVulnerability2.has(vulnerability.ghsaId))
226260
- vulnerableArtifactIdsPerVulnerability2.set(vulnerability.ghsaId, /* @__PURE__ */ new Set());
226261
- vulnerableArtifactIdsPerVulnerability2.get(vulnerability.ghsaId).add(index2);
226354
+ if (!artifact.vulnerabilities)
226355
+ continue;
226356
+ for (const vulnerability of artifact.vulnerabilities) {
226357
+ if (!(ghsaToVulnerableArtifactIds2[vulnerability.ghsaId] ??= []).includes(index2)) {
226358
+ ghsaToVulnerableArtifactIds2[vulnerability.ghsaId].push(index2);
226262
226359
  }
226263
226360
  }
226264
226361
  }
@@ -226269,7 +226366,7 @@ async function computeInputForComputingFixes(path2, options) {
226269
226366
  namespace: artifact.namespace ?? void 0,
226270
226367
  adj: artifact.dependencies?.map((dep) => artifacts2.findIndex((a4) => a4.id === dep)) ?? []
226271
226368
  }));
226272
- return { artifacts: sbomTaskArtifacts, vulnerableArtifactIdsPerVulnerability: vulnerableArtifactIdsPerVulnerability2 };
226369
+ return { artifacts: sbomTaskArtifacts, ghsaToVulnerableArtifactIds: ghsaToVulnerableArtifactIds2 };
226273
226370
  }
226274
226371
  const otherModulesCommunicator = new OtherModulesCommunicator(path2, options, {
226275
226372
  type: "missing"
@@ -226283,21 +226380,24 @@ async function computeInputForComputingFixes(path2, options) {
226283
226380
  const cliCore = new CliCore(path2, { ...defaultCliOptions, socketMode: "true" });
226284
226381
  const results = await asyncMap(supportedSubprojects, async (subproject) => cliCore.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subproject));
226285
226382
  const { artifacts, purlToIndex } = computeSBOMTaskArtifacts(results.flatMap((r2) => Object.values(r2.projectInfo).map((info) => info.dataForAnalysis.data.dependencyTree)));
226286
- const vulnerableArtifactIdsPerVulnerability = computeVulnerableArtifactIdsPerVulnerability(results.flatMap((r2) => Object.values(r2.workspaceToVulnerabilities).flat()), purlToIndex);
226287
- return { artifacts, vulnerableArtifactIdsPerVulnerability };
226383
+ const ghsaToVulnerableArtifactIds = computeVulnerableArtifactIdsPerVulnerability(results.flatMap((r2) => Object.values(r2.workspaceToVulnerabilities).flat()), purlToIndex);
226384
+ return { artifacts, ghsaToVulnerableArtifactIds };
226288
226385
  }
226289
226386
  function computeVulnerableArtifactIdsPerVulnerability(vulnerabilities, purlToIndex) {
226290
- const vulnerableArtifactIdsPerVulnerability = /* @__PURE__ */ new Map();
226387
+ const vulnerableArtifactIdsPerVulnerability = {};
226291
226388
  for (const vulnerability of vulnerabilities) {
226292
- if (!vulnerableArtifactIdsPerVulnerability.has(vulnerability.url)) {
226293
- vulnerableArtifactIdsPerVulnerability.set(vulnerability.url, /* @__PURE__ */ new Set());
226389
+ if (!vulnerableArtifactIdsPerVulnerability[vulnerability.url]) {
226390
+ vulnerableArtifactIdsPerVulnerability[vulnerability.url] = [];
226294
226391
  }
226295
226392
  if (!vulnerability.purl)
226296
226393
  throw new Error(`Vulnerability ${vulnerability.url} has no purl`);
226297
226394
  if (!purlToIndex.has(vulnerability.purl)) {
226298
226395
  throw new Error(`Vulnerability ${vulnerability.url} has no purl in sbomTaskArtifacts`);
226299
226396
  }
226300
- vulnerableArtifactIdsPerVulnerability.get(vulnerability.url).add(purlToIndex.get(vulnerability.purl));
226397
+ const index2 = purlToIndex.get(vulnerability.purl);
226398
+ if (!vulnerableArtifactIdsPerVulnerability[vulnerability.url].includes(index2)) {
226399
+ vulnerableArtifactIdsPerVulnerability[vulnerability.url].push(index2);
226400
+ }
226301
226401
  }
226302
226402
  return vulnerableArtifactIdsPerVulnerability;
226303
226403
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.11.14",
3
+ "version": "14.11.16",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -73178,7 +73178,8 @@ function getCoanaAPI() {
73178
73178
  registerSubprojectsCoana,
73179
73179
  registerAnalysisMetadataCoana,
73180
73180
  registerCLIProgressCoana,
73181
- sendErrorReportToCoanaDashboard
73181
+ sendErrorReportToCoanaDashboard,
73182
+ getBucketsForLastReport
73182
73183
  };
73183
73184
  }
73184
73185
 
@@ -73352,13 +73353,49 @@ async function registerAnalysisMetadataSocket(subprojectPath, workspacePath, eco
73352
73353
  handleError(error, "Error registering analysis metadata", false);
73353
73354
  }
73354
73355
  }
73356
+ async function getLatestBucketsSocket(subprojectPath, workspacePath) {
73357
+ try {
73358
+ const url2 = getSocketApiUrl("tier1-reachability-scan/latest-buckets");
73359
+ const params = {
73360
+ workspacePath,
73361
+ subprojectPath,
73362
+ repoName: process.env.SOCKET_REPO_NAME,
73363
+ branchName: process.env.SOCKET_BRANCH_NAME
73364
+ };
73365
+ const response = await axios2.get(url2, {
73366
+ headers: getAuthHeaders(),
73367
+ params
73368
+ });
73369
+ const responseData = response.data;
73370
+ if (responseData.type !== "success") {
73371
+ throw new Error(response.data.reason);
73372
+ }
73373
+ return {
73374
+ cliVersion: responseData.value.coana_cli_version,
73375
+ buckets: responseData.value.buckets.map((b) => ({
73376
+ vulnUrls: b.ghsas,
73377
+ heuristicName: b.heuristicName
73378
+ }))
73379
+ };
73380
+ } catch (error) {
73381
+ if (error?.response?.data?.message === "No successful report found") {
73382
+ return void 0;
73383
+ }
73384
+ logger.warn(
73385
+ "Unable to retrieve cached analysis configuration. Will continue with default configuration.",
73386
+ error?.message
73387
+ );
73388
+ return void 0;
73389
+ }
73390
+ }
73355
73391
  function getSocketAPI() {
73356
73392
  return {
73357
73393
  createSocketTier1Scan,
73358
73394
  sendErrorReportToSocketDashboard,
73359
73395
  registerSubprojectsSocket,
73360
73396
  registerCLIProgressSocket,
73361
- registerAnalysisMetadataSocket
73397
+ registerAnalysisMetadataSocket,
73398
+ getLatestBucketsSocket
73362
73399
  };
73363
73400
  }
73364
73401
 
@@ -73454,6 +73491,19 @@ var DashboardAPI = class {
73454
73491
  );
73455
73492
  }
73456
73493
  }
73494
+ async getBucketsForLastReport(subprojectPath, workspacePath, ecosystem, reportId, apiKey3) {
73495
+ if (this.socketMode) {
73496
+ return await this.socketAPI.getLatestBucketsSocket(subprojectPath, workspacePath);
73497
+ } else {
73498
+ return await this.coanaAPI.getBucketsForLastReport(
73499
+ subprojectPath,
73500
+ workspacePath,
73501
+ ecosystem,
73502
+ reportId,
73503
+ apiKey3
73504
+ );
73505
+ }
73506
+ }
73457
73507
  };
73458
73508
 
73459
73509
  // dist/analyzers/go-analyzer.js
@@ -96850,6 +96900,7 @@ function assertVulnChainDetails(vs) {
96850
96900
  assert8(vs.every((v) => v.vulnChainDetails));
96851
96901
  }
96852
96902
  var apiKey = COANA_API_KEY ? { type: "present", value: COANA_API_KEY } : { type: "missing" };
96903
+ var dashboardAPI = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
96853
96904
  async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecomputeForTimeoutsAndAborts, codeAwareScanner, analysisMetadataCollector, statusUpdater) {
96854
96905
  logger.debug("Starting analyzeWithHeuristics");
96855
96906
  assertVulnChainDetails(vulns);
@@ -96937,9 +96988,9 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
96937
96988
  }
96938
96989
  }
96939
96990
  async function getBucketsBasedOnPreviousResults() {
96940
- if (!COANA_REPORT_ID || apiKey.type === "missing")
96991
+ if (process.env.SOCKET_MODE !== "true" && (!COANA_REPORT_ID || apiKey.type === "missing"))
96941
96992
  return void 0;
96942
- const bucketsFromLastAnalysisAndCliVersion = await getBucketsForLastReport(relative5(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, vulnerabilities[0].ecosystem ?? "NPM", COANA_REPORT_ID, apiKey);
96993
+ const bucketsFromLastAnalysisAndCliVersion = await dashboardAPI.getBucketsForLastReport(relative5(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, vulnerabilities[0].ecosystem ?? "NPM", COANA_REPORT_ID, apiKey);
96943
96994
  if (!bucketsFromLastAnalysisAndCliVersion)
96944
96995
  return void 0;
96945
96996
  const { cliVersion, buckets: bucketsFromLastAnalysis } = bucketsFromLastAnalysisAndCliVersion;
@@ -97411,7 +97462,7 @@ var ecosystemAnalyzer = {
97411
97462
  RUST: RustAnalyzer
97412
97463
  };
97413
97464
  var apiKey2 = COANA_API_KEY ? { type: "present", value: COANA_API_KEY } : { type: "missing" };
97414
- var dashboardAPI = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
97465
+ var dashboardAPI2 = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
97415
97466
  async function runReachabilityAnalysis(state) {
97416
97467
  const projectDir = resolve16(state.subprojectDir, state.workspacePath);
97417
97468
  const ecosystem = state.workspaceData.data.type;
@@ -97425,7 +97476,7 @@ async function runReachabilityAnalysis(state) {
97425
97476
  }
97426
97477
  const [vulnerabilitiesWithPrecomputedResults, vulnerabilitiesWithoutPrecomputedResults] = partition3(state.vulnerabilities, (v) => "results" in v);
97427
97478
  const augmentedVulnerabilities = await runWholeProgramCodeAwareVulnerabilityScanner(analyzer, vulnerabilitiesWithoutPrecomputedResults, async (amd) => {
97428
- await dashboardAPI.registerAnalysisMetadata(relative6(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, state.workspaceData.data.type, amd, COANA_REPORT_ID, apiKey2);
97479
+ await dashboardAPI2.registerAnalysisMetadata(relative6(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, state.workspaceData.data.type, amd, COANA_REPORT_ID, apiKey2);
97429
97480
  });
97430
97481
  return [...vulnerabilitiesWithPrecomputedResults, ...augmentedVulnerabilities];
97431
97482
  }