@coana-tech/cli 14.12.16 → 14.12.19

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
@@ -206082,7 +206082,7 @@ var NpmSocketUpgradeManager = class {
206082
206082
  this.rootDir,
206083
206083
  subprojectDir
206084
206084
  );
206085
- this.applySecurityFixesForSocketArtifacts(
206085
+ await this.applySecurityFixesForSocketArtifacts(
206086
206086
  subprojectDir,
206087
206087
  fixingManager,
206088
206088
  artifacts,
@@ -224639,7 +224639,7 @@ var CoanaSupportedVulnerabilitiesDBInterface = class _CoanaSupportedVulnerabilit
224639
224639
  async upsertVulnerabilityPattern(ghsa, ecosystem, updateFields) {
224640
224640
  const advisory = ghsa;
224641
224641
  const _id = `${ghsa}-${ecosystem}`;
224642
- return this.vulnerabilitiesSupportedCollection.updateOne(
224642
+ return await this.vulnerabilitiesSupportedCollection.updateOne(
224643
224643
  { _id },
224644
224644
  {
224645
224645
  $set: {
@@ -225672,7 +225672,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
225672
225672
  }
225673
225673
 
225674
225674
  // dist/version.js
225675
- var version2 = "14.12.16";
225675
+ var version2 = "14.12.19";
225676
225676
 
225677
225677
  // dist/cli-core.js
225678
225678
  var { mapValues, omit, partition, pick } = import_lodash15.default;
@@ -226517,7 +226517,7 @@ async function computeFixesAndUpgradePurls(path2, options, logFile) {
226517
226517
  if (computedFix.type !== "success") {
226518
226518
  throw new Error(`No fix found for the given vulnerabilities`);
226519
226519
  }
226520
- const ghsasFailedToFix = options.applyFixesTo.filter((ghsa) => {
226520
+ const ghsasFailedToFix = Object.keys(ghsaToVulnerableArtifactIdsToApply).filter((ghsa) => {
226521
226521
  const artifactIds = ghsaToVulnerableArtifactIdsToApply[ghsa];
226522
226522
  if (!artifactIds)
226523
226523
  return false;
@@ -226550,7 +226550,7 @@ async function computeFixesAndUpgradePurls(path2, options, logFile) {
226550
226550
  concurrency: "1",
226551
226551
  globPattern: options.globPattern,
226552
226552
  rangeStyle: options.rangeStyle
226553
- }, autofixRunId) ?? "fixed-all";
226553
+ }, void 0, autofixRunId) ?? "fixed-all";
226554
226554
  if (autofixRunId) {
226555
226555
  await getSocketAPI().finalizeAutofixRun(autofixRunId, ghsasFailedToFix.length === 0 && applyFixesStatus === "fixed-all" ? "fixed-all" : ghsasFailedToFix.length === Object.keys(ghsaToVulnerableArtifactIdsToApply).length || applyFixesStatus === "fixed-none" ? "fixed-none" : "fixed-some");
226556
226556
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.12.16",
3
+ "version": "14.12.19",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -73725,12 +73725,6 @@ async function asyncForEach(array, fn, concurrency = 1) {
73725
73725
  }
73726
73726
  await Promise.all(Array.from({ length: concurrency }, async () => worker()));
73727
73727
  }
73728
- async function applySeries(arr, fn) {
73729
- let i2 = 0;
73730
- for (const item of arr) {
73731
- await fn(item, i2++);
73732
- }
73733
- }
73734
73728
  async function asyncFilter(arr, predicate, concurrency = 1) {
73735
73729
  const results = await asyncMap(arr, predicate, concurrency);
73736
73730
  return arr.filter((_v, index2) => results[index2]);
@@ -74383,20 +74377,6 @@ async function withTmpDirectory(prefix, fn, deleteTmpDir = true) {
74383
74377
 
74384
74378
  // ../web-compat-utils/src/vuln-chain-detail-utils.ts
74385
74379
  var ROOT_NODE_STR = "";
74386
- function computeParentsMap(d) {
74387
- const parentsMap = /* @__PURE__ */ new Map();
74388
- const addToMap = (children2, id) => {
74389
- children2?.forEach((dep) => {
74390
- if (!parentsMap.has(dep)) parentsMap.set(dep, []);
74391
- parentsMap.get(dep).push(id);
74392
- });
74393
- };
74394
- for (const [id, node] of Object.entries(d.transitiveDependencies)) {
74395
- addToMap(node.children, id);
74396
- }
74397
- addToMap(d.children, ROOT_NODE_STR);
74398
- return parentsMap;
74399
- }
74400
74380
 
74401
74381
  // dist/whole-program-code-aware-vulnerability-scanner/code-aware-vulnerability-scanner.js
74402
74382
  var import_lodash13 = __toESM(require_lodash(), 1);
@@ -88577,130 +88557,6 @@ async function convertSocketArtifacts2(artifacts, tmpDir) {
88577
88557
  return deps;
88578
88558
  }
88579
88559
 
88580
- // dist/whole-program-code-aware-vulnerability-scanner/js/jelly-runner.js
88581
- var import_lodash9 = __toESM(require_lodash(), 1);
88582
- import { readFile as readFile7, rm as rm2, writeFile as writeFile5 } from "fs/promises";
88583
- import { relative as relative4, resolve as resolve6 } from "path";
88584
- var { map: map2, uniq: uniq4 } = import_lodash9.default;
88585
- var PRINT_JELLY_COMMAND = false;
88586
- async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, vulnerabilities, experiment) {
88587
- const tmpFolder = await createTmpDirectory("jelly-analysis");
88588
- try {
88589
- const filesToAnalyze = reachabilityAnalysisOptions.entryPoints ? reachabilityAnalysisOptions.entryPoints : [projectRoot];
88590
- const jellyExecutable = resolve6(COANA_REPOS_PATH(), "jelly-private", "dist", "bundle", "jelly.js");
88591
- const vulnerabilitiesInJellyFormat = vulnerabilities.map((v) => ({
88592
- osv: v,
88593
- patterns: v.vulnerabilityAccessPaths.map((p) => experiment === "AUGMENT_IMPORT_PATHS_EXPERIMENT" ? p.replace(">", "/**>") : p)
88594
- // Repalce > with /**> to ensure Jelly also matches call <PKG/dist/index.js>.foo for pattern <PKG>.foo
88595
- }));
88596
- const vulnerabilitiesFile = resolve6(tmpFolder, "vulnerabilities.json");
88597
- const diagnosticsFile = resolve6(tmpFolder, "diagnostics.json");
88598
- const matchesFile = resolve6(tmpFolder, "matches.json");
88599
- const callStackFile = resolve6(tmpFolder, "call-stacks.json");
88600
- const logFile = reachabilityAnalysisOptions.analysisLogFile ?? (reachabilityAnalysisOptions.printLogFile && resolve6(projectRoot, "js-analysis.log"));
88601
- await writeFile5(vulnerabilitiesFile, JSON.stringify(vulnerabilitiesInJellyFormat));
88602
- let excludeEntries;
88603
- if (reachabilityAnalysisOptions.excludeDirs?.length) {
88604
- const excludeDirsRelativeToProjectRoot = reachabilityAnalysisOptions.excludeDirs.map((d) => relative4(projectRoot, resolve6(mainProjectRoot, d)));
88605
- const excludeDirsRelativeToProjectRootWithWildcards = excludeDirsRelativeToProjectRoot.map((d) => `${d}/**`);
88606
- excludeEntries = [...excludeDirsRelativeToProjectRoot, ...excludeDirsRelativeToProjectRootWithWildcards];
88607
- }
88608
- const jellyCmd = [
88609
- "node",
88610
- `--max-old-space-size=${reachabilityAnalysisOptions.memoryLimitInMB ?? 8192}`,
88611
- jellyExecutable,
88612
- "--basedir",
88613
- mainProjectRoot,
88614
- "--timeout",
88615
- "" + (reachabilityAnalysisOptions.timeoutInSeconds ?? 60),
88616
- "--vulnerabilities",
88617
- vulnerabilitiesFile,
88618
- ...excludeEntries ? ["--exclude-entries", ...excludeEntries] : [],
88619
- "--diagnostics-json",
88620
- diagnosticsFile,
88621
- ...jellyOptions.maxIndirections ? ["--max-indirections", "" + jellyOptions.maxIndirections] : [],
88622
- ...jellyOptions.includePackages ? ["--include-packages", ...jellyOptions.includePackages] : [],
88623
- ...jellyOptions.approx ? ["--approx"] : [],
88624
- ...logFile ? ["--logfile", logFile] : [],
88625
- "--matches-file",
88626
- matchesFile,
88627
- "--vulnerabilities-callstacks",
88628
- callStackFile,
88629
- ...filesToAnalyze
88630
- ];
88631
- if (PRINT_JELLY_COMMAND)
88632
- logger.info("Jelly command:", jellyCmd.join(" "));
88633
- await runCommandResolveStdOut(
88634
- jellyCmd,
88635
- void 0,
88636
- // If it is an experimental run, make sure to crash the process if Jelly takes more than 50% longer than the timeout.
88637
- // This is done to mitigate the scenario where the Jelly process gets close to the memory limit and thus ends up spending most of its time on garbage collection, which can increase the time between timeout checks dramatically.
88638
- experiment && reachabilityAnalysisOptions.timeoutInSeconds ? { timeout: reachabilityAnalysisOptions.timeoutInSeconds * 1e3 * 1.5 } : void 0
88639
- );
88640
- if (reachabilityAnalysisOptions.printLogFile)
88641
- logger.info("JS analysis log file:", await readFile7(logFile, "utf-8"));
88642
- const analysisDiagnostics = JSON.parse(await readFile7(diagnosticsFile, "utf-8"));
88643
- analysisDiagnostics.time = analysisDiagnostics.analysisTime;
88644
- delete analysisDiagnostics.analysisTime;
88645
- analysisDiagnostics.timings = {
88646
- analysisTime: analysisDiagnostics.time,
88647
- patternMatchingTime: analysisDiagnostics.patternMatchingTime
88648
- };
88649
- const callStacks = JSON.parse(await readFile7(callStackFile, "utf-8"));
88650
- const matches = {};
88651
- for (const { vulnerability, paths } of callStacks) {
88652
- const transformedStacks = transformJellyCallStacks(projectRoot, paths);
88653
- if (matches[vulnerability.osv.url]) {
88654
- matches[vulnerability.osv.url].stacks.push(...transformedStacks.stacks);
88655
- } else
88656
- matches[vulnerability.osv.url] = transformedStacks;
88657
- }
88658
- return {
88659
- matches,
88660
- analysisDiagnostics
88661
- };
88662
- } finally {
88663
- await rm2(tmpFolder, { recursive: true });
88664
- }
88665
- }
88666
- async function runJellyPhantomDependencyAnalysis(projectRoot) {
88667
- const tmpFolder = await createTmpDirectory("jelly-analysis");
88668
- try {
88669
- const jellyExecutable = resolve6(COANA_REPOS_PATH(), "jelly-private", "dist", "bundle", "jelly.js");
88670
- const reachablePackagesFile = resolve6(tmpFolder, "reachable-packages.json");
88671
- const jellyCmd = [
88672
- "node",
88673
- jellyExecutable,
88674
- "--basedir",
88675
- projectRoot,
88676
- "--modules-only",
88677
- "--ignore-dependencies",
88678
- "--reachable-packages-file",
88679
- reachablePackagesFile,
88680
- projectRoot
88681
- ];
88682
- await runCommandResolveStdOut(jellyCmd);
88683
- return JSON.parse(await readFile7(reachablePackagesFile, "utf-8"));
88684
- } finally {
88685
- await rm2(tmpFolder, { recursive: true });
88686
- }
88687
- }
88688
- function relativizeSourceLocations(projectDir, paths) {
88689
- return {
88690
- ...paths,
88691
- stacks: paths.stacks.map((stack) => stack.map((s2) => ({
88692
- ...s2,
88693
- sourceLocation: { ...s2.sourceLocation, filename: relative4(projectDir, s2.sourceLocation.filename) }
88694
- })))
88695
- };
88696
- }
88697
- function transformJellyCallStacks(projectRoot, paths) {
88698
- return {
88699
- ...relativizeSourceLocations(projectRoot, paths),
88700
- affectedPackages: uniq4(paths.stacks.flatMap((stack) => map2(stack, "package")))
88701
- };
88702
- }
88703
-
88704
88560
  // dist/whole-program-code-aware-vulnerability-scanner/js/js-code-aware-vulnerability-scanner.js
88705
88561
  import { mkdtempSync } from "fs";
88706
88562
  import { cp as cp3, mkdir as mkdir7, rm as rm3, writeFile as writeFile6 } from "fs/promises";
@@ -88708,11 +88564,11 @@ import { tmpdir as tmpdir2 } from "os";
88708
88564
  import { join as join16 } from "path";
88709
88565
 
88710
88566
  // dist/whole-program-code-aware-vulnerability-scanner/js/dependency-preparation.js
88711
- var import_lodash10 = __toESM(require_lodash(), 1);
88567
+ var import_lodash9 = __toESM(require_lodash(), 1);
88712
88568
  import { existsSync as existsSync8 } from "fs";
88713
88569
  import { mkdir as mkdir6, symlink } from "fs/promises";
88714
88570
  import { availableParallelism } from "os";
88715
- import { dirname as dirname9, resolve as resolve8 } from "path";
88571
+ import { dirname as dirname9, resolve as resolve7 } from "path";
88716
88572
 
88717
88573
  // ../../node_modules/.pnpm/@isaacs+fs-minipass@4.0.1/node_modules/@isaacs/fs-minipass/dist/esm/index.js
88718
88574
  import EE from "events";
@@ -93350,7 +93206,7 @@ var mkdirpNative = Object.assign(async (path9, options) => {
93350
93206
  }, { sync: mkdirpNativeSync });
93351
93207
 
93352
93208
  // ../../node_modules/.pnpm/mkdirp@3.0.1/node_modules/mkdirp/dist/mjs/path-arg.js
93353
- import { parse as parse13, resolve as resolve7 } from "path";
93209
+ import { parse as parse13, resolve as resolve6 } from "path";
93354
93210
  var platform3 = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform;
93355
93211
  var pathArg = (path9) => {
93356
93212
  if (/\0/.test(path9)) {
@@ -93359,7 +93215,7 @@ var pathArg = (path9) => {
93359
93215
  code: "ERR_INVALID_ARG_VALUE"
93360
93216
  });
93361
93217
  }
93362
- path9 = resolve7(path9);
93218
+ path9 = resolve6(path9);
93363
93219
  if (platform3 === "win32") {
93364
93220
  const badWinChars = /[*|"<>?:]/;
93365
93221
  const { root: root3 } = parse13(path9);
@@ -94704,12 +94560,12 @@ var mtimeFilter = (opt) => {
94704
94560
  };
94705
94561
 
94706
94562
  // dist/whole-program-code-aware-vulnerability-scanner/js/dependency-preparation.js
94707
- var { chunk } = import_lodash10.default;
94563
+ var { chunk } = import_lodash9.default;
94708
94564
  async function prepareNpmDependencies(subprojectDir, workspaceDir, artifactIdToArtifact, directDependencies, packageNamesToInstall) {
94709
- if (existsSync8(resolve8(subprojectDir, "node_modules")))
94565
+ if (existsSync8(resolve7(subprojectDir, "node_modules")))
94710
94566
  return { failedPackages: [], installedPackages: [] };
94711
94567
  return await withTmpDirectory("npm-packages", async (tmpDir) => {
94712
- const dirToInstallDependencies = resolve8(subprojectDir, "node_modules", ".jelly");
94568
+ const dirToInstallDependencies = resolve7(subprojectDir, "node_modules", ".jelly");
94713
94569
  const transitiveDependenciesToInstall = Object.fromEntries(Object.entries(artifactIdToArtifact).filter(([_, dep]) => packageNamesToInstall.includes(getPackageName(dep))).map(([depId, dep]) => [depId, { ...dep }]));
94714
94570
  const { installedPackages, failedPackages } = await downloadDependenciesToDir(Object.values(transitiveDependenciesToInstall), tmpDir);
94715
94571
  const augmentedInstalledPackages = await extractDownloadedDependenciesToDir(dirToInstallDependencies, tmpDir, installedPackages);
@@ -94742,7 +94598,7 @@ async function downloadDependenciesToDir(dependenciesToInstall, tmpDir) {
94742
94598
  })}`, tmpDir);
94743
94599
  const npmPackRes = JSON.parse(stdout);
94744
94600
  chunk2.forEach((dep, idx) => {
94745
- dep.tarFileName = resolve8(tmpDir, npmPackRes[idx].filename);
94601
+ dep.tarFileName = resolve7(tmpDir, npmPackRes[idx].filename);
94746
94602
  });
94747
94603
  installedPackages.push(...chunk2);
94748
94604
  } catch (e) {
@@ -94771,8 +94627,8 @@ function getPackageName(dep) {
94771
94627
  }
94772
94628
  async function extractDownloadedDependenciesToDir(dirToInstallDependencies, tmpDir, dependenciesToInstall) {
94773
94629
  return await asyncMap(dependenciesToInstall, async (dep) => {
94774
- const tgzPath = resolve8(tmpDir, dep.tarFileName);
94775
- const dependencyDir = resolve8(dirToInstallDependencies, `${dep.version ? `${getPackageName(dep)}@${dep.version}` : getPackageName(dep)}`.replace("/", "+"), "node_modules", "aliasName" in dep && dep.aliasName ? dep.aliasName : getPackageName(dep));
94630
+ const tgzPath = resolve7(tmpDir, dep.tarFileName);
94631
+ const dependencyDir = resolve7(dirToInstallDependencies, `${dep.version ? `${getPackageName(dep)}@${dep.version}` : getPackageName(dep)}`.replace("/", "+"), "node_modules", "aliasName" in dep && dep.aliasName ? dep.aliasName : getPackageName(dep));
94776
94632
  await mkdir6(dependencyDir, { recursive: true });
94777
94633
  await extract({ file: tgzPath, cwd: dependencyDir, stripComponents: 1 });
94778
94634
  dep.installedPath = dependencyDir;
@@ -94787,7 +94643,7 @@ async function createSymlinksForDependenciesInRootDir(workspaceDir, dependencies
94787
94643
  const aliasName = "aliasName" in dependencyToInstall ? dependencyToInstall.aliasName : void 0;
94788
94644
  if (directDependencyNameToInfo[packageName] && directDependencyNameToInfo[packageName].version !== version3)
94789
94645
  continue;
94790
- const pathToCreateSymlinkFrom = resolve8(workspaceDir, "node_modules", aliasName ?? packageName);
94646
+ const pathToCreateSymlinkFrom = resolve7(workspaceDir, "node_modules", aliasName ?? packageName);
94791
94647
  if (existsSync8(pathToCreateSymlinkFrom))
94792
94648
  continue;
94793
94649
  await mkdir6(dirname9(pathToCreateSymlinkFrom), { recursive: true });
@@ -94801,7 +94657,7 @@ async function createSymlinksForEachDependency(dependencyInfosForDependenciesToI
94801
94657
  const pathToCreateSymlinkTo = dep.installedPath;
94802
94658
  if (!existsSync8(pathToCreateSymlinkTo))
94803
94659
  continue;
94804
- const pathToCreateSymlinkFrom = resolve8(depInfo.installedPath, "..", "aliasName" in dep && dep.aliasName !== void 0 ? dep.aliasName : getPackageName(dep));
94660
+ const pathToCreateSymlinkFrom = resolve7(depInfo.installedPath, "..", "aliasName" in dep && dep.aliasName !== void 0 ? dep.aliasName : getPackageName(dep));
94805
94661
  if (existsSync8(pathToCreateSymlinkFrom))
94806
94662
  continue;
94807
94663
  await mkdir6(dirname9(pathToCreateSymlinkFrom), { recursive: true });
@@ -94928,6 +94784,122 @@ function computePackagesOnVulnPathExcludingVulnerablePackage(vulnerabilities) {
94928
94784
  return [...packagesToAnalyze];
94929
94785
  }
94930
94786
 
94787
+ // dist/whole-program-code-aware-vulnerability-scanner/js/jelly-runner.js
94788
+ var import_lodash10 = __toESM(require_lodash(), 1);
94789
+ import { readFile as readFile7, rm as rm2, writeFile as writeFile5 } from "fs/promises";
94790
+ import { relative as relative4, resolve as resolve8 } from "path";
94791
+ var { map: map2, uniq: uniq4 } = import_lodash10.default;
94792
+ var PRINT_JELLY_COMMAND = false;
94793
+ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, vulnerabilities, experiment) {
94794
+ const tmpFolder = await createTmpDirectory("jelly-analysis");
94795
+ try {
94796
+ const filesToAnalyze = reachabilityAnalysisOptions.entryPoints ? reachabilityAnalysisOptions.entryPoints : [projectRoot];
94797
+ const jellyExecutable = resolve8(COANA_REPOS_PATH(), "jelly-private", "dist", "bundle", "jelly.js");
94798
+ const vulnerabilitiesInJellyFormat = vulnerabilities.map((v) => ({
94799
+ osv: v,
94800
+ patterns: v.vulnerabilityAccessPaths.map((p) => experiment === "AUGMENT_IMPORT_PATHS_EXPERIMENT" ? p.replace(">", "/**>") : p)
94801
+ // Replace > with /**> to ensure Jelly also matches call <PKG/dist/index.js>.foo for pattern <PKG>.foo
94802
+ }));
94803
+ const vulnerabilitiesFile = resolve8(tmpFolder, "vulnerabilities.json");
94804
+ const diagnosticsFile = resolve8(tmpFolder, "diagnostics.json");
94805
+ const matchesFile = resolve8(tmpFolder, "matches.json");
94806
+ const callStackFile = resolve8(tmpFolder, "call-stacks.json");
94807
+ const logFile = reachabilityAnalysisOptions.analysisLogFile ?? (reachabilityAnalysisOptions.printLogFile && resolve8(projectRoot, "js-analysis.log"));
94808
+ await writeFile5(vulnerabilitiesFile, JSON.stringify(vulnerabilitiesInJellyFormat));
94809
+ let excludeEntries;
94810
+ if (reachabilityAnalysisOptions.excludeDirs?.length) {
94811
+ const excludeDirsRelativeToProjectRoot = reachabilityAnalysisOptions.excludeDirs.map((d) => relative4(projectRoot, resolve8(mainProjectRoot, d)));
94812
+ const excludeDirsRelativeToProjectRootWithWildcards = excludeDirsRelativeToProjectRoot.map((d) => `${d}/**`);
94813
+ excludeEntries = [...excludeDirsRelativeToProjectRoot, ...excludeDirsRelativeToProjectRootWithWildcards];
94814
+ }
94815
+ const jellyCmd = [
94816
+ "node",
94817
+ `--max-old-space-size=${reachabilityAnalysisOptions.memoryLimitInMB ?? 8192}`,
94818
+ jellyExecutable,
94819
+ "--basedir",
94820
+ mainProjectRoot,
94821
+ "--timeout",
94822
+ "" + (reachabilityAnalysisOptions.timeoutInSeconds ?? 60),
94823
+ "--vulnerabilities",
94824
+ vulnerabilitiesFile,
94825
+ ...excludeEntries ? ["--exclude-entries", ...excludeEntries] : [],
94826
+ "--diagnostics-json",
94827
+ diagnosticsFile,
94828
+ ...jellyOptions.maxIndirections ? ["--max-indirections", "" + jellyOptions.maxIndirections] : [],
94829
+ ...jellyOptions.includePackages ? ["--include-packages", ...jellyOptions.includePackages] : [],
94830
+ ...jellyOptions.approx ? ["--approx"] : [],
94831
+ ...logFile ? ["--logfile", logFile] : [],
94832
+ "--matches-file",
94833
+ matchesFile,
94834
+ "--vulnerabilities-callstacks",
94835
+ callStackFile,
94836
+ ...filesToAnalyze
94837
+ ];
94838
+ if (PRINT_JELLY_COMMAND)
94839
+ logger.info("Jelly command:", jellyCmd.join(" "));
94840
+ await runCommandResolveStdOut(
94841
+ jellyCmd,
94842
+ void 0,
94843
+ // If it is an experimental run, make sure to crash the process if Jelly takes more than 50% longer than the timeout.
94844
+ // This is done to mitigate the scenario where the Jelly process gets close to the memory limit and thus ends up spending most of its time on garbage collection, which can increase the time between timeout checks dramatically.
94845
+ experiment && reachabilityAnalysisOptions.timeoutInSeconds ? { timeout: reachabilityAnalysisOptions.timeoutInSeconds * 1e3 * 1.5 } : void 0
94846
+ );
94847
+ if (reachabilityAnalysisOptions.printLogFile)
94848
+ logger.info("JS analysis log file:", await readFile7(logFile, "utf-8"));
94849
+ const analysisDiagnostics = JSON.parse(await readFile7(diagnosticsFile, "utf-8"));
94850
+ analysisDiagnostics.time = analysisDiagnostics.analysisTime;
94851
+ delete analysisDiagnostics.analysisTime;
94852
+ analysisDiagnostics.timings = {
94853
+ analysisTime: analysisDiagnostics.time,
94854
+ patternMatchingTime: analysisDiagnostics.patternMatchingTime
94855
+ };
94856
+ const callStacks = JSON.parse(await readFile7(callStackFile, "utf-8"));
94857
+ const matches = {};
94858
+ for (const { vulnerability, paths } of callStacks) {
94859
+ const transformedStacks = transformJellyCallStacks(projectRoot, paths);
94860
+ if (matches[vulnerability.osv.url]) {
94861
+ matches[vulnerability.osv.url].stacks.push(...transformedStacks.stacks);
94862
+ } else
94863
+ matches[vulnerability.osv.url] = transformedStacks;
94864
+ }
94865
+ return {
94866
+ matches,
94867
+ analysisDiagnostics
94868
+ };
94869
+ } finally {
94870
+ await rm2(tmpFolder, { recursive: true });
94871
+ }
94872
+ }
94873
+ async function runJellyPhantomDependencyAnalysis(projectRoot, options) {
94874
+ const tmpFolder = await createTmpDirectory("jelly-analysis");
94875
+ try {
94876
+ const jellyExecutable = resolve8(COANA_REPOS_PATH(), "jelly-private", "dist", "bundle", "jelly.js");
94877
+ const reachablePackagesFile = resolve8(tmpFolder, "reachable-packages.json");
94878
+ const jellyCmd = cmdt`node --max-old-space-size=${options.memoryLimitInMB}
94879
+ ${jellyExecutable} --basedir ${projectRoot} --modules-only --ignore-dependencies
94880
+ --reachable-packages-file ${reachablePackagesFile} ${projectRoot}`;
94881
+ await runCommandResolveStdOut(jellyCmd);
94882
+ return JSON.parse(await readFile7(reachablePackagesFile, "utf-8"));
94883
+ } finally {
94884
+ await rm2(tmpFolder, { recursive: true });
94885
+ }
94886
+ }
94887
+ function relativizeSourceLocations(projectDir, paths) {
94888
+ return {
94889
+ ...paths,
94890
+ stacks: paths.stacks.map((stack) => stack.map((s2) => ({
94891
+ ...s2,
94892
+ sourceLocation: { ...s2.sourceLocation, filename: relative4(projectDir, s2.sourceLocation.filename) }
94893
+ })))
94894
+ };
94895
+ }
94896
+ function transformJellyCallStacks(projectRoot, paths) {
94897
+ return {
94898
+ ...relativizeSourceLocations(projectRoot, paths),
94899
+ affectedPackages: uniq4(paths.stacks.flatMap((stack) => map2(stack, "package")))
94900
+ };
94901
+ }
94902
+
94931
94903
  // dist/whole-program-code-aware-vulnerability-scanner/js/js-code-aware-vulnerability-scanner.js
94932
94904
  var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
94933
94905
  mainProjectDir;
@@ -94969,7 +94941,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
94969
94941
  computeDetectedOccurrences: ({ url: url2 }) => transformSourceLocations3(matches[url2] ?? [])
94970
94942
  };
94971
94943
  } catch (e) {
94972
- logger.error("Error while running analysis: ", e.stack);
94944
+ logger.debug("Error while running analysis: ", e.stack);
94973
94945
  return { type: "error", message: e.message };
94974
94946
  } finally {
94975
94947
  this.numberAnalysesRun++;
@@ -96575,10 +96547,13 @@ ${errors.join("\n")}`);
96575
96547
  var trunc = trunc2;
96576
96548
  const exc = e;
96577
96549
  msg = util5.format("Error running mambalade:\n%O\nStdout:\n%s\nStderr:\n%s", pick(exc, ["code", "signal"]), trunc2(exc.stdout), trunc2(exc.stderr));
96578
- if (exc.signal ?? (exc.stderr.endsWith("MemoryError\n") || exc.stderr.includes("OSError: [Errno 12] Cannot allocate memory")))
96550
+ if (exc.signal ?? (exc.stderr.endsWith("MemoryError\n") || exc.stderr.includes("OSError: [Errno 12] Cannot allocate memory"))) {
96579
96551
  msg = `Mambalade ran out of memory:
96580
96552
  ${msg}`;
96581
- logger.error(msg);
96553
+ logger.debug(msg);
96554
+ } else {
96555
+ logger.error(msg);
96556
+ }
96582
96557
  } else
96583
96558
  logger.error("Unexpected error:", e);
96584
96559
  return { type: "error", message: msg };
@@ -97449,9 +97424,9 @@ var NpmAnalyzer = class {
97449
97424
  }
97450
97425
  async runPhantomDependencyAnalysis() {
97451
97426
  try {
97452
- return (await runJellyPhantomDependencyAnalysis(this.projectDir)).map((r) => r.name);
97427
+ return (await runJellyPhantomDependencyAnalysis(this.projectDir, this.state.reachabilityAnalysisOptions)).map((r) => r.name);
97453
97428
  } catch (e) {
97454
- console.error(e);
97429
+ logger.debug("Error while running jelly phantom dependency analysis: ", e);
97455
97430
  }
97456
97431
  }
97457
97432
  async runReachabilityAnalysis(vulns, analysisMetadataCollector, statusUpdater) {
@@ -97518,46 +97493,6 @@ var RustAnalyzer = class {
97518
97493
  }
97519
97494
  };
97520
97495
 
97521
- // dist/apply-precomputed-reachability-results.js
97522
- async function addPrecomputedResultsToVulnerabilities(analyzer, vulnerabilities) {
97523
- const phantomDependencies = await analyzer.runPhantomDependencyAnalysis();
97524
- if (!phantomDependencies)
97525
- return;
97526
- await applySeries(vulnerabilities, async (v) => {
97527
- const dismissVulnerability = canDismissVulnerability(phantomDependencies, v.vulnChainDetails);
97528
- v.unreachableByPrecomputation = dismissVulnerability ? "YES" : "NO";
97529
- });
97530
- }
97531
- function canDismissVulnerability(phantomDependencies, vulnChainDetails) {
97532
- const parentsMap = computeParentsMap(vulnChainDetails);
97533
- const [vulnNodeIdentifier] = Object.entries(vulnChainDetails.transitiveDependencies).find(([_identifier, node]) => node.vulnerable);
97534
- let canDismiss = true;
97535
- const recHelper = (nodeIdentifier, depth) => {
97536
- if (depth === 0)
97537
- return void 0;
97538
- const parents3 = parentsMap.get(nodeIdentifier).filter((parent2) => parent2 !== ROOT_NODE_STR);
97539
- const thisReachabilityPrecomp = nodeIdentifier === vulnNodeIdentifier ? "Reachable" : vulnChainDetails.transitiveDependencies[nodeIdentifier].reachabilityPrecomp;
97540
- if (!thisReachabilityPrecomp)
97541
- return void 0;
97542
- const thisMayReachVulnerableNode = ["Reachable", "Unknown"].includes(thisReachabilityPrecomp);
97543
- if (parents3.length === 0 && thisMayReachVulnerableNode) {
97544
- canDismiss = false;
97545
- }
97546
- if (parents3) {
97547
- const parentsReachabilityPrecomp = parents3.map((p) => recHelper(p, depth - 1));
97548
- if (parentsReachabilityPrecomp.some((reachabilityPrecomp) => !reachabilityPrecomp) && thisMayReachVulnerableNode) {
97549
- canDismiss = false;
97550
- }
97551
- }
97552
- if (thisMayReachVulnerableNode && phantomDependencies.includes(nodeIdentifier)) {
97553
- canDismiss = false;
97554
- }
97555
- return thisReachabilityPrecomp;
97556
- };
97557
- recHelper(vulnNodeIdentifier, 5);
97558
- return canDismiss;
97559
- }
97560
-
97561
97496
  // dist/main.js
97562
97497
  var { partition: partition3 } = import_lodash19.default;
97563
97498
  var ecosystemAnalyzer = {
@@ -97578,10 +97513,6 @@ async function runReachabilityAnalysis(state) {
97578
97513
  if (!constructor)
97579
97514
  throw Error(`No analyzer associated with ecosystem ${ecosystem}`);
97580
97515
  const analyzer = new constructor(state, projectDir);
97581
- try {
97582
- await addPrecomputedResultsToVulnerabilities(analyzer, state.vulnerabilities);
97583
- } catch (e) {
97584
- }
97585
97516
  const [vulnerabilitiesWithPrecomputedResults, vulnerabilitiesWithoutPrecomputedResults] = partition3(state.vulnerabilities, (v) => "results" in v);
97586
97517
  const augmentedVulnerabilities = await runWholeProgramCodeAwareVulnerabilityScanner(analyzer, vulnerabilitiesWithoutPrecomputedResults, async (amd) => {
97587
97518
  await dashboardAPI2.registerAnalysisMetadata(relative6(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, state.workspaceData.data.type, amd, COANA_REPORT_ID, apiKey2);