@coana-tech/cli 14.12.164 → 14.12.166

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
@@ -204869,7 +204869,7 @@ function getSocketAPI() {
204869
204869
 
204870
204870
  // ../utils/src/tool-extractor.ts
204871
204871
  import { createHash } from "node:crypto";
204872
- import { createReadStream, createWriteStream as createWriteStream2, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
204872
+ import { createReadStream, createWriteStream as createWriteStream3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
204873
204873
  import { copyFile, cp as cp2, mkdir as mkdir4, writeFile as writeFile2 } from "node:fs/promises";
204874
204874
  import { tmpdir as tmpdir2 } from "node:os";
204875
204875
  import { basename as basename3, dirname as dirname5, join as join5 } from "node:path";
@@ -204879,6 +204879,7 @@ import { createGunzip } from "node:zlib";
204879
204879
  // ../utils/src/command-utils.ts
204880
204880
  import assert from "assert";
204881
204881
  import { execFile as execFile2 } from "child_process";
204882
+ import { createWriteStream as createWriteStream2 } from "fs";
204882
204883
 
204883
204884
  // ../../node_modules/.pnpm/async-mutex@0.5.0/node_modules/async-mutex/index.mjs
204884
204885
  var E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
@@ -205622,6 +205623,14 @@ async function execNeverFail(cmd, dir, options) {
205622
205623
  });
205623
205624
  });
205624
205625
  }
205626
+ if (options?.outputLogFile) {
205627
+ const logFileStream = createWriteStream2(options.outputLogFile, { flags: "w" });
205628
+ childProcess.stdout?.pipe(logFileStream);
205629
+ childProcess.stderr?.pipe(logFileStream);
205630
+ childProcess.on("close", () => {
205631
+ logFileStream.end();
205632
+ });
205633
+ }
205625
205634
  if (options?.stdin) childProcess.stdin?.write(options.stdin);
205626
205635
  childProcess.stdin?.end();
205627
205636
  });
@@ -211793,7 +211802,7 @@ async function getNodeExecutable(overridePath) {
211793
211802
  await pipeline(
211794
211803
  createReadStream(compressedBinaryPath),
211795
211804
  createGunzip(),
211796
- createWriteStream2(nodeBinaryPath, { mode: 493 })
211805
+ createWriteStream3(nodeBinaryPath, { mode: 493 })
211797
211806
  );
211798
211807
  logger.debug("Node.js binary extracted and ready");
211799
211808
  return nodeBinaryPath;
@@ -212022,7 +212031,7 @@ async function getUvExecutable() {
212022
212031
  await pipeline(
212023
212032
  createReadStream(compressedBinaryPath),
212024
212033
  createGunzip(),
212025
- createWriteStream2(uvBinaryPath, { mode: 493 })
212034
+ createWriteStream3(uvBinaryPath, { mode: 493 })
212026
212035
  );
212027
212036
  logger.debug("uv binary extracted and ready");
212028
212037
  return uvBinaryPath;
@@ -224349,6 +224358,7 @@ import { join as join12, resolve as resolve18 } from "path";
224349
224358
  // ../utils/dist/command-utils.js
224350
224359
  import assert9 from "assert";
224351
224360
  import { execFile as execFile4 } from "child_process";
224361
+ import { createWriteStream as createWriteStream4 } from "fs";
224352
224362
 
224353
224363
  // ../utils/dist/spinner.js
224354
224364
  var import_lodash4 = __toESM(require_lodash(), 1);
@@ -224879,6 +224889,14 @@ async function execNeverFail3(cmd, dir, options) {
224879
224889
  });
224880
224890
  });
224881
224891
  }
224892
+ if (options?.outputLogFile) {
224893
+ const logFileStream = createWriteStream4(options.outputLogFile, { flags: "w" });
224894
+ childProcess.stdout?.pipe(logFileStream);
224895
+ childProcess.stderr?.pipe(logFileStream);
224896
+ childProcess.on("close", () => {
224897
+ logFileStream.end();
224898
+ });
224899
+ }
224882
224900
  if (options?.stdin)
224883
224901
  childProcess.stdin?.write(options.stdin);
224884
224902
  childProcess.stdin?.end();
@@ -231320,7 +231338,7 @@ function flattenDockerSpec({
231320
231338
  // ../web-compat-utils/dist/logger-singleton.js
231321
231339
  var import_winston2 = __toESM(require_winston(), 1);
231322
231340
  import { Console as Console2 } from "console";
231323
- import { createWriteStream as createWriteStream3 } from "fs";
231341
+ import { createWriteStream as createWriteStream5 } from "fs";
231324
231342
  import { readFile as readFile29 } from "fs/promises";
231325
231343
 
231326
231344
  // ../web-compat-utils/dist/util-formatter.js
@@ -231354,7 +231372,7 @@ var CLILogger2 = class {
231354
231372
  }
231355
231373
  const transports = [new import_winston2.transports.Console()];
231356
231374
  if (logFilePath) {
231357
- this.writeStream = createWriteStream3(logFilePath, { flags: "a" });
231375
+ this.writeStream = createWriteStream5(logFilePath, { flags: "a" });
231358
231376
  transports.push(new import_winston2.transports.Stream({ stream: this.writeStream, level: "file" }));
231359
231377
  }
231360
231378
  const customLevels = {
@@ -234796,7 +234814,7 @@ var BatchedHttpLogStreamer = class {
234796
234814
  // ../utils/src/logging/socket-log-server.ts
234797
234815
  import { createServer } from "net";
234798
234816
  import { once as once8 } from "events";
234799
- import { createWriteStream as createWriteStream4, existsSync as existsSync24 } from "fs";
234817
+ import { createWriteStream as createWriteStream6, existsSync as existsSync24 } from "fs";
234800
234818
  import { unlink as unlink3 } from "fs/promises";
234801
234819
  var SocketLogServer = class {
234802
234820
  server;
@@ -234813,7 +234831,7 @@ var SocketLogServer = class {
234813
234831
  this.socketPath = options.socketPath;
234814
234832
  this.logFilePath = options.logFilePath;
234815
234833
  this.onLogReceived = options.onLogReceived;
234816
- this.writeStream = createWriteStream4(this.logFilePath, { flags: "a" });
234834
+ this.writeStream = createWriteStream6(this.logFilePath, { flags: "a" });
234817
234835
  this.server = createServer((socket) => this.handleConnection(socket));
234818
234836
  }
234819
234837
  async start() {
@@ -251289,7 +251307,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
251289
251307
  }
251290
251308
 
251291
251309
  // dist/version.js
251292
- var version3 = "14.12.164";
251310
+ var version3 = "14.12.166";
251293
251311
 
251294
251312
  // dist/cli-core.js
251295
251313
  var { mapValues, omit, partition, pickBy: pickBy2 } = import_lodash15.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.12.164",
3
+ "version": "14.12.166",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -80897,6 +80897,7 @@ import { join as join4 } from "path";
80897
80897
  // ../utils/src/command-utils.ts
80898
80898
  import assert from "assert";
80899
80899
  import { execFile as execFile2 } from "child_process";
80900
+ import { createWriteStream as createWriteStream2 } from "fs";
80900
80901
 
80901
80902
  // ../utils/src/telemetry/telemetry-collector.ts
80902
80903
  import { execFile } from "child_process";
@@ -81299,6 +81300,14 @@ async function execNeverFail(cmd, dir, options) {
81299
81300
  });
81300
81301
  });
81301
81302
  }
81303
+ if (options?.outputLogFile) {
81304
+ const logFileStream = createWriteStream2(options.outputLogFile, { flags: "w" });
81305
+ childProcess.stdout?.pipe(logFileStream);
81306
+ childProcess.stderr?.pipe(logFileStream);
81307
+ childProcess.on("close", () => {
81308
+ logFileStream.end();
81309
+ });
81310
+ }
81302
81311
  if (options?.stdin) childProcess.stdin?.write(options.stdin);
81303
81312
  childProcess.stdin?.end();
81304
81313
  });
@@ -81308,6 +81317,10 @@ async function execNeverFail(cmd, dir, options) {
81308
81317
  await analyzerTelemetryServer?.close();
81309
81318
  }
81310
81319
  }
81320
+ async function execAndResolveSucceeded(cmd, dir, options) {
81321
+ const { error } = await execNeverFail(cmd, dir, options);
81322
+ return !error;
81323
+ }
81311
81324
  async function exec(cmd, dir, options) {
81312
81325
  const { error, stdout, stderr } = await execNeverFail(cmd, dir, options);
81313
81326
  if (!error) return { stdout, stderr };
@@ -81387,6 +81400,12 @@ async function execNeverFail2(cmd, dir, options) {
81387
81400
  logger.debug(`Command ${formatCmd(cmd, dir)} finished ${result.error ? "with error" : "successfully"}`);
81388
81401
  return result;
81389
81402
  }
81403
+ async function execAndResolveSucceeded2(cmd, dir, options) {
81404
+ logger.debug(`Running command: ${formatCmd(cmd, dir)}`);
81405
+ const result = await execAndResolveSucceeded(cmd, dir, options);
81406
+ logger.debug(`Command ${formatCmd(cmd, dir)} finished ${result ? "successfully" : "with error"}`);
81407
+ return result;
81408
+ }
81390
81409
  async function exec2(cmd, dir, options) {
81391
81410
  logger.debug(`Running command: ${formatCmd(cmd, dir)}`);
81392
81411
  try {
@@ -88868,7 +88887,7 @@ function getUrlForPackage(packageName, version3) {
88868
88887
 
88869
88888
  // ../utils/src/tool-extractor.ts
88870
88889
  import { createHash } from "node:crypto";
88871
- import { createReadStream, createWriteStream as createWriteStream2, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
88890
+ import { createReadStream, createWriteStream as createWriteStream3, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
88872
88891
  import { copyFile as copyFile2, cp as cp4, mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
88873
88892
  import { tmpdir as tmpdir3 } from "node:os";
88874
88893
  import { basename as basename5, dirname as dirname8, join as join11 } from "node:path";
@@ -94020,7 +94039,7 @@ async function getNodeExecutable(overridePath) {
94020
94039
  await pipeline(
94021
94040
  createReadStream(compressedBinaryPath),
94022
94041
  createGunzip(),
94023
- createWriteStream2(nodeBinaryPath, { mode: 493 })
94042
+ createWriteStream3(nodeBinaryPath, { mode: 493 })
94024
94043
  );
94025
94044
  logger.debug("Node.js binary extracted and ready");
94026
94045
  return nodeBinaryPath;
@@ -110961,6 +110980,7 @@ import { readFile as readFile9, realpath as realpath2, rm as rm2, writeFile as w
110961
110980
  import { relative as relative6, resolve as resolve13 } from "path";
110962
110981
  var { map: map2, uniq: uniq4 } = import_lodash10.default;
110963
110982
  var PRINT_JELLY_COMMAND = false;
110983
+ var STRACE_MAX_LINES = 1e4;
110964
110984
  async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, timeoutInSeconds, vulnerabilities, experiment, telemetryHandler, analyzerTelemetryHandler) {
110965
110985
  const tmpFolder = await createTmpDirectory("jelly-analysis");
110966
110986
  try {
@@ -110978,7 +110998,7 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
110978
110998
  const diagnosticsFile = resolve13(tmpFolder, "diagnostics.json");
110979
110999
  const callStackFile = resolve13(tmpFolder, "call-stacks.json");
110980
111000
  const affectedPackagesFile = resolve13(tmpFolder, "affected-packages.json");
110981
- const logFile = reachabilityAnalysisOptions.analysisLogFile ?? (reachabilityAnalysisOptions.printLogFile && resolve13(projectRoot, "js-analysis.log"));
111001
+ const logFile = reachabilityAnalysisOptions.printLogFile ? resolve13(projectRoot, "js-analysis.log") : void 0;
110982
111002
  await writeFile7(vulnerabilitiesFile, JSON.stringify(vulnerabilitiesInJellyFormat));
110983
111003
  const useLazy = experiment === "LAZY_EXPERIMENT" || reachabilityAnalysisOptions.lazy;
110984
111004
  const { includePackages } = jellyOptions;
@@ -110996,15 +111016,21 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
110996
111016
  --max-indirections=${useLazy ? 2 : jellyOptions.maxIndirections}
110997
111017
  ${!!includePackages && (includePackages.length ? ["--include-packages", ...includePackages] : ["--ignore-dependencies"])}
110998
111018
  ${jellyOptions.approx && "--approx"}
110999
- ${logFile ? ["--logfile", logFile] : []}
111000
111019
  --callstacks-json ${callStackFile}
111001
111020
  ${additionalFlags}
111002
111021
  ${filesToAnalyze}
111003
111022
  `;
111004
111023
  if (PRINT_JELLY_COMMAND)
111005
111024
  logger.info("Jelly command:", jellyCmd.join(" "));
111025
+ const straceEnabled = process.env.COANA_ANALYSIS_ENABLE_STRACE === "true";
111026
+ const straceOutputFile = resolve13(mainProjectRoot, "strace-output.txt");
111027
+ const useStrace = straceEnabled && await isStraceAvailable();
111028
+ if (straceEnabled && !useStrace) {
111029
+ logger.info("COANA_ANALYSIS_ENABLE_STRACE is enabled but strace is not available on this system");
111030
+ }
111031
+ const cmdToRun = useStrace ? ["strace", "-f", "-o", `|tail -n ${STRACE_MAX_LINES} > ${straceOutputFile}`, ...jellyCmd] : jellyCmd;
111006
111032
  await runCommandResolveStdOut2(
111007
- jellyCmd,
111033
+ cmdToRun,
111008
111034
  void 0,
111009
111035
  // Use SIGKILL to ensure termination even if the process is unresponsive 50% above the timeout (e.g., due to GC pressure).
111010
111036
  {
@@ -111012,7 +111038,8 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
111012
111038
  killSignal: "SIGKILL",
111013
111039
  heartbeat: HEARTBEATS.js,
111014
111040
  telemetryHandler,
111015
- analyzerTelemetryHandler
111041
+ analyzerTelemetryHandler,
111042
+ outputLogFile: logFile
111016
111043
  }
111017
111044
  );
111018
111045
  if (reachabilityAnalysisOptions.printLogFile)
@@ -111111,6 +111138,9 @@ function transformJellyCallStacks(projectRoot, paths) {
111111
111138
  affectedPackages: uniq4(paths.stacks.flatMap((stack) => map2(stack, "package")))
111112
111139
  };
111113
111140
  }
111141
+ async function isStraceAvailable() {
111142
+ return execAndResolveSucceeded2(["which", "strace"]);
111143
+ }
111114
111144
 
111115
111145
  // dist/whole-program-code-aware-vulnerability-scanner/js/js-code-aware-vulnerability-scanner.js
111116
111146
  var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
@@ -111287,7 +111317,7 @@ function transformSourceLocations(fileMappings, detectedOccurrences) {
111287
111317
  // dist/whole-program-code-aware-vulnerability-scanner/go/go-code-aware-vulnerability-scanner.js
111288
111318
  var import_lodash11 = __toESM(require_lodash(), 1);
111289
111319
  import assert5 from "assert";
111290
- import { existsSync as existsSync11, createReadStream as createReadStream2, createWriteStream as createWriteStream3 } from "fs";
111320
+ import { existsSync as existsSync11, createReadStream as createReadStream2, createWriteStream as createWriteStream4 } from "fs";
111291
111321
  import { readFile as readFile10, rm as rm4, cp as cp6 } from "fs/promises";
111292
111322
  import zlib2 from "zlib";
111293
111323
  import { join as join16, resolve as resolve14, sep as sep3 } from "path";
@@ -111337,7 +111367,7 @@ var GoCodeAwareVulnerabilityScanner = class {
111337
111367
  const binaryPath = ToolPathResolver.getGoanaBinaryPath(process.platform, process.arch);
111338
111368
  if (!await exists(binaryPath))
111339
111369
  throw new Error(`goana binary not found at '${binaryPath}'`);
111340
- await pipeline2(createReadStream2(binaryPath), zlib2.createGunzip(), createWriteStream3(join16(tmpDir, "goana"), { mode: 493 }));
111370
+ await pipeline2(createReadStream2(binaryPath), zlib2.createGunzip(), createWriteStream4(join16(tmpDir, "goana"), { mode: 493 }));
111341
111371
  const vulnAccPaths = uniq5(vulns.flatMap((v) => v.vulnerabilityAccessPaths));
111342
111372
  const { error, stderr } = await execNeverFail2(cmdt`${join16(tmpDir, "goana")}
111343
111373
  -output-vulnerabilities ${vulnsOutputFile}
@@ -113690,7 +113720,7 @@ import { resolve as resolve21 } from "path";
113690
113720
 
113691
113721
  // dist/whole-program-code-aware-vulnerability-scanner/ruby/ruby-code-aware-vulnerability-scanner.js
113692
113722
  var import_lodash20 = __toESM(require_lodash(), 1);
113693
- import { createWriteStream as createWriteStream4, existsSync as existsSync15 } from "fs";
113723
+ import { createWriteStream as createWriteStream5, existsSync as existsSync15 } from "fs";
113694
113724
  import { mkdir as mkdir9, readdir as readdir5, readFile as readFile13, rm as rm7 } from "fs/promises";
113695
113725
  import { join as join18, relative as relative9 } from "path";
113696
113726
  import { pipeline as pipeline3 } from "stream/promises";
@@ -113892,7 +113922,7 @@ async function downloadAndExtractGem(gemName, version3, vendorDir) {
113892
113922
  throw new Error(`Failed to download gem from ${response.url}: ${response.status} ${response.statusText}`);
113893
113923
  if (!response.body)
113894
113924
  throw new Error("Response body is null");
113895
- await pipeline3(response.body, createWriteStream4(tempGemFile));
113925
+ await pipeline3(response.body, createWriteStream5(tempGemFile));
113896
113926
  await mkdir9(gemDir, { recursive: true });
113897
113927
  logger.debug(`Extracting gem ${gemName}@${version3}`);
113898
113928
  await exec2(["tar", "-xf", tempGemFile, "data.tar.gz"], gemDir);