@coana-tech/cli 14.12.42 → 14.12.43

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
@@ -207657,7 +207657,9 @@ function getPackageMangerForDirectory(directory) {
207657
207657
  } else if (existsSync11(join9(directory, "package-lock.json"))) {
207658
207658
  return "NPM";
207659
207659
  }
207660
- throw new Error("Upgrading packages is currently only supported for NPM projects using a lock file.");
207660
+ throw new Error(
207661
+ `Upgrading packages is currently only supported for NPM projects using a lock file. Failed to find a lock file in ${directory}`
207662
+ );
207661
207663
  }
207662
207664
  function sortUpgradesByOffset(upgrades) {
207663
207665
  return [...upgrades].sort((a4, b) => {
@@ -212387,366 +212389,999 @@ ${detailsString}` : ""}`;
212387
212389
  }
212388
212390
  };
212389
212391
 
212390
- // dist/cli-core.js
212391
- import { writeFileSync as writeFileSync3 } from "fs";
212392
- import { mkdir as mkdir2, writeFile as writeFile10 } from "fs/promises";
212393
-
212394
- // ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/index.mjs
212395
- var FORCE_COLOR;
212396
- var NODE_DISABLE_COLORS;
212397
- var NO_COLOR;
212398
- var TERM;
212399
- var isTTY = true;
212400
- if (typeof process !== "undefined") {
212401
- ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
212402
- isTTY = process.stdout && process.stdout.isTTY;
212403
- }
212404
- var $ = {
212405
- enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY),
212406
- // modifiers
212407
- reset: init(0, 0),
212408
- bold: init(1, 22),
212409
- dim: init(2, 22),
212410
- italic: init(3, 23),
212411
- underline: init(4, 24),
212412
- inverse: init(7, 27),
212413
- hidden: init(8, 28),
212414
- strikethrough: init(9, 29),
212415
- // colors
212416
- black: init(30, 39),
212417
- red: init(31, 39),
212418
- green: init(32, 39),
212419
- yellow: init(33, 39),
212420
- blue: init(34, 39),
212421
- magenta: init(35, 39),
212422
- cyan: init(36, 39),
212423
- white: init(37, 39),
212424
- gray: init(90, 39),
212425
- grey: init(90, 39),
212426
- // background colors
212427
- bgBlack: init(40, 49),
212428
- bgRed: init(41, 49),
212429
- bgGreen: init(42, 49),
212430
- bgYellow: init(43, 49),
212431
- bgBlue: init(44, 49),
212432
- bgMagenta: init(45, 49),
212433
- bgCyan: init(46, 49),
212434
- bgWhite: init(47, 49)
212435
- };
212436
- function run(arr, str) {
212437
- let i7 = 0, tmp, beg = "", end2 = "";
212438
- for (; i7 < arr.length; i7++) {
212439
- tmp = arr[i7];
212440
- beg += tmp.open;
212441
- end2 += tmp.close;
212442
- if (!!~str.indexOf(tmp.close)) {
212443
- str = str.replace(tmp.rgx, tmp.close + tmp.open);
212392
+ // ../utils/src/promise-queue.ts
212393
+ var PromiseQueue = class {
212394
+ /*
212395
+ * @param maxConcurrency The maximum number of tasks that can run in parallel.
212396
+ * @param maxQueueLength The maximum number of tasks that can be queued. If the queue is full, the oldest task is removed.
212397
+ */
212398
+ constructor(maxConcurrency, maxQueueLength) {
212399
+ this.maxConcurrency = maxConcurrency;
212400
+ this.maxQueueLength = maxQueueLength;
212401
+ if (maxQueueLength && maxQueueLength < 1) {
212402
+ throw new Error("maxQueueLength must be at least 1");
212444
212403
  }
212404
+ this.maxConcurrency = maxConcurrency;
212445
212405
  }
212446
- return beg + str + end2;
212447
- }
212448
- function chain(has2, keys) {
212449
- let ctx = { has: has2, keys };
212450
- ctx.reset = $.reset.bind(ctx);
212451
- ctx.bold = $.bold.bind(ctx);
212452
- ctx.dim = $.dim.bind(ctx);
212453
- ctx.italic = $.italic.bind(ctx);
212454
- ctx.underline = $.underline.bind(ctx);
212455
- ctx.inverse = $.inverse.bind(ctx);
212456
- ctx.hidden = $.hidden.bind(ctx);
212457
- ctx.strikethrough = $.strikethrough.bind(ctx);
212458
- ctx.black = $.black.bind(ctx);
212459
- ctx.red = $.red.bind(ctx);
212460
- ctx.green = $.green.bind(ctx);
212461
- ctx.yellow = $.yellow.bind(ctx);
212462
- ctx.blue = $.blue.bind(ctx);
212463
- ctx.magenta = $.magenta.bind(ctx);
212464
- ctx.cyan = $.cyan.bind(ctx);
212465
- ctx.white = $.white.bind(ctx);
212466
- ctx.gray = $.gray.bind(ctx);
212467
- ctx.grey = $.grey.bind(ctx);
212468
- ctx.bgBlack = $.bgBlack.bind(ctx);
212469
- ctx.bgRed = $.bgRed.bind(ctx);
212470
- ctx.bgGreen = $.bgGreen.bind(ctx);
212471
- ctx.bgYellow = $.bgYellow.bind(ctx);
212472
- ctx.bgBlue = $.bgBlue.bind(ctx);
212473
- ctx.bgMagenta = $.bgMagenta.bind(ctx);
212474
- ctx.bgCyan = $.bgCyan.bind(ctx);
212475
- ctx.bgWhite = $.bgWhite.bind(ctx);
212476
- return ctx;
212477
- }
212478
- function init(open, close) {
212479
- let blk = {
212480
- open: `\x1B[${open}m`,
212481
- close: `\x1B[${close}m`,
212482
- rgx: new RegExp(`\\x1b\\[${close}m`, "g")
212483
- };
212484
- return function(txt) {
212485
- if (this !== void 0 && this.has !== void 0) {
212486
- !!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));
212487
- return txt === void 0 ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
212406
+ queue = [];
212407
+ activeTasks = 0;
212408
+ idleResolver = null;
212409
+ idleRejector = null;
212410
+ error = null;
212411
+ async runNextTask() {
212412
+ if (this.activeTasks >= this.maxConcurrency) {
212413
+ return;
212414
+ }
212415
+ const task = this.queue.shift();
212416
+ if (task) {
212417
+ this.activeTasks++;
212418
+ try {
212419
+ await task();
212420
+ } catch (e) {
212421
+ this.error = e;
212422
+ } finally {
212423
+ this.activeTasks--;
212424
+ this.runNextTask();
212425
+ this.checkIdle();
212426
+ }
212427
+ } else {
212428
+ this.checkIdle();
212488
212429
  }
212489
- return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
212490
- };
212491
- }
212492
- var kleur_default = $;
212493
-
212494
- // ../../node_modules/.pnpm/yoctocolors@2.1.2/node_modules/yoctocolors/base.js
212495
- import tty from "node:tty";
212496
- var hasColors = tty?.WriteStream?.prototype?.hasColors?.() ?? false;
212497
- var format5 = (open, close) => {
212498
- if (!hasColors) {
212499
- return (input) => input;
212500
212430
  }
212501
- const openCode = `\x1B[${open}m`;
212502
- const closeCode = `\x1B[${close}m`;
212503
- return (input) => {
212504
- const string = input + "";
212505
- let index2 = string.indexOf(closeCode);
212506
- if (index2 === -1) {
212507
- return openCode + string + closeCode;
212431
+ checkIdle() {
212432
+ if (!this.idleResolver || !this.idleRejector) return;
212433
+ const shouldResolve = this.queue.length === 0 && this.activeTasks === 0;
212434
+ if (this.error) this.idleRejector(this.error);
212435
+ else if (shouldResolve) this.idleResolver();
212436
+ const resolvedOrRejected = !!this.error || shouldResolve;
212437
+ if (resolvedOrRejected) {
212438
+ this.error = null;
212439
+ this.idleResolver = null;
212440
+ this.idleRejector = null;
212508
212441
  }
212509
- let result = openCode;
212510
- let lastIndex = 0;
212511
- const reopenOnNestedClose = close === 22;
212512
- const replaceCode = (reopenOnNestedClose ? closeCode : "") + openCode;
212513
- while (index2 !== -1) {
212514
- result += string.slice(lastIndex, index2) + replaceCode;
212515
- lastIndex = index2 + closeCode.length;
212516
- index2 = string.indexOf(closeCode, lastIndex);
212442
+ }
212443
+ enqueueTask(task) {
212444
+ if (this.maxQueueLength && this.queue.length >= this.maxQueueLength) {
212445
+ this.queue.shift();
212517
212446
  }
212518
- result += string.slice(lastIndex) + closeCode;
212519
- return result;
212520
- };
212447
+ this.queue.push(task);
212448
+ this.runNextTask();
212449
+ }
212450
+ async onIdle() {
212451
+ return new Promise((resolve36, reject) => {
212452
+ if (this.error) {
212453
+ reject(this.error);
212454
+ this.error = null;
212455
+ } else if (this.queue.length === 0 && this.activeTasks === 0) {
212456
+ resolve36();
212457
+ } else {
212458
+ this.idleResolver = resolve36;
212459
+ this.idleRejector = reject;
212460
+ }
212461
+ });
212462
+ }
212521
212463
  };
212522
- var reset = format5(0, 0);
212523
- var bold = format5(1, 22);
212524
- var dim = format5(2, 22);
212525
- var italic = format5(3, 23);
212526
- var underline = format5(4, 24);
212527
- var overline = format5(53, 55);
212528
- var inverse = format5(7, 27);
212529
- var hidden = format5(8, 28);
212530
- var strikethrough = format5(9, 29);
212531
- var black = format5(30, 39);
212532
- var red = format5(31, 39);
212533
- var green = format5(32, 39);
212534
- var yellow = format5(33, 39);
212535
- var blue = format5(34, 39);
212536
- var magenta = format5(35, 39);
212537
- var cyan = format5(36, 39);
212538
- var white = format5(37, 39);
212539
- var gray = format5(90, 39);
212540
- var bgBlack = format5(40, 49);
212541
- var bgRed = format5(41, 49);
212542
- var bgGreen = format5(42, 49);
212543
- var bgYellow = format5(43, 49);
212544
- var bgBlue = format5(44, 49);
212545
- var bgMagenta = format5(45, 49);
212546
- var bgCyan = format5(46, 49);
212547
- var bgWhite = format5(47, 49);
212548
- var bgGray = format5(100, 49);
212549
- var redBright = format5(91, 39);
212550
- var greenBright = format5(92, 39);
212551
- var yellowBright = format5(93, 39);
212552
- var blueBright = format5(94, 39);
212553
- var magentaBright = format5(95, 39);
212554
- var cyanBright = format5(96, 39);
212555
- var whiteBright = format5(97, 39);
212556
- var bgRedBright = format5(101, 49);
212557
- var bgGreenBright = format5(102, 49);
212558
- var bgYellowBright = format5(103, 49);
212559
- var bgBlueBright = format5(104, 49);
212560
- var bgMagentaBright = format5(105, 49);
212561
- var bgCyanBright = format5(106, 49);
212562
- var bgWhiteBright = format5(107, 49);
212563
212464
 
212564
- // dist/cli-core.js
212565
- var import_lodash15 = __toESM(require_lodash(), 1);
212566
- import os from "os";
212567
- import { join as join26, relative as relative14, resolve as resolve33 } from "path";
212465
+ // dist/cli-upgrade-purl.js
212466
+ import { join as join25, relative as relative14, resolve as resolve32 } from "node:path";
212568
212467
 
212569
- // ../utils/src/dashboard-api/shared-api.ts
212570
- var DashboardAPI = class {
212571
- socketMode;
212572
- coanaAPI;
212573
- socketAPI;
212574
- disableAnalyticsSharing;
212575
- constructor(socketMode, disableAnalyticsSharing) {
212576
- this.socketMode = socketMode;
212577
- this.disableAnalyticsSharing = disableAnalyticsSharing;
212578
- this.coanaAPI = getCoanaAPI();
212579
- this.socketAPI = getSocketAPI();
212580
- }
212581
- async createReport(repoUrl, projectName, cliVersion, commitSha, branchName, cliOptions, apiKey, cliRunEnv) {
212582
- if (this.disableAnalyticsSharing) {
212583
- return;
212584
- }
212585
- if (this.socketMode) {
212586
- return (await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion)).tier1_reachability_scan_id;
212587
- } else {
212588
- return await this.coanaAPI.createCoanaReport(
212589
- repoUrl,
212590
- projectName,
212591
- cliVersion,
212592
- commitSha,
212593
- branchName,
212594
- cliOptions,
212595
- apiKey,
212596
- cliRunEnv
212597
- );
212598
- }
212599
- }
212600
- async sendErrorReport(apiKey, stackTrace, shouldLogSharing, reportId, repoUrl, projectName, logContent) {
212601
- if (this.disableAnalyticsSharing) {
212602
- return;
212603
- }
212604
- if (this.socketMode) {
212605
- await this.socketAPI.sendErrorReportToSocketDashboard(stackTrace, shouldLogSharing, reportId, logContent);
212606
- } else {
212607
- await this.coanaAPI.sendErrorReportToCoanaDashboard(
212608
- apiKey,
212609
- stackTrace,
212610
- shouldLogSharing,
212611
- reportId,
212612
- repoUrl,
212613
- projectName,
212614
- logContent
212615
- );
212468
+ // ../web-compat-utils/src/assertions.ts
212469
+ function assertDefined(value) {
212470
+ if (value === void 0 || value === null) throw new Error("Expected value to be defined");
212471
+ return value;
212472
+ }
212473
+
212474
+ // dist/cli-upgrade-purl.js
212475
+ var import_packageurl_js3 = __toESM(require_packageurl_js(), 1);
212476
+
212477
+ // dist/internal/socket-mode-helpers-socket-dependency-trees.js
212478
+ var import_packageurl_js2 = __toESM(require_packageurl_js(), 1);
212479
+ var import_picomatch4 = __toESM(require_picomatch2(), 1);
212480
+ import { basename as basename10, dirname as dirname13, join as join24, sep as sep5 } from "path";
212481
+ var REQUIREMENTS_FILES_SEARCH_DEPTH2 = 3;
212482
+ function inferWorkspaceFromManifestPath(ecosystem, manifestPath, properPythonProjects) {
212483
+ switch (ecosystem) {
212484
+ case "NPM": {
212485
+ const base = basename10(manifestPath);
212486
+ const dir = dirname13(manifestPath);
212487
+ return base === "package.json" ? dir || "." : void 0;
212616
212488
  }
212617
- }
212618
- async registerSubprojects(subprojects, reportId, apiKey) {
212619
- if (this.disableAnalyticsSharing) {
212620
- return;
212489
+ case "MAVEN": {
212490
+ return ".";
212621
212491
  }
212622
- if (this.socketMode) {
212623
- await this.socketAPI.registerSubprojectsSocket(subprojects, reportId);
212624
- } else {
212625
- await this.coanaAPI.registerSubprojectsCoana(subprojects, reportId, apiKey);
212492
+ case "PIP": {
212493
+ const base = basename10(manifestPath);
212494
+ const dir = dirname13(manifestPath);
212495
+ const workspaceDir = dir === "" ? "." : dir;
212496
+ if (properPythonProjects.includes(workspaceDir)) {
212497
+ return workspaceDir;
212498
+ }
212499
+ if (base === "poetry.lock" || base === "Pipfile.lock" || base === "uv.lock") {
212500
+ return workspaceDir;
212501
+ }
212502
+ if (base.endsWith(".txt")) {
212503
+ const properProjectDirs = properPythonProjects.filter((properProjectDir) => (properProjectDir === "." || workspaceDir === "." || workspaceDir.startsWith(properProjectDir)) && workspaceDir.replace(properProjectDir, "").split(sep5).length <= REQUIREMENTS_FILES_SEARCH_DEPTH2);
212504
+ const longestProperProjectDir = l5(properProjectDirs, [(d4) => d4.length, "desc"]);
212505
+ if (longestProperProjectDir) {
212506
+ return longestProperProjectDir;
212507
+ }
212508
+ return workspaceDir;
212509
+ }
212510
+ logger.warn(`No workspace found for manifest file ${manifestPath}`);
212511
+ return void 0;
212626
212512
  }
212627
- }
212628
- async registerCLIProgress(cliProgressEvent, isStartEvent, reportId, apiKey) {
212629
- if (this.disableAnalyticsSharing) {
212630
- return;
212513
+ case "NUGET": {
212514
+ return ".";
212631
212515
  }
212632
- if (this.socketMode) {
212633
- await this.socketAPI.registerCLIProgressSocket(isStartEvent, cliProgressEvent, reportId);
212634
- } else {
212635
- await this.coanaAPI.registerCLIProgressCoana(cliProgressEvent, isStartEvent, reportId, apiKey);
212516
+ case "RUST": {
212517
+ return dirname13(manifestPath) || ".";
212636
212518
  }
212637
- }
212638
- async registerAnalysisMetadata(subprojectPath, workspacePath, ecosystem, analysisMetadata, reportId, apiKey) {
212639
- if (this.disableAnalyticsSharing) {
212640
- return;
212519
+ case "GO": {
212520
+ const base = basename10(manifestPath);
212521
+ const dir = dirname13(manifestPath);
212522
+ return base === "go.mod" ? dir || "." : void 0;
212641
212523
  }
212642
- if (this.socketMode) {
212643
- await this.socketAPI.registerAnalysisMetadataSocket(
212644
- subprojectPath,
212645
- workspacePath,
212646
- ecosystem,
212647
- analysisMetadata,
212648
- reportId
212649
- );
212650
- } else {
212651
- await this.coanaAPI.registerAnalysisMetadataCoana(
212652
- subprojectPath,
212653
- workspacePath,
212654
- ecosystem,
212655
- analysisMetadata,
212656
- reportId,
212657
- apiKey
212658
- );
212524
+ default: {
212525
+ return ".";
212659
212526
  }
212660
212527
  }
212661
- async getBucketsForLastReport(subprojectPath, workspacePath, ecosystem, reportId, apiKey) {
212662
- if (this.socketMode) {
212663
- return await this.socketAPI.getLatestBucketsSocket(subprojectPath, workspacePath);
212664
- } else {
212665
- return await this.coanaAPI.getBucketsForLastReport(
212666
- subprojectPath,
212667
- workspacePath,
212668
- ecosystem,
212669
- reportId,
212670
- apiKey
212671
- );
212528
+ }
212529
+ function inferProjectFromManifestPath(ecosystem, manifestPath) {
212530
+ switch (ecosystem) {
212531
+ case "NPM": {
212532
+ const filename = basename10(manifestPath);
212533
+ if (["package-lock.json", "pnpm-lock.yaml", "pnpm-lock.yml", "yarn.lock"].includes(filename)) {
212534
+ return dirname13(manifestPath) || ".";
212535
+ }
212536
+ return void 0;
212672
212537
  }
212673
212538
  }
212674
- };
212675
-
212676
- // ../utils/src/promise-queue.ts
212677
- var PromiseQueue = class {
212678
- /*
212679
- * @param maxConcurrency The maximum number of tasks that can run in parallel.
212680
- * @param maxQueueLength The maximum number of tasks that can be queued. If the queue is full, the oldest task is removed.
212681
- */
212682
- constructor(maxConcurrency, maxQueueLength) {
212683
- this.maxConcurrency = maxConcurrency;
212684
- this.maxQueueLength = maxQueueLength;
212685
- if (maxQueueLength && maxQueueLength < 1) {
212686
- throw new Error("maxQueueLength must be at least 1");
212539
+ }
212540
+ function getAllToplevelAncestors(artifactMap, artifactId) {
212541
+ const visited = /* @__PURE__ */ new Set();
212542
+ const toplevelAncestors = /* @__PURE__ */ new Set();
212543
+ function findAncestors(currentId) {
212544
+ if (visited.has(currentId)) {
212545
+ return;
212687
212546
  }
212688
- this.maxConcurrency = maxConcurrency;
212689
- }
212690
- queue = [];
212691
- activeTasks = 0;
212692
- idleResolver = null;
212693
- idleRejector = null;
212694
- error = null;
212695
- async runNextTask() {
212696
- if (this.activeTasks >= this.maxConcurrency) {
212547
+ visited.add(currentId);
212548
+ const artifact = artifactMap.get(currentId);
212549
+ if (!artifact) {
212697
212550
  return;
212698
212551
  }
212699
- const task = this.queue.shift();
212700
- if (task) {
212701
- this.activeTasks++;
212702
- try {
212703
- await task();
212704
- } catch (e) {
212705
- this.error = e;
212706
- } finally {
212707
- this.activeTasks--;
212708
- this.runNextTask();
212709
- this.checkIdle();
212552
+ if (artifact.toplevelAncestors && artifact.toplevelAncestors.length > 0) {
212553
+ for (const ancestorId of artifact.toplevelAncestors) {
212554
+ toplevelAncestors.add(ancestorId);
212555
+ findAncestors(ancestorId);
212710
212556
  }
212711
- } else {
212712
- this.checkIdle();
212713
- }
212714
- }
212715
- checkIdle() {
212716
- if (!this.idleResolver || !this.idleRejector) return;
212717
- const shouldResolve = this.queue.length === 0 && this.activeTasks === 0;
212718
- if (this.error) this.idleRejector(this.error);
212719
- else if (shouldResolve) this.idleResolver();
212720
- const resolvedOrRejected = !!this.error || shouldResolve;
212721
- if (resolvedOrRejected) {
212722
- this.error = null;
212723
- this.idleResolver = null;
212724
- this.idleRejector = null;
212725
212557
  }
212726
212558
  }
212727
- enqueueTask(task) {
212728
- if (this.maxQueueLength && this.queue.length >= this.maxQueueLength) {
212729
- this.queue.shift();
212559
+ findAncestors(artifactId);
212560
+ return Array.from(toplevelAncestors);
212561
+ }
212562
+ async function fetchArtifactsFromSocket(rootWorkingDirectory, manifestsTarHash, mode) {
212563
+ logger.info("Fetching artifacts from Socket backend using manifests tar hash", manifestsTarHash);
212564
+ try {
212565
+ const { artifacts } = await fetchArtifactsFromManifestsTarHash(manifestsTarHash);
212566
+ const properPythonProjects = [];
212567
+ const pipArtifactToRepresentativeManifest = {};
212568
+ for (const artifact of artifacts) {
212569
+ if (artifact.type === "pypi" && artifact.manifestFiles) {
212570
+ pipArtifactToRepresentativeManifest[simplePurl(artifact.type, artifact.namespace ?? "", artifact.name, artifact.version ?? "")] = artifact;
212571
+ }
212730
212572
  }
212731
- this.queue.push(task);
212732
- this.runNextTask();
212733
- }
212734
- async onIdle() {
212735
- return new Promise((resolve36, reject) => {
212736
- if (this.error) {
212737
- reject(this.error);
212738
- this.error = null;
212739
- } else if (this.queue.length === 0 && this.activeTasks === 0) {
212740
- resolve36();
212741
- } else {
212742
- this.idleResolver = resolve36;
212743
- this.idleRejector = reject;
212573
+ const venvExcludes = [
212574
+ "venv",
212575
+ ".venv",
212576
+ "env",
212577
+ ".env",
212578
+ "virtualenv",
212579
+ ".virtualenv",
212580
+ "venvs",
212581
+ ".venvs",
212582
+ "envs",
212583
+ ".envs",
212584
+ "__pycache__",
212585
+ ".tox",
212586
+ ".nox",
212587
+ ".pytest_cache",
212588
+ "site-packages",
212589
+ "dist-packages",
212590
+ "conda-meta",
212591
+ "conda-bld",
212592
+ ".mypy_cache",
212593
+ ".ruff_cache",
212594
+ ".hypothesis"
212595
+ ];
212596
+ const allFiles = await getFilesRelative(rootWorkingDirectory, venvExcludes);
212597
+ for (const file of allFiles) {
212598
+ const base = basename10(file);
212599
+ const workspaceDir = dirname13(file) || ".";
212600
+ if (base === "pyproject.toml" || base === "setup.py" && await isSetupPySetuptools(join24(rootWorkingDirectory, file))) {
212601
+ if (!properPythonProjects.includes(workspaceDir)) {
212602
+ properPythonProjects.push(workspaceDir);
212603
+ }
212744
212604
  }
212745
- });
212746
- }
212747
- };
212748
-
212749
- // ../utils/src/vulnerable-paths-utils.ts
212605
+ }
212606
+ const artifactMap = new Map(artifacts.map((a4) => [a4.id, a4]));
212607
+ const ecosystemToWorkspaceToAnalysisData = {};
212608
+ const ecosystemWorkspaceVulnIds = /* @__PURE__ */ new Set();
212609
+ const ecosystemToWorkspaceToVulnerabilities = {};
212610
+ const purlsFailedToFindWorkspace = /* @__PURE__ */ new Set();
212611
+ for (const artifact of artifacts) {
212612
+ let processToplevelAncestors2 = function(artifact2) {
212613
+ const allAncestorIds = getAllToplevelAncestors(artifactMap, artifact2.id);
212614
+ allAncestorIds.forEach((ancestorId) => artifactMap.get(ancestorId)?.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file)));
212615
+ };
212616
+ var processToplevelAncestors = processToplevelAncestors2;
212617
+ const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
212618
+ if (!ecosystem)
212619
+ continue;
212620
+ const manifestFiles = [];
212621
+ switch (ecosystem) {
212622
+ case "MAVEN": {
212623
+ manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch4.default)("{{*-*.,}pom{.xml,},gradle.lockfile}")(basename10(file))));
212624
+ break;
212625
+ }
212626
+ case "NUGET": {
212627
+ manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch4.default)("{*.csproj,packages.lock.json}")(basename10(file))));
212628
+ break;
212629
+ }
212630
+ case "PIP": {
212631
+ const sPurl = simplePurl(artifact.type, artifact.namespace ?? "", artifact.name, artifact.version ?? "");
212632
+ if (pipArtifactToRepresentativeManifest[sPurl]) {
212633
+ manifestFiles.push(...(pipArtifactToRepresentativeManifest[sPurl].manifestFiles ?? []).map((ref) => ref.file));
212634
+ }
212635
+ processToplevelAncestors2(artifact);
212636
+ break;
212637
+ }
212638
+ default: {
212639
+ artifact.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file));
212640
+ processToplevelAncestors2(artifact);
212641
+ break;
212642
+ }
212643
+ }
212644
+ const workspaceToManifestFiles = {};
212645
+ manifestFiles.forEach((manifestFile) => {
212646
+ const workspace = inferWorkspaceFromManifestPath(ecosystem, manifestFile, properPythonProjects);
212647
+ if (!workspace)
212648
+ return;
212649
+ (workspaceToManifestFiles[workspace] ??= []).push(manifestFile);
212650
+ });
212651
+ if (Object.keys(workspaceToManifestFiles).length === 0) {
212652
+ manifestFiles.forEach((manifestFile) => {
212653
+ const workspace = inferProjectFromManifestPath(ecosystem, manifestFile);
212654
+ if (!workspace)
212655
+ return;
212656
+ (workspaceToManifestFiles[workspace] ??= []).push(manifestFile);
212657
+ });
212658
+ }
212659
+ if (Object.keys(workspaceToManifestFiles).length === 0 && artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
212660
+ const purl = new import_packageurl_js2.PackageURL(artifact.type, artifact.namespace, artifact.name, artifact.version, artifact.qualifiers).toString();
212661
+ purlsFailedToFindWorkspace.add(purl);
212662
+ }
212663
+ for (const [workspace, manifestFiles2] of Object.entries(workspaceToManifestFiles)) {
212664
+ const workspaceData = (ecosystemToWorkspaceToAnalysisData[ecosystem] ??= {})[workspace] ??= {
212665
+ type: "socket",
212666
+ data: {
212667
+ type: ecosystem,
212668
+ manifestFiles: manifestFiles2,
212669
+ artifacts: []
212670
+ }
212671
+ };
212672
+ workspaceData.type;
212673
+ workspaceData.data.artifacts.push(artifact);
212674
+ }
212675
+ if (artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
212676
+ for (const workspace of Object.keys(workspaceToManifestFiles)) {
212677
+ for (const vuln of artifact.vulnerabilities) {
212678
+ const vulnerability = {
212679
+ url: vuln.ghsaId,
212680
+ purlType: artifact.type,
212681
+ range: vuln.range,
212682
+ name: artifact.name ?? "",
212683
+ dependency: artifact.name ?? "",
212684
+ vulnChainDetails: computeVulnChainDetails(artifacts, artifact.id),
212685
+ vulnerabilityAccessPaths: vuln.reachabilityData?.undeterminableReachability ? vuln.reachabilityData.publicComment ?? "" : vuln.reachabilityData?.pattern ?? null,
212686
+ ecosystem,
212687
+ artifactId: artifact.id
212688
+ };
212689
+ const vulnId = `${ecosystem}-${workspace}-${vulnerability.url}`;
212690
+ if (!ecosystemWorkspaceVulnIds.has(vulnId)) {
212691
+ ecosystemWorkspaceVulnIds.add(vulnId);
212692
+ ((ecosystemToWorkspaceToVulnerabilities[ecosystem] ??= {})[workspace] ??= []).push(vulnerability);
212693
+ }
212694
+ }
212695
+ }
212696
+ }
212697
+ }
212698
+ if (purlsFailedToFindWorkspace.size > 0) {
212699
+ logger.warn(`Failed to find workspace for the following purls with vulnerabilities: ${Array.from(purlsFailedToFindWorkspace).join(", ")}.
212700
+ ${mode === "reachability" ? "This means that we will not do a full reachability analysis for these vulnerabilities, but fallback to the results from the pre-computed reachability analysis." : ""}`);
212701
+ }
212702
+ return {
212703
+ artifacts,
212704
+ ecosystemToWorkspaceToAnalysisData,
212705
+ ecosystemToWorkspaceToVulnerabilities
212706
+ };
212707
+ } catch (error) {
212708
+ logger.error("Failed to fetch artifacts from Socket backend", error);
212709
+ throw error;
212710
+ }
212711
+ }
212712
+ function computeVulnChainDetails(artifacts, vulnerableArtifactId) {
212713
+ const artifactMap = new Map(artifacts.map((a4) => [a4.id, a4]));
212714
+ const parentsMap = /* @__PURE__ */ new Map();
212715
+ for (const artifact of artifacts) {
212716
+ if (artifact.dependencies) {
212717
+ for (const depId of artifact.dependencies) {
212718
+ if (!parentsMap.has(depId)) {
212719
+ parentsMap.set(depId, []);
212720
+ }
212721
+ parentsMap.get(depId).push(artifact.id);
212722
+ }
212723
+ }
212724
+ }
212725
+ const res = {
212726
+ packageName: "root",
212727
+ version: "0.0.0",
212728
+ children: [],
212729
+ transitiveDependencies: {}
212730
+ };
212731
+ function addNode(currentId, childId, visited) {
212732
+ if (visited.has(currentId))
212733
+ return;
212734
+ const currentArtifact = artifactMap.get(currentId);
212735
+ if (!currentArtifact)
212736
+ return;
212737
+ const parents4 = parentsMap.get(currentId);
212738
+ const newCurrentNode = {
212739
+ packageName: getNameFromNamespaceAndName(currentArtifact.type, currentArtifact.namespace, currentArtifact.name),
212740
+ version: currentArtifact.version ?? void 0,
212741
+ children: []
212742
+ };
212743
+ res.transitiveDependencies[currentId] = newCurrentNode;
212744
+ if (childId && !newCurrentNode.children.includes(childId)) {
212745
+ newCurrentNode.children.push(childId);
212746
+ }
212747
+ if (currentId === vulnerableArtifactId) {
212748
+ newCurrentNode.vulnerable = true;
212749
+ }
212750
+ if (currentArtifact.direct && !res.children.includes(currentId)) {
212751
+ res.children.push(currentId);
212752
+ }
212753
+ visited.add(currentId);
212754
+ if (parents4) {
212755
+ for (const parentId of parents4) {
212756
+ addNode(parentId, currentId, visited);
212757
+ }
212758
+ }
212759
+ }
212760
+ addNode(vulnerableArtifactId, void 0, /* @__PURE__ */ new Set());
212761
+ return res;
212762
+ }
212763
+
212764
+ // dist/cli-upgrade-purl.js
212765
+ var ECOSYSTEMS_WITH_SOCKET_UPGRADES = ["NPM", "MAVEN", "NUGET", "GO", "RUST"];
212766
+ async function upgradePurl(rootDir, upgrades, options, logFile, cliFixRunId) {
212767
+ if (options.rangeStyle && options.rangeStyle !== "pin") {
212768
+ throw new Error('Range style must be "pin"');
212769
+ }
212770
+ logger.initWinstonLogger(options.debug);
212771
+ logger.silent = options.silent;
212772
+ let cliRunId = cliFixRunId;
212773
+ if (!cliRunId && options.manifestsTarHash) {
212774
+ cliRunId = await getSocketAPI().registerAutofixOrUpgradePurlRun(options.manifestsTarHash, options, "upgrade-purls");
212775
+ }
212776
+ const upgradePurlRunId = cliRunId && await getSocketAPI().registerUpgradePurlRun(cliRunId, upgrades);
212777
+ Spinner.instance({
212778
+ text: "Running Coana Upgrade Purl CLI",
212779
+ isSilent: options.silentSpinner ?? options.silent
212780
+ }).start();
212781
+ try {
212782
+ logger.info(`Upgrading purls for ${rootDir}:
212783
+ ${upgrades.map(({ purl, upgradeVersion }) => ` ${prettyPrintPurlUpgrade(purl, upgradeVersion)}`).join("\n")}`);
212784
+ if (options.manifestsTarHash) {
212785
+ const { supportedUpgrades, unsupportedUpgrades } = upgrades.reduce((acc, upgrade) => {
212786
+ const ecosystem = getAdvisoryEcosystemFromPurl(upgrade.purl);
212787
+ const target = ECOSYSTEMS_WITH_SOCKET_UPGRADES.includes(ecosystem) ? "supportedUpgrades" : "unsupportedUpgrades";
212788
+ acc[target].push(upgrade);
212789
+ return acc;
212790
+ }, { supportedUpgrades: [], unsupportedUpgrades: [] });
212791
+ if (unsupportedUpgrades.length > 0) {
212792
+ logger.warn(`The following upgrades are not supported due to missing support for upgrading their ecosystem: ${unsupportedUpgrades.map(({ purl, upgradeVersion }) => ` ${prettyPrintPurlUpgrade(purl, upgradeVersion)}`).join("\n")}`);
212793
+ }
212794
+ if (supportedUpgrades.length === 0) {
212795
+ return "fixed-none";
212796
+ }
212797
+ try {
212798
+ const purlToUpgradeVersion = new Map(supportedUpgrades.map((upgrade) => [upgrade.purl, upgrade.upgradeVersion]));
212799
+ const [manifestFiles, artifacts] = await Promise.all([
212800
+ fetchManifestFilesFromManifestsTarHash(options.manifestsTarHash),
212801
+ (await fetchArtifactsFromSocket(rootDir, options.manifestsTarHash, "upgrade-purls")).artifacts
212802
+ ]);
212803
+ const ecosystemToSocketArtifactUpgrades = /* @__PURE__ */ new Map();
212804
+ artifacts.forEach((artifact, idx) => {
212805
+ if (!artifact.name)
212806
+ return;
212807
+ if (!artifact.version)
212808
+ return;
212809
+ const purl = new import_packageurl_js3.PackageURL(artifact.type, artifact.namespace, artifact.name, artifact.version, artifact.qualifiers).toString();
212810
+ const upgradeVersion = purlToUpgradeVersion.get(purl);
212811
+ if (!upgradeVersion)
212812
+ return;
212813
+ const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
212814
+ if (!ecosystemToSocketArtifactUpgrades.has(ecosystem)) {
212815
+ ecosystemToSocketArtifactUpgrades.set(ecosystem, /* @__PURE__ */ new Map());
212816
+ }
212817
+ const currentUpgradeVersion = ecosystemToSocketArtifactUpgrades.get(ecosystem).get(idx);
212818
+ if (currentUpgradeVersion === void 0) {
212819
+ ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, upgradeVersion);
212820
+ } else {
212821
+ const versions = sortVersions(ecosystem, [artifact.version, currentUpgradeVersion, upgradeVersion]);
212822
+ if (versionSatisfiesRelation(ecosystem, artifact.version, "=", versions[0])) {
212823
+ ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[versions.length - 1]);
212824
+ } else if (versionSatisfiesRelation(ecosystem, artifact.version, "=", versions[versions.length - 1])) {
212825
+ ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[0]);
212826
+ } else {
212827
+ ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[versions.length - 1]);
212828
+ }
212829
+ }
212830
+ });
212831
+ let anyErrors = false;
212832
+ for (const [ecosystem, upgrades2] of ecosystemToSocketArtifactUpgrades) {
212833
+ if (options.rangeStyle && !["NPM", "MAVEN", "NUGET", "RUST"].includes(ecosystem)) {
212834
+ logger.warn(`Range style is not supported for ${ecosystem}, skipping upgrades`);
212835
+ continue;
212836
+ }
212837
+ const statusUpdater = (update2) => {
212838
+ const statusIcons = {
212839
+ success: "\u2705",
212840
+ skipped: "\u26AA",
212841
+ warn: "\u26A0\uFE0F",
212842
+ error: "\u274C"
212843
+ };
212844
+ logger.info(`${statusIcons[update2.status]} ${update2.message} \u2500 ${relative14(rootDir, resolve32(rootDir, update2.file))}`);
212845
+ update2.artifacts.forEach((idx, i7) => {
212846
+ logger.info(`${" ".repeat(3)}${i7 === update2.artifacts.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${prettyPrintSocketFactArtifactUpgrade(artifacts[idx], upgrades2.get(idx))}`);
212847
+ });
212848
+ for (const detail of update2.details ?? []) {
212849
+ logger.debug(detail);
212850
+ }
212851
+ if (update2.patch)
212852
+ logger.debug(update2.patch);
212853
+ if (update2.status === "error")
212854
+ anyErrors = true;
212855
+ };
212856
+ const ctxt = {
212857
+ manifestFiles,
212858
+ upgrades: upgrades2,
212859
+ artifacts,
212860
+ rangeStyle: options.rangeStyle,
212861
+ statusUpdater
212862
+ };
212863
+ await applySocketUpgrades(ecosystem, rootDir, ctxt);
212864
+ }
212865
+ if (upgradePurlRunId) {
212866
+ await getSocketAPI().finalizeUpgradePurlRun(upgradePurlRunId, "succeeded");
212867
+ }
212868
+ return unsupportedUpgrades.length === 0 && !anyErrors ? "fixed-all" : "fixed-some";
212869
+ } catch (error) {
212870
+ if (upgradePurlRunId) {
212871
+ await getSocketAPI().finalizeUpgradePurlRun(
212872
+ upgradePurlRunId,
212873
+ "error",
212874
+ !cliFixRunId ? error.stack : void 0,
212875
+ // do not send stack trace and logContent for computeFixes runs, as that will be handled by that command.
212876
+ !cliFixRunId && logFile ? await logger.getLogContent(logFile) : void 0
212877
+ );
212878
+ }
212879
+ throw error;
212880
+ }
212881
+ }
212882
+ const otherModulesCommunicator = new OtherModulesCommunicator(rootDir, options, {
212883
+ type: "missing"
212884
+ });
212885
+ const ecosystems = upgrades.map((upgrade) => getAdvisoryEcosystemFromPurl(upgrade.purl));
212886
+ const manager = await ProjectManager.create(rootDir, otherModulesCommunicator, ecosystems);
212887
+ const { reachabilitySupport, traditionalScaSupport } = manager.getSubprojectsWithWorkspacePaths();
212888
+ const supportedSubprojects = reachabilitySupport.concat(traditionalScaSupport).filter((p3) => getPackageManagerSupport(p3.packageManagerName).supportsApplyingFixes);
212889
+ if (supportedSubprojects.length === 0) {
212890
+ throw new Error(`No supported projects found in ${rootDir}.`);
212891
+ }
212892
+ const subprojectPromiseQueue = new PromiseQueue(Number(options.concurrency));
212893
+ supportedSubprojects.forEach((subproject) => {
212894
+ subprojectPromiseQueue.enqueueTask(async () => {
212895
+ const workspacePathsMatchingGlob = subproject.workspacePaths.filter((wsPath) => minimatch(join25(subproject.subprojectPath, wsPath), options.globPattern ?? "**"));
212896
+ if (workspacePathsMatchingGlob.length === 0)
212897
+ return;
212898
+ logger.info(`Found workspaces for subproject ${subproject.subprojectPath}${options.globPattern ? `matching glob ${options.globPattern}` : ""}:
212899
+ ${workspacePathsMatchingGlob.map((wsPath) => ` ${wsPath}`).join("\n")}`);
212900
+ const fixingData = await otherModulesCommunicator.getFixingData(subproject.packageManagerName, subproject.subprojectPath, workspacePathsMatchingGlob);
212901
+ const workspaceToFixes = {};
212902
+ Object.entries(fixingData.dependencyTrees).forEach(([wsPath, depTree]) => {
212903
+ const vulnerabilityFixes = [];
212904
+ const simplePurlToDepId = getPurlStrings(depTree);
212905
+ upgrades.forEach((upgrade) => {
212906
+ const purl = import_packageurl_js3.PackageURL.fromString(upgrade.purl);
212907
+ if (purl.version === void 0)
212908
+ throw Error(`Undefined version for purl ${upgrade.purl}`);
212909
+ const simplePurl2 = `pkg:${purl.type}/${purl.namespace ? `${purl.namespace}/` : ""}${purl.name}${purl.version ? `@${purl.version}` : ""}`;
212910
+ for (const depIdMatchingPurl of simplePurlToDepId[simplePurl2] ?? []) {
212911
+ const node = depTree.transitiveDependencies[depIdMatchingPurl];
212912
+ if (!node)
212913
+ throw Error("should not happen!");
212914
+ vulnerabilityFixes.push({
212915
+ dependencyName: node.packageName,
212916
+ currentVersion: assertDefined(node.version),
212917
+ dependencyIdentifier: depIdMatchingPurl,
212918
+ fixedVersion: upgrade.upgradeVersion
212919
+ });
212920
+ }
212921
+ });
212922
+ if (vulnerabilityFixes.length === 0)
212923
+ return;
212924
+ logger.info(`Found ${vulnerabilityFixes.length} ${vulnerabilityFixes.length === 1 ? "dependency" : "dependencies"} matching upgrade specs for ${join25(subproject.subprojectPath, wsPath)}`);
212925
+ workspaceToFixes[wsPath] = [
212926
+ {
212927
+ fixId: "dummy",
212928
+ vulnerabilityFixes
212929
+ }
212930
+ ];
212931
+ });
212932
+ if (Object.entries(workspaceToFixes).length === 0) {
212933
+ logger.info(`No dependencies matching upgrade specs found for subproject ${subproject.subprojectPath}`);
212934
+ return;
212935
+ }
212936
+ await applySecurityFixes(subproject.packageManagerName, rootDir, relative14(rootDir, subproject.subprojectPath) || ".", otherModulesCommunicator, workspaceToFixes, fixingData, signalFixApplied);
212937
+ });
212938
+ });
212939
+ await subprojectPromiseQueue.onIdle();
212940
+ } finally {
212941
+ Spinner.instance().stop();
212942
+ }
212943
+ }
212944
+ var signalFixApplied = (_fixId, subprojectPath, workspacePath, vulnerabilityFixes) => {
212945
+ logger.info(`Successfully upgraded purls for: ${join25(subprojectPath, workspacePath)}`);
212946
+ logger.info(`Upgraded:
212947
+ ${vulnerabilityFixes.map((fix) => ` ${fix.dependencyName} from ${fix.currentVersion} to ${fix.fixedVersion}`).join("\n")}`);
212948
+ };
212949
+
212950
+ // dist/cli-compute-fixes-and-upgrade-purls.js
212951
+ async function computeFixesAndUpgradePurls(path2, options, logFile) {
212952
+ const autofixRunId = options.manifestsTarHash && await getSocketAPI().registerAutofixOrUpgradePurlRun(options.manifestsTarHash, options, "autofix");
212953
+ const { artifacts, ghsaToVulnerableArtifactIds } = await computeInputForComputingFixes(path2, options);
212954
+ if (Object.keys(ghsaToVulnerableArtifactIds).length === 0) {
212955
+ logger.info("No vulnerabilities to compute fixes for");
212956
+ return { type: "no-vulnerabilities-found" };
212957
+ }
212958
+ if (options.applyFixesTo.length === 0) {
212959
+ logger.info("Vulnerabilities found:", Object.keys(ghsaToVulnerableArtifactIds).join(", "));
212960
+ logger.info("Run again with --apply-fixes-to GHSA_IDS to fix those vulnerabilities by computing packages to upgrade and apply them");
212961
+ return { type: "no-ghsas-fix-requested", ghsas: Object.keys(ghsaToVulnerableArtifactIds) };
212962
+ }
212963
+ const ghsaToVulnerableArtifactIdsToApply = options.applyFixesTo.includes("all") ? ghsaToVulnerableArtifactIds : Object.fromEntries(Object.entries(ghsaToVulnerableArtifactIds).filter(([ghsa]) => options.applyFixesTo.includes(ghsa)));
212964
+ const computedFix = await useSocketComputeFixEndpoint(autofixRunId, artifacts, ghsaToVulnerableArtifactIdsToApply, {
212965
+ noMajorUpdates: options.disableMajorUpdates,
212966
+ minimumReleaseAgeInMinutes: options.minimumReleaseAgeInMinutes
212967
+ });
212968
+ if (computedFix.type !== "success") {
212969
+ throw new Error(`No fix found for the given vulnerabilities`);
212970
+ }
212971
+ const ghsasFailedToFix = Object.keys(ghsaToVulnerableArtifactIdsToApply).filter((ghsa) => {
212972
+ const artifactIds = ghsaToVulnerableArtifactIdsToApply[ghsa];
212973
+ if (!artifactIds)
212974
+ return false;
212975
+ return artifactIds.some((artifactId) => computedFix.ghsaToResult[ghsa].failedArtifacts?.includes(artifactId));
212976
+ });
212977
+ if (ghsasFailedToFix.length > 0) {
212978
+ logger.info("Failed to compute fixes for the following vulnerabilities:");
212979
+ }
212980
+ for (const ghsa of ghsasFailedToFix) {
212981
+ logger.info(` - ${ghsa} (${ghsaToVulnerableArtifactIdsToApply[ghsa].map((id) => simplePurl(artifacts[id].type, artifacts[id].namespace ?? null, artifacts[id].name ?? "", artifacts[id].version ?? null)).join(", ")})`);
212982
+ }
212983
+ const fixesFound = Object.entries(computedFix.ghsaToResult).filter(([_, result]) => result.failedArtifacts === void 0 || result.failedArtifacts.length === 0);
212984
+ if (options.onlyDirectDependencyUpgrades) {
212985
+ return computeDirectDependencyUpgrades(artifacts, fixesFound);
212986
+ }
212987
+ const combinedFixes = fixesFound.flatMap(([_, result]) => result.fixes);
212988
+ if (options.dryRun) {
212989
+ logger.info("Fixes found:");
212990
+ for (const [ghsa, result] of fixesFound) {
212991
+ logger.info(` - ${ghsa}:`);
212992
+ for (const fix of result.fixes) {
212993
+ logger.info(` - ${fix.purl} -> ${fix.fixedVersion}`);
212994
+ }
212995
+ }
212996
+ return {
212997
+ type: "dry-run-result",
212998
+ fixes: Object.fromEntries(fixesFound.map(([ghsa, result]) => [ghsa, result.fixes])),
212999
+ ...ghsasFailedToFix.length > 0 && { failedToFix: ghsasFailedToFix }
213000
+ };
213001
+ }
213002
+ if (combinedFixes.length === 0) {
213003
+ if (autofixRunId) {
213004
+ await getSocketAPI().finalizeAutofixRun(autofixRunId, "fixed-none");
213005
+ }
213006
+ throw new Error("Failed to find a fix for the given vulnerabilities");
213007
+ }
213008
+ try {
213009
+ const applyFixesStatus = await upgradePurl(path2, T3(combinedFixes, (fix) => `${fix.purl}${fix.fixedVersion}`).map((fix) => ({
213010
+ purl: fix.purl,
213011
+ upgradeVersion: fix.fixedVersion
213012
+ })), {
213013
+ debug: options.debug,
213014
+ silent: options.silent,
213015
+ runWithoutDocker: options.runWithoutDocker,
213016
+ manifestsTarHash: options.manifestsTarHash,
213017
+ concurrency: "1",
213018
+ globPattern: options.globPattern,
213019
+ rangeStyle: options.rangeStyle
213020
+ }, void 0, autofixRunId) ?? "fixed-all";
213021
+ if (autofixRunId) {
213022
+ 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");
213023
+ }
213024
+ return {
213025
+ type: "applied-fixes",
213026
+ fixes: Object.fromEntries(fixesFound.map(([ghsa, result]) => [ghsa, result.fixes]))
213027
+ };
213028
+ } catch (error) {
213029
+ if (autofixRunId) {
213030
+ await getSocketAPI().finalizeAutofixRun(autofixRunId, "error", error.stack, await logger.getLogContent(logFile));
213031
+ }
213032
+ logger.error("Error applying fixes:", error);
213033
+ throw error;
213034
+ }
213035
+ }
213036
+ async function computeInputForComputingFixes(path2, options) {
213037
+ if (options.manifestsTarHash) {
213038
+ const { artifacts } = await fetchArtifactsFromSocket(path2, options.manifestsTarHash, "autofix");
213039
+ const ghsaToVulnerableArtifactIds = {};
213040
+ for (const [index2, artifact] of artifacts.entries()) {
213041
+ if (!artifact.vulnerabilities)
213042
+ continue;
213043
+ for (const vulnerability of artifact.vulnerabilities) {
213044
+ if (!(ghsaToVulnerableArtifactIds[vulnerability.ghsaId] ??= []).includes(index2)) {
213045
+ ghsaToVulnerableArtifactIds[vulnerability.ghsaId].push(index2);
213046
+ }
213047
+ }
213048
+ }
213049
+ const sbomTaskArtifacts = artifacts.map((artifact) => ({
213050
+ type: artifact.type,
213051
+ name: artifact.name ?? "",
213052
+ version: artifact.version ?? "",
213053
+ namespace: artifact.namespace ?? void 0,
213054
+ adj: artifact.dependencies?.map((dep) => artifacts.findIndex((a4) => a4.id === dep)) ?? [],
213055
+ direct: artifact.direct,
213056
+ topLevelAncestors: artifact.toplevelAncestors?.map((ancestor) => artifacts.findIndex((a4) => a4.id === ancestor)) ?? []
213057
+ }));
213058
+ return { artifacts: sbomTaskArtifacts, ghsaToVulnerableArtifactIds };
213059
+ }
213060
+ throw new Error("Fixes are only supported when using --manifests-tar-hash");
213061
+ }
213062
+ async function computeDirectDependencyUpgrades(artifacts, fixesFound) {
213063
+ const purlToArtifact = Object.fromEntries(artifacts.map((a4) => [simplePurl(a4.type, a4.namespace ?? null, a4.name ?? "", a4.version ?? null), a4]));
213064
+ const packageFixes = {};
213065
+ for (const [ghsa, result2] of fixesFound) {
213066
+ const directUpdates = {};
213067
+ for (const directFix of result2.fixes.filter((fix) => purlToArtifact[fix.purl]?.direct)) {
213068
+ directUpdates[directFix.purl] = { fixedVersion: directFix.fixedVersion };
213069
+ }
213070
+ const directUpdatePurls = Object.keys(directUpdates);
213071
+ for (const indirectFix of result2.fixes.filter((fix) => !purlToArtifact[fix.purl]?.direct)) {
213072
+ const directDependencies = purlToArtifact[indirectFix.purl]?.topLevelAncestors;
213073
+ for (const directDependency of directDependencies) {
213074
+ const artifact = artifacts[directDependency];
213075
+ const purl = simplePurl(artifact.type, artifact.namespace ?? null, artifact.name ?? "", artifact.version ?? null);
213076
+ if (directUpdatePurls.includes(purl))
213077
+ continue;
213078
+ if (directUpdates[purl]) {
213079
+ (directUpdates[purl].transitiveFixes ??= []).push(indirectFix);
213080
+ } else {
213081
+ directUpdates[purl] = { transitiveFixes: [indirectFix] };
213082
+ }
213083
+ directUpdates[purl] = { transitiveFixes: [indirectFix] };
213084
+ }
213085
+ }
213086
+ packageFixes[ghsa] = {
213087
+ directDependencies: Object.entries(directUpdates).map(([purl, update2]) => ({ purl, ...update2 }))
213088
+ };
213089
+ }
213090
+ const result = {
213091
+ type: "only-direct-dependency-upgrades",
213092
+ fixes: packageFixes
213093
+ };
213094
+ logger.info("Affected direct dependencies and upgrades to fix (--show-affected-direct-dependencies does not apply the upgrades):", JSON.stringify(result, null, 2));
213095
+ return result;
213096
+ }
213097
+
213098
+ // dist/cli-core.js
213099
+ import { writeFileSync as writeFileSync3 } from "fs";
213100
+ import { mkdir as mkdir2, writeFile as writeFile10 } from "fs/promises";
213101
+
213102
+ // ../../node_modules/.pnpm/kleur@4.1.5/node_modules/kleur/index.mjs
213103
+ var FORCE_COLOR;
213104
+ var NODE_DISABLE_COLORS;
213105
+ var NO_COLOR;
213106
+ var TERM;
213107
+ var isTTY = true;
213108
+ if (typeof process !== "undefined") {
213109
+ ({ FORCE_COLOR, NODE_DISABLE_COLORS, NO_COLOR, TERM } = process.env || {});
213110
+ isTTY = process.stdout && process.stdout.isTTY;
213111
+ }
213112
+ var $ = {
213113
+ enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== "dumb" && (FORCE_COLOR != null && FORCE_COLOR !== "0" || isTTY),
213114
+ // modifiers
213115
+ reset: init(0, 0),
213116
+ bold: init(1, 22),
213117
+ dim: init(2, 22),
213118
+ italic: init(3, 23),
213119
+ underline: init(4, 24),
213120
+ inverse: init(7, 27),
213121
+ hidden: init(8, 28),
213122
+ strikethrough: init(9, 29),
213123
+ // colors
213124
+ black: init(30, 39),
213125
+ red: init(31, 39),
213126
+ green: init(32, 39),
213127
+ yellow: init(33, 39),
213128
+ blue: init(34, 39),
213129
+ magenta: init(35, 39),
213130
+ cyan: init(36, 39),
213131
+ white: init(37, 39),
213132
+ gray: init(90, 39),
213133
+ grey: init(90, 39),
213134
+ // background colors
213135
+ bgBlack: init(40, 49),
213136
+ bgRed: init(41, 49),
213137
+ bgGreen: init(42, 49),
213138
+ bgYellow: init(43, 49),
213139
+ bgBlue: init(44, 49),
213140
+ bgMagenta: init(45, 49),
213141
+ bgCyan: init(46, 49),
213142
+ bgWhite: init(47, 49)
213143
+ };
213144
+ function run(arr, str) {
213145
+ let i7 = 0, tmp, beg = "", end2 = "";
213146
+ for (; i7 < arr.length; i7++) {
213147
+ tmp = arr[i7];
213148
+ beg += tmp.open;
213149
+ end2 += tmp.close;
213150
+ if (!!~str.indexOf(tmp.close)) {
213151
+ str = str.replace(tmp.rgx, tmp.close + tmp.open);
213152
+ }
213153
+ }
213154
+ return beg + str + end2;
213155
+ }
213156
+ function chain(has2, keys) {
213157
+ let ctx = { has: has2, keys };
213158
+ ctx.reset = $.reset.bind(ctx);
213159
+ ctx.bold = $.bold.bind(ctx);
213160
+ ctx.dim = $.dim.bind(ctx);
213161
+ ctx.italic = $.italic.bind(ctx);
213162
+ ctx.underline = $.underline.bind(ctx);
213163
+ ctx.inverse = $.inverse.bind(ctx);
213164
+ ctx.hidden = $.hidden.bind(ctx);
213165
+ ctx.strikethrough = $.strikethrough.bind(ctx);
213166
+ ctx.black = $.black.bind(ctx);
213167
+ ctx.red = $.red.bind(ctx);
213168
+ ctx.green = $.green.bind(ctx);
213169
+ ctx.yellow = $.yellow.bind(ctx);
213170
+ ctx.blue = $.blue.bind(ctx);
213171
+ ctx.magenta = $.magenta.bind(ctx);
213172
+ ctx.cyan = $.cyan.bind(ctx);
213173
+ ctx.white = $.white.bind(ctx);
213174
+ ctx.gray = $.gray.bind(ctx);
213175
+ ctx.grey = $.grey.bind(ctx);
213176
+ ctx.bgBlack = $.bgBlack.bind(ctx);
213177
+ ctx.bgRed = $.bgRed.bind(ctx);
213178
+ ctx.bgGreen = $.bgGreen.bind(ctx);
213179
+ ctx.bgYellow = $.bgYellow.bind(ctx);
213180
+ ctx.bgBlue = $.bgBlue.bind(ctx);
213181
+ ctx.bgMagenta = $.bgMagenta.bind(ctx);
213182
+ ctx.bgCyan = $.bgCyan.bind(ctx);
213183
+ ctx.bgWhite = $.bgWhite.bind(ctx);
213184
+ return ctx;
213185
+ }
213186
+ function init(open, close) {
213187
+ let blk = {
213188
+ open: `\x1B[${open}m`,
213189
+ close: `\x1B[${close}m`,
213190
+ rgx: new RegExp(`\\x1b\\[${close}m`, "g")
213191
+ };
213192
+ return function(txt) {
213193
+ if (this !== void 0 && this.has !== void 0) {
213194
+ !!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));
213195
+ return txt === void 0 ? this : $.enabled ? run(this.keys, txt + "") : txt + "";
213196
+ }
213197
+ return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt + "") : txt + "";
213198
+ };
213199
+ }
213200
+ var kleur_default = $;
213201
+
213202
+ // ../../node_modules/.pnpm/yoctocolors@2.1.2/node_modules/yoctocolors/base.js
213203
+ import tty from "node:tty";
213204
+ var hasColors = tty?.WriteStream?.prototype?.hasColors?.() ?? false;
213205
+ var format5 = (open, close) => {
213206
+ if (!hasColors) {
213207
+ return (input) => input;
213208
+ }
213209
+ const openCode = `\x1B[${open}m`;
213210
+ const closeCode = `\x1B[${close}m`;
213211
+ return (input) => {
213212
+ const string = input + "";
213213
+ let index2 = string.indexOf(closeCode);
213214
+ if (index2 === -1) {
213215
+ return openCode + string + closeCode;
213216
+ }
213217
+ let result = openCode;
213218
+ let lastIndex = 0;
213219
+ const reopenOnNestedClose = close === 22;
213220
+ const replaceCode = (reopenOnNestedClose ? closeCode : "") + openCode;
213221
+ while (index2 !== -1) {
213222
+ result += string.slice(lastIndex, index2) + replaceCode;
213223
+ lastIndex = index2 + closeCode.length;
213224
+ index2 = string.indexOf(closeCode, lastIndex);
213225
+ }
213226
+ result += string.slice(lastIndex) + closeCode;
213227
+ return result;
213228
+ };
213229
+ };
213230
+ var reset = format5(0, 0);
213231
+ var bold = format5(1, 22);
213232
+ var dim = format5(2, 22);
213233
+ var italic = format5(3, 23);
213234
+ var underline = format5(4, 24);
213235
+ var overline = format5(53, 55);
213236
+ var inverse = format5(7, 27);
213237
+ var hidden = format5(8, 28);
213238
+ var strikethrough = format5(9, 29);
213239
+ var black = format5(30, 39);
213240
+ var red = format5(31, 39);
213241
+ var green = format5(32, 39);
213242
+ var yellow = format5(33, 39);
213243
+ var blue = format5(34, 39);
213244
+ var magenta = format5(35, 39);
213245
+ var cyan = format5(36, 39);
213246
+ var white = format5(37, 39);
213247
+ var gray = format5(90, 39);
213248
+ var bgBlack = format5(40, 49);
213249
+ var bgRed = format5(41, 49);
213250
+ var bgGreen = format5(42, 49);
213251
+ var bgYellow = format5(43, 49);
213252
+ var bgBlue = format5(44, 49);
213253
+ var bgMagenta = format5(45, 49);
213254
+ var bgCyan = format5(46, 49);
213255
+ var bgWhite = format5(47, 49);
213256
+ var bgGray = format5(100, 49);
213257
+ var redBright = format5(91, 39);
213258
+ var greenBright = format5(92, 39);
213259
+ var yellowBright = format5(93, 39);
213260
+ var blueBright = format5(94, 39);
213261
+ var magentaBright = format5(95, 39);
213262
+ var cyanBright = format5(96, 39);
213263
+ var whiteBright = format5(97, 39);
213264
+ var bgRedBright = format5(101, 49);
213265
+ var bgGreenBright = format5(102, 49);
213266
+ var bgYellowBright = format5(103, 49);
213267
+ var bgBlueBright = format5(104, 49);
213268
+ var bgMagentaBright = format5(105, 49);
213269
+ var bgCyanBright = format5(106, 49);
213270
+ var bgWhiteBright = format5(107, 49);
213271
+
213272
+ // dist/cli-core.js
213273
+ var import_lodash15 = __toESM(require_lodash(), 1);
213274
+ import os from "os";
213275
+ import { join as join27, relative as relative15, resolve as resolve34 } from "path";
213276
+
213277
+ // ../utils/src/dashboard-api/shared-api.ts
213278
+ var DashboardAPI = class {
213279
+ socketMode;
213280
+ coanaAPI;
213281
+ socketAPI;
213282
+ disableAnalyticsSharing;
213283
+ constructor(socketMode, disableAnalyticsSharing) {
213284
+ this.socketMode = socketMode;
213285
+ this.disableAnalyticsSharing = disableAnalyticsSharing;
213286
+ this.coanaAPI = getCoanaAPI();
213287
+ this.socketAPI = getSocketAPI();
213288
+ }
213289
+ async createReport(repoUrl, projectName, cliVersion, commitSha, branchName, cliOptions, apiKey, cliRunEnv) {
213290
+ if (this.disableAnalyticsSharing) {
213291
+ return;
213292
+ }
213293
+ if (this.socketMode) {
213294
+ return (await this.socketAPI.createSocketTier1Scan(cliOptions, cliVersion)).tier1_reachability_scan_id;
213295
+ } else {
213296
+ return await this.coanaAPI.createCoanaReport(
213297
+ repoUrl,
213298
+ projectName,
213299
+ cliVersion,
213300
+ commitSha,
213301
+ branchName,
213302
+ cliOptions,
213303
+ apiKey,
213304
+ cliRunEnv
213305
+ );
213306
+ }
213307
+ }
213308
+ async sendErrorReport(apiKey, stackTrace, shouldLogSharing, reportId, repoUrl, projectName, logContent) {
213309
+ if (this.disableAnalyticsSharing) {
213310
+ return;
213311
+ }
213312
+ if (this.socketMode) {
213313
+ await this.socketAPI.sendErrorReportToSocketDashboard(stackTrace, shouldLogSharing, reportId, logContent);
213314
+ } else {
213315
+ await this.coanaAPI.sendErrorReportToCoanaDashboard(
213316
+ apiKey,
213317
+ stackTrace,
213318
+ shouldLogSharing,
213319
+ reportId,
213320
+ repoUrl,
213321
+ projectName,
213322
+ logContent
213323
+ );
213324
+ }
213325
+ }
213326
+ async registerSubprojects(subprojects, reportId, apiKey) {
213327
+ if (this.disableAnalyticsSharing) {
213328
+ return;
213329
+ }
213330
+ if (this.socketMode) {
213331
+ await this.socketAPI.registerSubprojectsSocket(subprojects, reportId);
213332
+ } else {
213333
+ await this.coanaAPI.registerSubprojectsCoana(subprojects, reportId, apiKey);
213334
+ }
213335
+ }
213336
+ async registerCLIProgress(cliProgressEvent, isStartEvent, reportId, apiKey) {
213337
+ if (this.disableAnalyticsSharing) {
213338
+ return;
213339
+ }
213340
+ if (this.socketMode) {
213341
+ await this.socketAPI.registerCLIProgressSocket(isStartEvent, cliProgressEvent, reportId);
213342
+ } else {
213343
+ await this.coanaAPI.registerCLIProgressCoana(cliProgressEvent, isStartEvent, reportId, apiKey);
213344
+ }
213345
+ }
213346
+ async registerAnalysisMetadata(subprojectPath, workspacePath, ecosystem, analysisMetadata, reportId, apiKey) {
213347
+ if (this.disableAnalyticsSharing) {
213348
+ return;
213349
+ }
213350
+ if (this.socketMode) {
213351
+ await this.socketAPI.registerAnalysisMetadataSocket(
213352
+ subprojectPath,
213353
+ workspacePath,
213354
+ ecosystem,
213355
+ analysisMetadata,
213356
+ reportId
213357
+ );
213358
+ } else {
213359
+ await this.coanaAPI.registerAnalysisMetadataCoana(
213360
+ subprojectPath,
213361
+ workspacePath,
213362
+ ecosystem,
213363
+ analysisMetadata,
213364
+ reportId,
213365
+ apiKey
213366
+ );
213367
+ }
213368
+ }
213369
+ async getBucketsForLastReport(subprojectPath, workspacePath, ecosystem, reportId, apiKey) {
213370
+ if (this.socketMode) {
213371
+ return await this.socketAPI.getLatestBucketsSocket(subprojectPath, workspacePath);
213372
+ } else {
213373
+ return await this.coanaAPI.getBucketsForLastReport(
213374
+ subprojectPath,
213375
+ workspacePath,
213376
+ ecosystem,
213377
+ reportId,
213378
+ apiKey
213379
+ );
213380
+ }
213381
+ }
213382
+ };
213383
+
213384
+ // ../utils/src/vulnerable-paths-utils.ts
212750
213385
  function mkTrie() {
212751
213386
  return { children: {}, leaf: false };
212752
213387
  }
@@ -212885,13 +213520,13 @@ var DEFAULT_REPORT_FILENAME_BASE = "coana-report";
212885
213520
  // dist/internal/exclude-dirs-from-configuration-files.js
212886
213521
  import { existsSync as existsSync20 } from "fs";
212887
213522
  import { readFile as readFile27 } from "fs/promises";
212888
- import { basename as basename10, resolve as resolve32 } from "path";
213523
+ import { basename as basename11, resolve as resolve33 } from "path";
212889
213524
  var import_yaml2 = __toESM(require_dist11(), 1);
212890
213525
  async function inferExcludeDirsFromConfigurationFiles(rootWorkingDir) {
212891
- const socketYmlConfigFile = resolve32(rootWorkingDir, "socket.yml");
213526
+ const socketYmlConfigFile = resolve33(rootWorkingDir, "socket.yml");
212892
213527
  if (existsSync20(socketYmlConfigFile))
212893
213528
  return inferExcludeDirsFromSocketConfig(socketYmlConfigFile);
212894
- const socketYamlConfigFile = resolve32(rootWorkingDir, "socket.yaml");
213529
+ const socketYamlConfigFile = resolve33(rootWorkingDir, "socket.yaml");
212895
213530
  if (existsSync20(socketYamlConfigFile))
212896
213531
  return inferExcludeDirsFromSocketConfig(socketYamlConfigFile);
212897
213532
  return void 0;
@@ -212905,398 +213540,111 @@ async function inferExcludeDirsFromSocketConfig(socketConfigFile) {
212905
213540
  return void 0;
212906
213541
  if (ignorePaths.some((ignorePath) => ignorePath.includes("!")))
212907
213542
  return void 0;
212908
- logger.info(`Inferring paths to exclude based on Socket config file: ${basename10(socketConfigFile)}`);
212909
- return config3.projectIgnorePaths;
212910
- } catch (e) {
212911
- return void 0;
212912
- }
212913
- }
212914
-
212915
- // dist/internal/socket-mode-helpers-coana-dependency-trees.js
212916
- var ROOT_IDENTIFIER = "ROOT";
212917
- async function scanForVulnerabilitiesSocketMode(dependencyTree) {
212918
- if (!dependencyTree.ecosystem)
212919
- dependencyTree.ecosystem = "NPM";
212920
- const purlStringsToIdentifier = getPurlStrings(dependencyTree);
212921
- const components = await augmentArtifactsWithVulnerabilities(Object.keys(purlStringsToIdentifier).map((purl) => ({ purl })));
212922
- const parentsMap = /* @__PURE__ */ new Map();
212923
- for (const [depId, node] of [
212924
- ...Object.entries(dependencyTree.transitiveDependencies),
212925
- [ROOT_IDENTIFIER, dependencyTree]
212926
- ]) {
212927
- for (const childId of node.dependencies ?? []) {
212928
- if (!parentsMap.has(childId)) {
212929
- parentsMap.set(childId, []);
212930
- }
212931
- parentsMap.get(childId).push(depId);
212932
- }
212933
- }
212934
- const vulnerabilities = [];
212935
- const dependencyIdentifiersNotFound = new Set(Object.keys(dependencyTree.transitiveDependencies));
212936
- for (const c3 of components) {
212937
- let simplePurlForComponent = simplePurl(c3.purl_type, c3.namespace, c3.name, c3.version);
212938
- if (!(simplePurlForComponent in purlStringsToIdentifier))
212939
- simplePurlForComponent = simplePurl(c3.purl_type, c3.namespace, c3.name, null);
212940
- const dependencyIdentifiers = purlStringsToIdentifier[simplePurlForComponent];
212941
- for (const dependencyIdentifier of dependencyIdentifiers) {
212942
- dependencyIdentifiersNotFound.delete(dependencyIdentifier);
212943
- const dependencyTreeNode = dependencyTree.transitiveDependencies[dependencyIdentifier];
212944
- if (!dependencyTreeNode)
212945
- throw new Error(`Dependency tree does not contain dependency ${simplePurlForComponent}`);
212946
- dependencyTreeNode.purlObj = {
212947
- type: c3.purl_type,
212948
- namespace: c3.namespace ?? void 0,
212949
- name: c3.name,
212950
- version: c3.version ?? void 0,
212951
- subpath: c3.subpath ?? void 0,
212952
- artifactId: c3.artifactId ?? void 0,
212953
- artifact_id: c3.artifact_id ?? void 0,
212954
- qualifiers: c3.qualifiers ?? void 0,
212955
- purlString: c3.purl
212956
- };
212957
- for (const vulnerability of c3.vulnerabilities) {
212958
- vulnerabilities.push({
212959
- url: vulnerability.ghsaId,
212960
- purl: c3.purl,
212961
- purlType: c3.purl_type,
212962
- range: vulnerability.range,
212963
- name: dependencyTreeNode.packageName,
212964
- dependency: dependencyTreeNode.packageName,
212965
- vulnChainDetails: computeVulnChainDetails(dependencyTree, dependencyIdentifier, parentsMap),
212966
- vulnerabilityAccessPaths: vulnerability.reachabilityData?.pattern ?? null,
212967
- ecosystem: dependencyTree.ecosystem
212968
- });
212969
- }
212970
- }
212971
- }
212972
- for (const dependencyIdentifier of dependencyIdentifiersNotFound) {
212973
- logger.warn(`Dependency ${dependencyIdentifier} not found in Socket mode`, dependencyTree.transitiveDependencies[dependencyIdentifier]);
212974
- }
212975
- return vulnerabilities;
212976
- }
212977
- function computeVulnChainDetails(dependencyTree, dependencyIdentifier, parentsMap) {
212978
- const res = {
212979
- packageName: "root",
212980
- version: "0.0.0",
212981
- children: [],
212982
- transitiveDependencies: {}
212983
- };
212984
- function addNode(currentIdentifier, childIdentifier, visited) {
212985
- if (visited.has(currentIdentifier))
212986
- return;
212987
- const parents4 = parentsMap.get(currentIdentifier);
212988
- const newCurrentNode = transformToVulnChainNode(dependencyTree.transitiveDependencies[currentIdentifier]);
212989
- res.transitiveDependencies[currentIdentifier] = newCurrentNode;
212990
- if (childIdentifier && !newCurrentNode.children.includes(childIdentifier))
212991
- newCurrentNode.children.push(childIdentifier);
212992
- if (!childIdentifier)
212993
- newCurrentNode.vulnerable = true;
212994
- if (!parents4)
212995
- return res;
212996
- visited.add(currentIdentifier);
212997
- for (const parent2 of parents4) {
212998
- if (parent2 === ROOT_IDENTIFIER)
212999
- res.children.push(currentIdentifier);
213000
- else
213001
- addNode(parent2, currentIdentifier, visited);
213002
- }
213003
- }
213004
- addNode(dependencyIdentifier, void 0, /* @__PURE__ */ new Set());
213005
- return res;
213006
- }
213007
- function transformToVulnChainNode(dependencyTree) {
213008
- return {
213009
- ...a3(dependencyTree, ["packageName", "version"]),
213010
- children: []
213011
- };
213012
- }
213013
-
213014
- // dist/internal/socket-mode-helpers-socket-dependency-trees.js
213015
- var import_packageurl_js2 = __toESM(require_packageurl_js(), 1);
213016
- var import_picomatch4 = __toESM(require_picomatch2(), 1);
213017
- import { basename as basename11, dirname as dirname13, join as join24, sep as sep5 } from "path";
213018
- var REQUIREMENTS_FILES_SEARCH_DEPTH2 = 3;
213019
- function inferWorkspaceFromManifestPath(ecosystem, manifestPath, properPythonProjects) {
213020
- switch (ecosystem) {
213021
- case "NPM": {
213022
- const base = basename11(manifestPath);
213023
- const dir = dirname13(manifestPath);
213024
- return base === "package.json" ? dir || "." : void 0;
213025
- }
213026
- case "MAVEN": {
213027
- return ".";
213028
- }
213029
- case "PIP": {
213030
- const base = basename11(manifestPath);
213031
- const dir = dirname13(manifestPath);
213032
- const workspaceDir = dir === "" ? "." : dir;
213033
- if (properPythonProjects.includes(workspaceDir)) {
213034
- return workspaceDir;
213035
- }
213036
- if (base === "poetry.lock" || base === "Pipfile.lock" || base === "uv.lock") {
213037
- return workspaceDir;
213038
- }
213039
- if (base.endsWith(".txt")) {
213040
- const properProjectDirs = properPythonProjects.filter((properProjectDir) => (properProjectDir === "." || workspaceDir === "." || workspaceDir.startsWith(properProjectDir)) && workspaceDir.replace(properProjectDir, "").split(sep5).length <= REQUIREMENTS_FILES_SEARCH_DEPTH2);
213041
- const longestProperProjectDir = l5(properProjectDirs, [(d4) => d4.length, "desc"]);
213042
- if (longestProperProjectDir) {
213043
- return longestProperProjectDir;
213044
- }
213045
- return workspaceDir;
213046
- }
213047
- logger.warn(`No workspace found for manifest file ${manifestPath}`);
213048
- return void 0;
213049
- }
213050
- case "NUGET": {
213051
- return ".";
213052
- }
213053
- case "RUST": {
213054
- return dirname13(manifestPath) || ".";
213055
- }
213056
- case "GO": {
213057
- const base = basename11(manifestPath);
213058
- const dir = dirname13(manifestPath);
213059
- return base === "go.mod" ? dir || "." : void 0;
213060
- }
213061
- default: {
213062
- return ".";
213063
- }
213064
- }
213065
- }
213066
- function inferProjectFromManifestPath(ecosystem, manifestPath) {
213067
- switch (ecosystem) {
213068
- case "NPM": {
213069
- const filename = basename11(manifestPath);
213070
- if (["package-lock.json", "pnpm-lock.yaml", "pnpm-lock.yml", "yarn.lock"].includes(filename)) {
213071
- return dirname13(manifestPath) || ".";
213072
- }
213073
- return void 0;
213074
- }
213543
+ logger.info(`Inferring paths to exclude based on Socket config file: ${basename11(socketConfigFile)}`);
213544
+ return config3.projectIgnorePaths;
213545
+ } catch (e) {
213546
+ return void 0;
213075
213547
  }
213076
213548
  }
213077
- function getAllToplevelAncestors(artifactMap, artifactId) {
213078
- const visited = /* @__PURE__ */ new Set();
213079
- const toplevelAncestors = /* @__PURE__ */ new Set();
213080
- function findAncestors(currentId) {
213081
- if (visited.has(currentId)) {
213082
- return;
213083
- }
213084
- visited.add(currentId);
213085
- const artifact = artifactMap.get(currentId);
213086
- if (!artifact) {
213087
- return;
213088
- }
213089
- if (artifact.toplevelAncestors && artifact.toplevelAncestors.length > 0) {
213090
- for (const ancestorId of artifact.toplevelAncestors) {
213091
- toplevelAncestors.add(ancestorId);
213092
- findAncestors(ancestorId);
213549
+
213550
+ // dist/internal/socket-mode-helpers-coana-dependency-trees.js
213551
+ var ROOT_IDENTIFIER = "ROOT";
213552
+ async function scanForVulnerabilitiesSocketMode(dependencyTree) {
213553
+ if (!dependencyTree.ecosystem)
213554
+ dependencyTree.ecosystem = "NPM";
213555
+ const purlStringsToIdentifier = getPurlStrings(dependencyTree);
213556
+ const components = await augmentArtifactsWithVulnerabilities(Object.keys(purlStringsToIdentifier).map((purl) => ({ purl })));
213557
+ const parentsMap = /* @__PURE__ */ new Map();
213558
+ for (const [depId, node] of [
213559
+ ...Object.entries(dependencyTree.transitiveDependencies),
213560
+ [ROOT_IDENTIFIER, dependencyTree]
213561
+ ]) {
213562
+ for (const childId of node.dependencies ?? []) {
213563
+ if (!parentsMap.has(childId)) {
213564
+ parentsMap.set(childId, []);
213093
213565
  }
213566
+ parentsMap.get(childId).push(depId);
213094
213567
  }
213095
213568
  }
213096
- findAncestors(artifactId);
213097
- return Array.from(toplevelAncestors);
213098
- }
213099
- async function fetchArtifactsFromSocket(rootWorkingDirectory, manifestsTarHash, mode) {
213100
- logger.info("Fetching artifacts from Socket backend using manifests tar hash", manifestsTarHash);
213101
- try {
213102
- const { artifacts } = await fetchArtifactsFromManifestsTarHash(manifestsTarHash);
213103
- const properPythonProjects = [];
213104
- const pipArtifactToRepresentativeManifest = {};
213105
- for (const artifact of artifacts) {
213106
- if (artifact.type === "pypi" && artifact.manifestFiles) {
213107
- pipArtifactToRepresentativeManifest[simplePurl(artifact.type, artifact.namespace ?? "", artifact.name, artifact.version ?? "")] = artifact;
213108
- }
213109
- }
213110
- const venvExcludes = [
213111
- "venv",
213112
- ".venv",
213113
- "env",
213114
- ".env",
213115
- "virtualenv",
213116
- ".virtualenv",
213117
- "venvs",
213118
- ".venvs",
213119
- "envs",
213120
- ".envs",
213121
- "__pycache__",
213122
- ".tox",
213123
- ".nox",
213124
- ".pytest_cache",
213125
- "site-packages",
213126
- "dist-packages",
213127
- "conda-meta",
213128
- "conda-bld",
213129
- ".mypy_cache",
213130
- ".ruff_cache",
213131
- ".hypothesis"
213132
- ];
213133
- const allFiles = await getFilesRelative(rootWorkingDirectory, venvExcludes);
213134
- for (const file of allFiles) {
213135
- const base = basename11(file);
213136
- const workspaceDir = dirname13(file) || ".";
213137
- if (base === "pyproject.toml" || base === "setup.py" && await isSetupPySetuptools(join24(rootWorkingDirectory, file))) {
213138
- if (!properPythonProjects.includes(workspaceDir)) {
213139
- properPythonProjects.push(workspaceDir);
213140
- }
213141
- }
213142
- }
213143
- const artifactMap = new Map(artifacts.map((a4) => [a4.id, a4]));
213144
- const ecosystemToWorkspaceToAnalysisData = {};
213145
- const ecosystemWorkspaceVulnIds = /* @__PURE__ */ new Set();
213146
- const ecosystemToWorkspaceToVulnerabilities = {};
213147
- const purlsFailedToFindWorkspace = /* @__PURE__ */ new Set();
213148
- for (const artifact of artifacts) {
213149
- let processToplevelAncestors2 = function(artifact2) {
213150
- const allAncestorIds = getAllToplevelAncestors(artifactMap, artifact2.id);
213151
- allAncestorIds.forEach((ancestorId) => artifactMap.get(ancestorId)?.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file)));
213569
+ const vulnerabilities = [];
213570
+ const dependencyIdentifiersNotFound = new Set(Object.keys(dependencyTree.transitiveDependencies));
213571
+ for (const c3 of components) {
213572
+ let simplePurlForComponent = simplePurl(c3.purl_type, c3.namespace, c3.name, c3.version);
213573
+ if (!(simplePurlForComponent in purlStringsToIdentifier))
213574
+ simplePurlForComponent = simplePurl(c3.purl_type, c3.namespace, c3.name, null);
213575
+ const dependencyIdentifiers = purlStringsToIdentifier[simplePurlForComponent];
213576
+ for (const dependencyIdentifier of dependencyIdentifiers) {
213577
+ dependencyIdentifiersNotFound.delete(dependencyIdentifier);
213578
+ const dependencyTreeNode = dependencyTree.transitiveDependencies[dependencyIdentifier];
213579
+ if (!dependencyTreeNode)
213580
+ throw new Error(`Dependency tree does not contain dependency ${simplePurlForComponent}`);
213581
+ dependencyTreeNode.purlObj = {
213582
+ type: c3.purl_type,
213583
+ namespace: c3.namespace ?? void 0,
213584
+ name: c3.name,
213585
+ version: c3.version ?? void 0,
213586
+ subpath: c3.subpath ?? void 0,
213587
+ artifactId: c3.artifactId ?? void 0,
213588
+ artifact_id: c3.artifact_id ?? void 0,
213589
+ qualifiers: c3.qualifiers ?? void 0,
213590
+ purlString: c3.purl
213152
213591
  };
213153
- var processToplevelAncestors = processToplevelAncestors2;
213154
- const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
213155
- if (!ecosystem)
213156
- continue;
213157
- const manifestFiles = [];
213158
- switch (ecosystem) {
213159
- case "MAVEN": {
213160
- manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch4.default)("{{*-*.,}pom{.xml,},gradle.lockfile}")(basename11(file))));
213161
- break;
213162
- }
213163
- case "NUGET": {
213164
- manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch4.default)("{*.csproj,packages.lock.json}")(basename11(file))));
213165
- break;
213166
- }
213167
- case "PIP": {
213168
- const sPurl = simplePurl(artifact.type, artifact.namespace ?? "", artifact.name, artifact.version ?? "");
213169
- if (pipArtifactToRepresentativeManifest[sPurl]) {
213170
- manifestFiles.push(...(pipArtifactToRepresentativeManifest[sPurl].manifestFiles ?? []).map((ref) => ref.file));
213171
- }
213172
- processToplevelAncestors2(artifact);
213173
- break;
213174
- }
213175
- default: {
213176
- artifact.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file));
213177
- processToplevelAncestors2(artifact);
213178
- break;
213179
- }
213180
- }
213181
- const workspaceToManifestFiles = {};
213182
- manifestFiles.forEach((manifestFile) => {
213183
- const workspace = inferWorkspaceFromManifestPath(ecosystem, manifestFile, properPythonProjects);
213184
- if (!workspace)
213185
- return;
213186
- (workspaceToManifestFiles[workspace] ??= []).push(manifestFile);
213187
- });
213188
- if (Object.keys(workspaceToManifestFiles).length === 0) {
213189
- manifestFiles.forEach((manifestFile) => {
213190
- const workspace = inferProjectFromManifestPath(ecosystem, manifestFile);
213191
- if (!workspace)
213192
- return;
213193
- (workspaceToManifestFiles[workspace] ??= []).push(manifestFile);
213592
+ for (const vulnerability of c3.vulnerabilities) {
213593
+ vulnerabilities.push({
213594
+ url: vulnerability.ghsaId,
213595
+ purl: c3.purl,
213596
+ purlType: c3.purl_type,
213597
+ range: vulnerability.range,
213598
+ name: dependencyTreeNode.packageName,
213599
+ dependency: dependencyTreeNode.packageName,
213600
+ vulnChainDetails: computeVulnChainDetails2(dependencyTree, dependencyIdentifier, parentsMap),
213601
+ vulnerabilityAccessPaths: vulnerability.reachabilityData?.pattern ?? null,
213602
+ ecosystem: dependencyTree.ecosystem
213194
213603
  });
213195
213604
  }
213196
- if (Object.keys(workspaceToManifestFiles).length === 0 && artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
213197
- const purl = new import_packageurl_js2.PackageURL(artifact.type, artifact.namespace, artifact.name, artifact.version, artifact.qualifiers).toString();
213198
- purlsFailedToFindWorkspace.add(purl);
213199
- }
213200
- for (const [workspace, manifestFiles2] of Object.entries(workspaceToManifestFiles)) {
213201
- const workspaceData = (ecosystemToWorkspaceToAnalysisData[ecosystem] ??= {})[workspace] ??= {
213202
- type: "socket",
213203
- data: {
213204
- type: ecosystem,
213205
- manifestFiles: manifestFiles2,
213206
- artifacts: []
213207
- }
213208
- };
213209
- workspaceData.type;
213210
- workspaceData.data.artifacts.push(artifact);
213211
- }
213212
- if (artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
213213
- for (const workspace of Object.keys(workspaceToManifestFiles)) {
213214
- for (const vuln of artifact.vulnerabilities) {
213215
- const vulnerability = {
213216
- url: vuln.ghsaId,
213217
- purlType: artifact.type,
213218
- range: vuln.range,
213219
- name: artifact.name ?? "",
213220
- dependency: artifact.name ?? "",
213221
- vulnChainDetails: computeVulnChainDetails2(artifacts, artifact.id),
213222
- vulnerabilityAccessPaths: vuln.reachabilityData?.undeterminableReachability ? vuln.reachabilityData.publicComment ?? "" : vuln.reachabilityData?.pattern ?? null,
213223
- ecosystem,
213224
- artifactId: artifact.id
213225
- };
213226
- const vulnId = `${ecosystem}-${workspace}-${vulnerability.url}`;
213227
- if (!ecosystemWorkspaceVulnIds.has(vulnId)) {
213228
- ecosystemWorkspaceVulnIds.add(vulnId);
213229
- ((ecosystemToWorkspaceToVulnerabilities[ecosystem] ??= {})[workspace] ??= []).push(vulnerability);
213230
- }
213231
- }
213232
- }
213233
- }
213234
213605
  }
213235
- if (purlsFailedToFindWorkspace.size > 0) {
213236
- logger.warn(`Failed to find workspace for the following purls with vulnerabilities: ${Array.from(purlsFailedToFindWorkspace).join(", ")}.
213237
- ${mode === "reachability" ? "This means that we will not do a full reachability analysis for these vulnerabilities, but fallback to the results from the pre-computed reachability analysis." : ""}`);
213238
- }
213239
- return {
213240
- artifacts,
213241
- ecosystemToWorkspaceToAnalysisData,
213242
- ecosystemToWorkspaceToVulnerabilities
213243
- };
213244
- } catch (error) {
213245
- logger.error("Failed to fetch artifacts from Socket backend", error);
213246
- throw error;
213247
213606
  }
213248
- }
213249
- function computeVulnChainDetails2(artifacts, vulnerableArtifactId) {
213250
- const artifactMap = new Map(artifacts.map((a4) => [a4.id, a4]));
213251
- const parentsMap = /* @__PURE__ */ new Map();
213252
- for (const artifact of artifacts) {
213253
- if (artifact.dependencies) {
213254
- for (const depId of artifact.dependencies) {
213255
- if (!parentsMap.has(depId)) {
213256
- parentsMap.set(depId, []);
213257
- }
213258
- parentsMap.get(depId).push(artifact.id);
213259
- }
213260
- }
213607
+ for (const dependencyIdentifier of dependencyIdentifiersNotFound) {
213608
+ logger.warn(`Dependency ${dependencyIdentifier} not found in Socket mode`, dependencyTree.transitiveDependencies[dependencyIdentifier]);
213261
213609
  }
213610
+ return vulnerabilities;
213611
+ }
213612
+ function computeVulnChainDetails2(dependencyTree, dependencyIdentifier, parentsMap) {
213262
213613
  const res = {
213263
213614
  packageName: "root",
213264
213615
  version: "0.0.0",
213265
213616
  children: [],
213266
213617
  transitiveDependencies: {}
213267
213618
  };
213268
- function addNode(currentId, childId, visited) {
213269
- if (visited.has(currentId))
213270
- return;
213271
- const currentArtifact = artifactMap.get(currentId);
213272
- if (!currentArtifact)
213619
+ function addNode(currentIdentifier, childIdentifier, visited) {
213620
+ if (visited.has(currentIdentifier))
213273
213621
  return;
213274
- const parents4 = parentsMap.get(currentId);
213275
- const newCurrentNode = {
213276
- packageName: getNameFromNamespaceAndName(currentArtifact.type, currentArtifact.namespace, currentArtifact.name),
213277
- version: currentArtifact.version ?? void 0,
213278
- children: []
213279
- };
213280
- res.transitiveDependencies[currentId] = newCurrentNode;
213281
- if (childId && !newCurrentNode.children.includes(childId)) {
213282
- newCurrentNode.children.push(childId);
213283
- }
213284
- if (currentId === vulnerableArtifactId) {
213285
- newCurrentNode.vulnerable = true;
213286
- }
213287
- if (currentArtifact.direct && !res.children.includes(currentId)) {
213288
- res.children.push(currentId);
213289
- }
213290
- visited.add(currentId);
213291
- if (parents4) {
213292
- for (const parentId of parents4) {
213293
- addNode(parentId, currentId, visited);
213294
- }
213622
+ const parents4 = parentsMap.get(currentIdentifier);
213623
+ const newCurrentNode = transformToVulnChainNode(dependencyTree.transitiveDependencies[currentIdentifier]);
213624
+ res.transitiveDependencies[currentIdentifier] = newCurrentNode;
213625
+ if (childIdentifier && !newCurrentNode.children.includes(childIdentifier))
213626
+ newCurrentNode.children.push(childIdentifier);
213627
+ if (!childIdentifier)
213628
+ newCurrentNode.vulnerable = true;
213629
+ if (!parents4)
213630
+ return res;
213631
+ visited.add(currentIdentifier);
213632
+ for (const parent2 of parents4) {
213633
+ if (parent2 === ROOT_IDENTIFIER)
213634
+ res.children.push(currentIdentifier);
213635
+ else
213636
+ addNode(parent2, currentIdentifier, visited);
213295
213637
  }
213296
213638
  }
213297
- addNode(vulnerableArtifactId, void 0, /* @__PURE__ */ new Set());
213639
+ addNode(dependencyIdentifier, void 0, /* @__PURE__ */ new Set());
213298
213640
  return res;
213299
213641
  }
213642
+ function transformToVulnChainNode(dependencyTree) {
213643
+ return {
213644
+ ...a3(dependencyTree, ["packageName", "version"]),
213645
+ children: []
213646
+ };
213647
+ }
213300
213648
 
213301
213649
  // dist/internal/socket-report-coana-dependency-tree.js
213302
213650
  var MAX_STACKS_TO_SEND = 10;
@@ -226988,7 +227336,7 @@ var { root: root2 } = static_exports;
226988
227336
  // ../utils/src/maven-utils.ts
226989
227337
  var import_lodash14 = __toESM(require_lodash(), 1);
226990
227338
  import { existsSync as existsSync21, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
226991
- import { join as join25 } from "path";
227339
+ import { join as join26 } from "path";
226992
227340
  var { memoize: memoize3 } = import_lodash14.default;
226993
227341
  var memoizedParseShellArgs = memoize3(parseShellArgs);
226994
227342
  var MAVEN_PUBLIC_REPOSITORIES = [
@@ -227671,12 +228019,6 @@ var InMemoryVulnerabilityMetadataStore = class {
227671
228019
  }
227672
228020
  };
227673
228021
 
227674
- // ../web-compat-utils/src/assertions.ts
227675
- function assertDefined(value) {
227676
- if (value === void 0 || value === null) throw new Error("Expected value to be defined");
227677
- return value;
227678
- }
227679
-
227680
228022
  // ../security-auditor/security-auditor-api/src/fixes-task.ts
227681
228023
  var MESSAGE_PREFIX_FOR_FAILED_TO_PICK_VERSION = `Failed to pick a version`;
227682
228024
  var MESSAGE_PREFIX_FOR_NO_POTENTIAL_VERSIONS = `No potential versions`;
@@ -228359,7 +228701,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
228359
228701
  }
228360
228702
 
228361
228703
  // dist/version.js
228362
- var version2 = "14.12.42";
228704
+ var version2 = "14.12.43";
228363
228705
 
228364
228706
  // dist/cli-core.js
228365
228707
  var { mapValues, omit, partition, pick } = import_lodash15.default;
@@ -228389,7 +228731,7 @@ var CliCore = class {
228389
228731
  throw new Error("Invalid analysis timeout value");
228390
228732
  }
228391
228733
  }
228392
- this.rootWorkingDirectory = resolve33(rootWorkingDirectory);
228734
+ this.rootWorkingDirectory = resolve34(rootWorkingDirectory);
228393
228735
  this.spinner = Spinner.instance({
228394
228736
  text: "Running Coana CLI",
228395
228737
  isSilent: this.options.silentSpinner ?? this.options.silent
@@ -228464,7 +228806,7 @@ var CliCore = class {
228464
228806
  }
228465
228807
  }
228466
228808
  async main() {
228467
- this.coanaLogPath = join26(await createTmpDirectory("coana-cli-"), "coana-log.txt");
228809
+ this.coanaLogPath = join27(await createTmpDirectory("coana-cli-"), "coana-log.txt");
228468
228810
  logger.initWinstonLogger(this.options.debug, this.coanaLogPath);
228469
228811
  logger.silent = this.options.silent;
228470
228812
  try {
@@ -228562,7 +228904,7 @@ var CliCore = class {
228562
228904
  this.sendProgress("RUN_ON_SUBPROJECT", false, this.rootWorkingDirectory);
228563
228905
  }
228564
228906
  const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults, this.reportId);
228565
- const outputFile = resolve33(this.options.socketMode);
228907
+ const outputFile = resolve34(this.options.socketMode);
228566
228908
  await writeFile10(outputFile, JSON.stringify(socketReport, null, 2));
228567
228909
  logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
228568
228910
  }
@@ -228580,13 +228922,13 @@ var CliCore = class {
228580
228922
  throw new Error("Dependency trees should be available when using --socket-mode");
228581
228923
  }
228582
228924
  const socketReport = toSocketFacts(report, this.reportDependencyTrees, subPjToWsPathToDirectDependencies);
228583
- const outputFile = resolve33(this.options.socketMode);
228925
+ const outputFile = resolve34(this.options.socketMode);
228584
228926
  await writeFile10(outputFile, JSON.stringify(socketReport, null, 2));
228585
228927
  logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
228586
228928
  return;
228587
228929
  }
228588
228930
  if (outputDir) {
228589
- const jsonReportPath = resolve33(outputDir, `${DEFAULT_REPORT_FILENAME_BASE}.json`);
228931
+ const jsonReportPath = resolve34(outputDir, `${DEFAULT_REPORT_FILENAME_BASE}.json`);
228590
228932
  await mkdir2(outputDir, { recursive: true });
228591
228933
  writeFileSync3(jsonReportPath, JSON.stringify(report, null, 2));
228592
228934
  logger.info(kleur_default.green(`JSON report written to: ${jsonReportPath}`));
@@ -228624,7 +228966,7 @@ var CliCore = class {
228624
228966
  const { reachabilitySupport, traditionalScaSupport, noSupport } = manager.getSubprojectsWithWorkspacePaths();
228625
228967
  await this.dashboardAPI.registerSubprojects([...reachabilitySupport, ...traditionalScaSupport, ...noSupport].map((sp) => ({
228626
228968
  ...sp,
228627
- subprojectPath: relative14(this.rootWorkingDirectory, sp.subprojectPath) || "."
228969
+ subprojectPath: relative15(this.rootWorkingDirectory, sp.subprojectPath) || "."
228628
228970
  })), this.reportId, this.apiKey);
228629
228971
  for (const unsupported of noSupport)
228630
228972
  logger.warn(unsupported.unsupportedMsg);
@@ -228653,7 +228995,7 @@ var CliCore = class {
228653
228995
  await this.spinner.succeed();
228654
228996
  } catch (error) {
228655
228997
  if (this.options.ignoreFailingWorkspaces) {
228656
- const relativeSubprojectPath = relative14(this.rootWorkingDirectory, subprojectAndWsPath.subprojectPath) || ".";
228998
+ const relativeSubprojectPath = relative15(this.rootWorkingDirectory, subprojectAndWsPath.subprojectPath) || ".";
228657
228999
  this.failedSubprojects.push({
228658
229000
  subproject: relativeSubprojectPath,
228659
229001
  error: error.message || "Unknown error"
@@ -228712,7 +229054,7 @@ Subproject: ${subproject}`);
228712
229054
  }
228713
229055
  async updateSpinnerTextOnNewSubproject(subprojectAndWsPath, numberSubprojects, index2) {
228714
229056
  this.spinner.start();
228715
- const relativeSubprojectPath = relative14(this.rootWorkingDirectory, subprojectAndWsPath.subprojectPath) || ".";
229057
+ const relativeSubprojectPath = relative15(this.rootWorkingDirectory, subprojectAndWsPath.subprojectPath) || ".";
228716
229058
  await this.spinner.setText(numberSubprojects > 1 ? `Processing subproject ${relativeSubprojectPath} (${index2 + 1}/${numberSubprojects})${+this.options.concurrency > 1 ? `. May process up to ${+this.options.concurrency - 1} other workspaces in parallel` : ""}` : `Processing ${relativeSubprojectPath}`);
228717
229059
  }
228718
229060
  async initialize() {
@@ -228790,7 +229132,7 @@ Subproject: ${subproject}`);
228790
229132
  return workspaceToAugmentedVulnerabilities[workspacePath] !== void 0;
228791
229133
  }).map((workspacePath) => {
228792
229134
  return {
228793
- subprojectPath: relative14(this.rootWorkingDirectory, subprojectPath) || ".",
229135
+ subprojectPath: relative15(this.rootWorkingDirectory, subprojectPath) || ".",
228794
229136
  workspacePath,
228795
229137
  directDependencies: projectInfo[workspacePath].dataForAnalysis.directDependenciesMap ?? {},
228796
229138
  vulnerabilities: workspaceToAugmentedVulnerabilities[workspacePath],
@@ -228889,7 +229231,7 @@ Subproject: ${subproject}`);
228889
229231
  excludeDirs: this.options.excludeDirs ?? [],
228890
229232
  changedFiles: this.options.changedFiles,
228891
229233
  includeDirs: this.options.includeDirs ?? []
228892
- }, resolve33(subprojectPath, workspacePath));
229234
+ }, resolve34(subprojectPath, workspacePath));
228893
229235
  if (shouldExcludeWorkspaceForAnalysis) {
228894
229236
  logger.info(`Skipping reachability analysis for workspace ${workspacePath} due to it being excluded.`);
228895
229237
  }
@@ -228920,7 +229262,7 @@ Subproject: ${subproject}`);
228920
229262
  async sendProgress(type, isStartEvent, subprojectPath, workspacePath) {
228921
229263
  await this.dashboardAPI.registerCLIProgress({
228922
229264
  type,
228923
- ...subprojectPath ? { subprojectPath: relative14(this.rootWorkingDirectory, subprojectPath) || "." } : {},
229265
+ ...subprojectPath ? { subprojectPath: relative15(this.rootWorkingDirectory, subprojectPath) || "." } : {},
228924
229266
  ...workspacePath ? { workspacePath } : {}
228925
229267
  }, isStartEvent, this.reportId, this.apiKey);
228926
229268
  }
@@ -228959,471 +229301,108 @@ Subproject: ${subproject}`);
228959
229301
  artifactId: v.artifactId
228960
229302
  };
228961
229303
  });
228962
- }
228963
- async getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subProjAndWsPath) {
228964
- const { packageManagerName, subprojectPath, workspacePaths } = subProjAndWsPath;
228965
- this.sendProgress("RUN_ON_SUBPROJECT", true, subprojectPath);
228966
- const rootWorkingDirectory = this.rootWorkingDirectory;
228967
- this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", true, subprojectPath);
228968
- const projectInfo = await otherModulesCommunicator.prepareProjectAndGetProjectData(packageManagerName, subprojectPath, workspacePaths, this.options.lightweightReachability, this.options.providerProject ? await this.runOnProvider(this.options.providerProject) : void 0);
228969
- this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", false, subprojectPath);
228970
- const workspaceToPlainDependencyTree = Object.fromEntries(workspacePaths.map((workspacePath) => [
228971
- workspacePath,
228972
- toPlainDependencyTree(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree)
228973
- ]));
228974
- const dependencyTrees = workspacePaths.map((workspacePath) => ({
228975
- treeType: "v1",
228976
- dependencyTree: workspaceToPlainDependencyTree[workspacePath],
228977
- ecosystem: workspaceToPlainDependencyTree[workspacePath].ecosystem ?? "NPM",
228978
- workspacePath,
228979
- subprojectPath: relative14(rootWorkingDirectory, subprojectPath) || "."
228980
- }));
228981
- if (this.options.socketMode) {
228982
- this.reportDependencyTrees = workspacePaths.map((workspacePath) => ({
228983
- treeType: "v1",
228984
- dependencyTree: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree,
228985
- ecosystem: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree.ecosystem ?? "NPM",
228986
- workspacePath,
228987
- subprojectPath: relative14(rootWorkingDirectory, subprojectPath) || "."
228988
- }));
228989
- }
228990
- if (this.shareWithDashboard)
228991
- sendDependencyTreesToDashboard(dependencyTrees, this.reportId, this.apiKey);
228992
- const workspaceToVulnerabilities = Object.fromEntries(await asyncMap(workspacePaths, async (workspacePath, idx) => this.spinner.wrap(`Scanning for vulnerabilities: (${subProjAndWsPath.packageManagerName}) (${idx + 1}/${workspacePaths.length}) ${workspacePath}`, async () => {
228993
- const dependencyTree = projectInfo[workspacePath].dataForAnalysis.data.dependencyTree;
228994
- this.sendProgress("SCAN_FOR_VULNERABILITIES", true, subprojectPath, workspacePath);
228995
- try {
228996
- return [
228997
- workspacePath,
228998
- this.options.socketMode ? await scanForVulnerabilitiesSocketMode(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree) : (await scanForVulnerabilities(dependencyTree, this.options.offlineDatabase, this.apiKey, Number(this.options.timeout))).vulnerabilities
228999
- ];
229000
- } catch (e) {
229001
- logger.error(`Scanning for vulnerabilities failed for subproject ${subprojectPath} in workspace ${workspacePath}`);
229002
- if (this.options.ignoreFailingWorkspaces) {
229003
- const relativeSubprojectPath = relative14(this.rootWorkingDirectory, subprojectPath) || ".";
229004
- this.failedWorkspaces.push({
229005
- subproject: relativeSubprojectPath,
229006
- workspace: workspacePath,
229007
- error: e.message || "Unknown error",
229008
- phase: "vulnerability-scanning"
229009
- });
229010
- return [workspacePath, void 0];
229011
- }
229012
- throw e;
229013
- } finally {
229014
- this.sendProgress("SCAN_FOR_VULNERABILITIES", false, subprojectPath, workspacePath);
229015
- }
229016
- })));
229017
- const successfulWorkspaceToVulnerabilities = Object.fromEntries(Object.entries(workspaceToVulnerabilities).filter(([_, vulns]) => vulns !== void 0));
229018
- return { projectInfo, workspaceToVulnerabilities: successfulWorkspaceToVulnerabilities };
229019
- }
229020
- };
229021
- function getRelativeSubprojectPath(subprojectPath, projectDir) {
229022
- return relative14(projectDir, subprojectPath) || ".";
229023
- }
229024
- function getDependencyType(vulnChainDetails, codeAwareScanResults, directDependencies, reachability) {
229025
- if (reachability === "UNREACHABLE" || reachability === "UNKNOWN") {
229026
- return getDependencyTypeForUnreachableVulnerability(vulnChainDetails, directDependencies);
229027
- }
229028
- if (codeAwareScanResults.type === "noAnalysisCheck") {
229029
- const affectedPackages = [
229030
- "",
229031
- ...Object.values(vulnChainDetails?.transitiveDependencies ?? []).map((n2) => `${n2.packageName}@${n2.version}`)
229032
- ];
229033
- return getDependencyTypeForReachableVulnerability(vulnChainDetails, directDependencies, affectedPackages);
229034
- }
229035
- if (codeAwareScanResults.type !== "success") {
229036
- throw new Error(`AssertionError: Expected codeAwareScanResults to be either success or noAnalysisCheck when reachability is REACHABLE`);
229037
- }
229038
- const detectedOccurrences = codeAwareScanResults.detectedOccurrences;
229039
- let dependencyType = "unknown";
229040
- for (const detectedOccurrence of Array.isArray(detectedOccurrences) ? detectedOccurrences : [detectedOccurrences]) {
229041
- const affectedPackages = detectedOccurrence.affectedPackages;
229042
- const dependencyTypeForOccurrence = getDependencyTypeForReachableVulnerability(vulnChainDetails, directDependencies, affectedPackages);
229043
- if (dependencyType === "unknown") {
229044
- dependencyType = dependencyTypeForOccurrence;
229045
- } else if (dependencyType !== dependencyTypeForOccurrence) {
229046
- return "prod&dev";
229047
- }
229048
- }
229049
- if (dependencyType === "unknown") {
229050
- dependencyType = getDependencyTypeForUnreachableVulnerability(vulnChainDetails, directDependencies);
229051
- }
229052
- return dependencyType;
229053
- }
229054
- async function getGitDataToMetadataIfAvailable(rootWorkingDirectory) {
229055
- const base = cmdt`git -c safe.directory=${rootWorkingDirectory} rev-parse`;
229056
- try {
229057
- return {
229058
- sha: await runCommandResolveStdOut([...base, "HEAD"], rootWorkingDirectory),
229059
- branchName: await runCommandResolveStdOut([...base, "--abbrev-ref", "HEAD"], rootWorkingDirectory)
229060
- };
229061
- } catch (e) {
229062
- logger.debug("Unable to get git data. Is the folder even in a git repository?", e);
229063
- }
229064
- }
229065
-
229066
- // dist/cli-upgrade-purl.js
229067
- import { join as join27, relative as relative15, resolve as resolve34 } from "node:path";
229068
- var import_packageurl_js3 = __toESM(require_packageurl_js(), 1);
229069
- var ECOSYSTEMS_WITH_SOCKET_UPGRADES = ["NPM", "MAVEN", "NUGET", "GO", "RUST"];
229070
- async function upgradePurl(rootDir, upgrades, options, logFile, cliFixRunId) {
229071
- if (options.rangeStyle && options.rangeStyle !== "pin") {
229072
- throw new Error('Range style must be "pin"');
229073
- }
229074
- logger.initWinstonLogger(options.debug);
229075
- logger.silent = options.silent;
229076
- let cliRunId = cliFixRunId;
229077
- if (!cliRunId && options.manifestsTarHash) {
229078
- cliRunId = await getSocketAPI().registerAutofixOrUpgradePurlRun(options.manifestsTarHash, options, "upgrade-purls");
229079
- }
229080
- const upgradePurlRunId = cliRunId && await getSocketAPI().registerUpgradePurlRun(cliRunId, upgrades);
229081
- Spinner.instance({
229082
- text: "Running Coana Upgrade Purl CLI",
229083
- isSilent: options.silentSpinner ?? options.silent
229084
- }).start();
229085
- try {
229086
- logger.info(`Upgrading purls for ${rootDir}:
229087
- ${upgrades.map(({ purl, upgradeVersion }) => ` ${prettyPrintPurlUpgrade(purl, upgradeVersion)}`).join("\n")}`);
229088
- if (options.manifestsTarHash) {
229089
- const { supportedUpgrades, unsupportedUpgrades } = upgrades.reduce((acc, upgrade) => {
229090
- const ecosystem = getAdvisoryEcosystemFromPurl(upgrade.purl);
229091
- const target = ECOSYSTEMS_WITH_SOCKET_UPGRADES.includes(ecosystem) ? "supportedUpgrades" : "unsupportedUpgrades";
229092
- acc[target].push(upgrade);
229093
- return acc;
229094
- }, { supportedUpgrades: [], unsupportedUpgrades: [] });
229095
- if (unsupportedUpgrades.length > 0) {
229096
- logger.warn(`The following upgrades are not supported due to missing support for upgrading their ecosystem: ${unsupportedUpgrades.map(({ purl, upgradeVersion }) => ` ${prettyPrintPurlUpgrade(purl, upgradeVersion)}`).join("\n")}`);
229097
- }
229098
- if (supportedUpgrades.length === 0) {
229099
- return "fixed-none";
229100
- }
229101
- try {
229102
- const purlToUpgradeVersion = new Map(supportedUpgrades.map((upgrade) => [upgrade.purl, upgrade.upgradeVersion]));
229103
- const [manifestFiles, artifacts] = await Promise.all([
229104
- fetchManifestFilesFromManifestsTarHash(options.manifestsTarHash),
229105
- (await fetchArtifactsFromSocket(rootDir, options.manifestsTarHash, "upgrade-purls")).artifacts
229106
- ]);
229107
- const ecosystemToSocketArtifactUpgrades = /* @__PURE__ */ new Map();
229108
- artifacts.forEach((artifact, idx) => {
229109
- if (!artifact.name)
229110
- return;
229111
- if (!artifact.version)
229112
- return;
229113
- const purl = new import_packageurl_js3.PackageURL(artifact.type, artifact.namespace, artifact.name, artifact.version, artifact.qualifiers).toString();
229114
- const upgradeVersion = purlToUpgradeVersion.get(purl);
229115
- if (!upgradeVersion)
229116
- return;
229117
- const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
229118
- if (!ecosystemToSocketArtifactUpgrades.has(ecosystem)) {
229119
- ecosystemToSocketArtifactUpgrades.set(ecosystem, /* @__PURE__ */ new Map());
229120
- }
229121
- const currentUpgradeVersion = ecosystemToSocketArtifactUpgrades.get(ecosystem).get(idx);
229122
- if (currentUpgradeVersion === void 0) {
229123
- ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, upgradeVersion);
229124
- } else {
229125
- const versions = sortVersions(ecosystem, [artifact.version, currentUpgradeVersion, upgradeVersion]);
229126
- if (versionSatisfiesRelation(ecosystem, artifact.version, "=", versions[0])) {
229127
- ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[versions.length - 1]);
229128
- } else if (versionSatisfiesRelation(ecosystem, artifact.version, "=", versions[versions.length - 1])) {
229129
- ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[0]);
229130
- } else {
229131
- ecosystemToSocketArtifactUpgrades.get(ecosystem).set(idx, versions[versions.length - 1]);
229132
- }
229133
- }
229134
- });
229135
- let anyErrors = false;
229136
- for (const [ecosystem, upgrades2] of ecosystemToSocketArtifactUpgrades) {
229137
- if (options.rangeStyle && !["NPM", "MAVEN", "NUGET", "RUST"].includes(ecosystem)) {
229138
- logger.warn(`Range style is not supported for ${ecosystem}, skipping upgrades`);
229139
- continue;
229140
- }
229141
- const statusUpdater = (update2) => {
229142
- const statusIcons = {
229143
- success: "\u2705",
229144
- skipped: "\u26AA",
229145
- warn: "\u26A0\uFE0F",
229146
- error: "\u274C"
229147
- };
229148
- logger.info(`${statusIcons[update2.status]} ${update2.message} \u2500 ${relative15(rootDir, resolve34(rootDir, update2.file))}`);
229149
- update2.artifacts.forEach((idx, i7) => {
229150
- logger.info(`${" ".repeat(3)}${i7 === update2.artifacts.length - 1 ? "\u2514\u2500" : "\u251C\u2500"} ${prettyPrintSocketFactArtifactUpgrade(artifacts[idx], upgrades2.get(idx))}`);
229151
- });
229152
- for (const detail of update2.details ?? []) {
229153
- logger.debug(detail);
229154
- }
229155
- if (update2.patch)
229156
- logger.debug(update2.patch);
229157
- if (update2.status === "error")
229158
- anyErrors = true;
229159
- };
229160
- const ctxt = {
229161
- manifestFiles,
229162
- upgrades: upgrades2,
229163
- artifacts,
229164
- rangeStyle: options.rangeStyle,
229165
- statusUpdater
229166
- };
229167
- await applySocketUpgrades(ecosystem, rootDir, ctxt);
229168
- }
229169
- if (upgradePurlRunId) {
229170
- await getSocketAPI().finalizeUpgradePurlRun(upgradePurlRunId, "succeeded");
229171
- }
229172
- return unsupportedUpgrades.length === 0 && !anyErrors ? "fixed-all" : "fixed-some";
229173
- } catch (error) {
229174
- if (upgradePurlRunId) {
229175
- await getSocketAPI().finalizeUpgradePurlRun(
229176
- upgradePurlRunId,
229177
- "error",
229178
- !cliFixRunId ? error.stack : void 0,
229179
- // do not send stack trace and logContent for computeFixes runs, as that will be handled by that command.
229180
- !cliFixRunId && logFile ? await logger.getLogContent(logFile) : void 0
229181
- );
229182
- }
229183
- throw error;
229184
- }
229185
- }
229186
- const otherModulesCommunicator = new OtherModulesCommunicator(rootDir, options, {
229187
- type: "missing"
229188
- });
229189
- const ecosystems = upgrades.map((upgrade) => getAdvisoryEcosystemFromPurl(upgrade.purl));
229190
- const manager = await ProjectManager.create(rootDir, otherModulesCommunicator, ecosystems);
229191
- const { reachabilitySupport, traditionalScaSupport } = manager.getSubprojectsWithWorkspacePaths();
229192
- const supportedSubprojects = reachabilitySupport.concat(traditionalScaSupport).filter((p3) => getPackageManagerSupport(p3.packageManagerName).supportsApplyingFixes);
229193
- if (supportedSubprojects.length === 0) {
229194
- throw new Error(`No supported projects found in ${rootDir}.`);
229304
+ }
229305
+ async getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subProjAndWsPath) {
229306
+ const { packageManagerName, subprojectPath, workspacePaths } = subProjAndWsPath;
229307
+ this.sendProgress("RUN_ON_SUBPROJECT", true, subprojectPath);
229308
+ const rootWorkingDirectory = this.rootWorkingDirectory;
229309
+ this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", true, subprojectPath);
229310
+ const projectInfo = await otherModulesCommunicator.prepareProjectAndGetProjectData(packageManagerName, subprojectPath, workspacePaths, this.options.lightweightReachability, this.options.providerProject ? await this.runOnProvider(this.options.providerProject) : void 0);
229311
+ this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", false, subprojectPath);
229312
+ const workspaceToPlainDependencyTree = Object.fromEntries(workspacePaths.map((workspacePath) => [
229313
+ workspacePath,
229314
+ toPlainDependencyTree(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree)
229315
+ ]));
229316
+ const dependencyTrees = workspacePaths.map((workspacePath) => ({
229317
+ treeType: "v1",
229318
+ dependencyTree: workspaceToPlainDependencyTree[workspacePath],
229319
+ ecosystem: workspaceToPlainDependencyTree[workspacePath].ecosystem ?? "NPM",
229320
+ workspacePath,
229321
+ subprojectPath: relative15(rootWorkingDirectory, subprojectPath) || "."
229322
+ }));
229323
+ if (this.options.socketMode) {
229324
+ this.reportDependencyTrees = workspacePaths.map((workspacePath) => ({
229325
+ treeType: "v1",
229326
+ dependencyTree: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree,
229327
+ ecosystem: projectInfo[workspacePath].dataForAnalysis.data.dependencyTree.ecosystem ?? "NPM",
229328
+ workspacePath,
229329
+ subprojectPath: relative15(rootWorkingDirectory, subprojectPath) || "."
229330
+ }));
229195
229331
  }
229196
- const subprojectPromiseQueue = new PromiseQueue(Number(options.concurrency));
229197
- supportedSubprojects.forEach((subproject) => {
229198
- subprojectPromiseQueue.enqueueTask(async () => {
229199
- const workspacePathsMatchingGlob = subproject.workspacePaths.filter((wsPath) => minimatch(join27(subproject.subprojectPath, wsPath), options.globPattern ?? "**"));
229200
- if (workspacePathsMatchingGlob.length === 0)
229201
- return;
229202
- logger.info(`Found workspaces for subproject ${subproject.subprojectPath}${options.globPattern ? `matching glob ${options.globPattern}` : ""}:
229203
- ${workspacePathsMatchingGlob.map((wsPath) => ` ${wsPath}`).join("\n")}`);
229204
- const fixingData = await otherModulesCommunicator.getFixingData(subproject.packageManagerName, subproject.subprojectPath, workspacePathsMatchingGlob);
229205
- const workspaceToFixes = {};
229206
- Object.entries(fixingData.dependencyTrees).forEach(([wsPath, depTree]) => {
229207
- const vulnerabilityFixes = [];
229208
- const simplePurlToDepId = getPurlStrings(depTree);
229209
- upgrades.forEach((upgrade) => {
229210
- const purl = import_packageurl_js3.PackageURL.fromString(upgrade.purl);
229211
- if (purl.version === void 0)
229212
- throw Error(`Undefined version for purl ${upgrade.purl}`);
229213
- const simplePurl2 = `pkg:${purl.type}/${purl.namespace ? `${purl.namespace}/` : ""}${purl.name}${purl.version ? `@${purl.version}` : ""}`;
229214
- for (const depIdMatchingPurl of simplePurlToDepId[simplePurl2] ?? []) {
229215
- const node = depTree.transitiveDependencies[depIdMatchingPurl];
229216
- if (!node)
229217
- throw Error("should not happen!");
229218
- vulnerabilityFixes.push({
229219
- dependencyName: node.packageName,
229220
- currentVersion: assertDefined(node.version),
229221
- dependencyIdentifier: depIdMatchingPurl,
229222
- fixedVersion: upgrade.upgradeVersion
229223
- });
229224
- }
229332
+ if (this.shareWithDashboard)
229333
+ sendDependencyTreesToDashboard(dependencyTrees, this.reportId, this.apiKey);
229334
+ const workspaceToVulnerabilities = Object.fromEntries(await asyncMap(workspacePaths, async (workspacePath, idx) => this.spinner.wrap(`Scanning for vulnerabilities: (${subProjAndWsPath.packageManagerName}) (${idx + 1}/${workspacePaths.length}) ${workspacePath}`, async () => {
229335
+ const dependencyTree = projectInfo[workspacePath].dataForAnalysis.data.dependencyTree;
229336
+ this.sendProgress("SCAN_FOR_VULNERABILITIES", true, subprojectPath, workspacePath);
229337
+ try {
229338
+ return [
229339
+ workspacePath,
229340
+ this.options.socketMode ? await scanForVulnerabilitiesSocketMode(projectInfo[workspacePath].dataForAnalysis.data.dependencyTree) : (await scanForVulnerabilities(dependencyTree, this.options.offlineDatabase, this.apiKey, Number(this.options.timeout))).vulnerabilities
229341
+ ];
229342
+ } catch (e) {
229343
+ logger.error(`Scanning for vulnerabilities failed for subproject ${subprojectPath} in workspace ${workspacePath}`);
229344
+ if (this.options.ignoreFailingWorkspaces) {
229345
+ const relativeSubprojectPath = relative15(this.rootWorkingDirectory, subprojectPath) || ".";
229346
+ this.failedWorkspaces.push({
229347
+ subproject: relativeSubprojectPath,
229348
+ workspace: workspacePath,
229349
+ error: e.message || "Unknown error",
229350
+ phase: "vulnerability-scanning"
229225
229351
  });
229226
- if (vulnerabilityFixes.length === 0)
229227
- return;
229228
- logger.info(`Found ${vulnerabilityFixes.length} ${vulnerabilityFixes.length === 1 ? "dependency" : "dependencies"} matching upgrade specs for ${join27(subproject.subprojectPath, wsPath)}`);
229229
- workspaceToFixes[wsPath] = [
229230
- {
229231
- fixId: "dummy",
229232
- vulnerabilityFixes
229233
- }
229234
- ];
229235
- });
229236
- if (Object.entries(workspaceToFixes).length === 0) {
229237
- logger.info(`No dependencies matching upgrade specs found for subproject ${subproject.subprojectPath}`);
229238
- return;
229352
+ return [workspacePath, void 0];
229239
229353
  }
229240
- await applySecurityFixes(subproject.packageManagerName, rootDir, relative15(rootDir, subproject.subprojectPath) || ".", otherModulesCommunicator, workspaceToFixes, fixingData, signalFixApplied);
229241
- });
229242
- });
229243
- await subprojectPromiseQueue.onIdle();
229244
- } finally {
229245
- Spinner.instance().stop();
229354
+ throw e;
229355
+ } finally {
229356
+ this.sendProgress("SCAN_FOR_VULNERABILITIES", false, subprojectPath, workspacePath);
229357
+ }
229358
+ })));
229359
+ const successfulWorkspaceToVulnerabilities = Object.fromEntries(Object.entries(workspaceToVulnerabilities).filter(([_, vulns]) => vulns !== void 0));
229360
+ return { projectInfo, workspaceToVulnerabilities: successfulWorkspaceToVulnerabilities };
229246
229361
  }
229247
- }
229248
- var signalFixApplied = (_fixId, subprojectPath, workspacePath, vulnerabilityFixes) => {
229249
- logger.info(`Successfully upgraded purls for: ${join27(subprojectPath, workspacePath)}`);
229250
- logger.info(`Upgraded:
229251
- ${vulnerabilityFixes.map((fix) => ` ${fix.dependencyName} from ${fix.currentVersion} to ${fix.fixedVersion}`).join("\n")}`);
229252
229362
  };
229253
-
229254
- // dist/cli-compute-fixes-and-upgrade-purls.js
229255
- async function computeFixesAndUpgradePurls(path2, options, logFile) {
229256
- const autofixRunId = options.manifestsTarHash && await getSocketAPI().registerAutofixOrUpgradePurlRun(options.manifestsTarHash, options, "autofix");
229257
- const { artifacts, ghsaToVulnerableArtifactIds } = await computeInputForComputingFixes(path2, options);
229258
- if (Object.keys(ghsaToVulnerableArtifactIds).length === 0) {
229259
- logger.info("No vulnerabilities to compute fixes for");
229260
- return { type: "no-vulnerabilities-found" };
229261
- }
229262
- if (options.applyFixesTo.length === 0) {
229263
- logger.info("Vulnerabilities found:", Object.keys(ghsaToVulnerableArtifactIds).join(", "));
229264
- logger.info("Run again with --apply-fixes-to GHSA_IDS to fix those vulnerabilities by computing packages to upgrade and apply them");
229265
- return { type: "no-ghsas-fix-requested", ghsas: Object.keys(ghsaToVulnerableArtifactIds) };
229266
- }
229267
- const ghsaToVulnerableArtifactIdsToApply = options.applyFixesTo.includes("all") ? ghsaToVulnerableArtifactIds : Object.fromEntries(Object.entries(ghsaToVulnerableArtifactIds).filter(([ghsa]) => options.applyFixesTo.includes(ghsa)));
229268
- const computedFix = await useSocketComputeFixEndpoint(autofixRunId, artifacts, ghsaToVulnerableArtifactIdsToApply, {
229269
- noMajorUpdates: options.disableMajorUpdates,
229270
- minimumReleaseAgeInMinutes: options.minimumReleaseAgeInMinutes
229271
- });
229272
- if (computedFix.type !== "success") {
229273
- throw new Error(`No fix found for the given vulnerabilities`);
229363
+ function getRelativeSubprojectPath(subprojectPath, projectDir) {
229364
+ return relative15(projectDir, subprojectPath) || ".";
229365
+ }
229366
+ function getDependencyType(vulnChainDetails, codeAwareScanResults, directDependencies, reachability) {
229367
+ if (reachability === "UNREACHABLE" || reachability === "UNKNOWN") {
229368
+ return getDependencyTypeForUnreachableVulnerability(vulnChainDetails, directDependencies);
229274
229369
  }
229275
- const ghsasFailedToFix = Object.keys(ghsaToVulnerableArtifactIdsToApply).filter((ghsa) => {
229276
- const artifactIds = ghsaToVulnerableArtifactIdsToApply[ghsa];
229277
- if (!artifactIds)
229278
- return false;
229279
- return artifactIds.some((artifactId) => computedFix.ghsaToResult[ghsa].failedArtifacts?.includes(artifactId));
229280
- });
229281
- if (ghsasFailedToFix.length > 0) {
229282
- logger.info("Failed to compute fixes for the following vulnerabilities:");
229370
+ if (codeAwareScanResults.type === "noAnalysisCheck") {
229371
+ const affectedPackages = [
229372
+ "",
229373
+ ...Object.values(vulnChainDetails?.transitiveDependencies ?? []).map((n2) => `${n2.packageName}@${n2.version}`)
229374
+ ];
229375
+ return getDependencyTypeForReachableVulnerability(vulnChainDetails, directDependencies, affectedPackages);
229283
229376
  }
229284
- for (const ghsa of ghsasFailedToFix) {
229285
- logger.info(` - ${ghsa} (${ghsaToVulnerableArtifactIdsToApply[ghsa].map((id) => simplePurl(artifacts[id].type, artifacts[id].namespace ?? null, artifacts[id].name ?? "", artifacts[id].version ?? null)).join(", ")})`);
229377
+ if (codeAwareScanResults.type !== "success") {
229378
+ throw new Error(`AssertionError: Expected codeAwareScanResults to be either success or noAnalysisCheck when reachability is REACHABLE`);
229286
229379
  }
229287
- const fixesFound = Object.entries(computedFix.ghsaToResult).filter(([_, result]) => result.failedArtifacts === void 0 || result.failedArtifacts.length === 0);
229288
- const combinedFixes = fixesFound.flatMap(([_, result]) => result.fixes);
229289
- if (options.dryRun) {
229290
- logger.info("Fixes found:");
229291
- for (const [ghsa, result] of fixesFound) {
229292
- logger.info(` - ${ghsa}:`);
229293
- for (const fix of result.fixes) {
229294
- logger.info(` - ${fix.purl} -> ${fix.fixedVersion}`);
229295
- }
229380
+ const detectedOccurrences = codeAwareScanResults.detectedOccurrences;
229381
+ let dependencyType = "unknown";
229382
+ for (const detectedOccurrence of Array.isArray(detectedOccurrences) ? detectedOccurrences : [detectedOccurrences]) {
229383
+ const affectedPackages = detectedOccurrence.affectedPackages;
229384
+ const dependencyTypeForOccurrence = getDependencyTypeForReachableVulnerability(vulnChainDetails, directDependencies, affectedPackages);
229385
+ if (dependencyType === "unknown") {
229386
+ dependencyType = dependencyTypeForOccurrence;
229387
+ } else if (dependencyType !== dependencyTypeForOccurrence) {
229388
+ return "prod&dev";
229296
229389
  }
229297
- return {
229298
- type: "dry-run-result",
229299
- fixes: Object.fromEntries(fixesFound.map(([ghsa, result]) => [ghsa, result.fixes])),
229300
- ...ghsasFailedToFix.length > 0 && { failedToFix: ghsasFailedToFix }
229301
- };
229302
229390
  }
229303
- if (combinedFixes.length === 0) {
229304
- if (autofixRunId) {
229305
- await getSocketAPI().finalizeAutofixRun(autofixRunId, "fixed-none");
229306
- }
229307
- throw new Error("Failed to find a fix for the given vulnerabilities");
229391
+ if (dependencyType === "unknown") {
229392
+ dependencyType = getDependencyTypeForUnreachableVulnerability(vulnChainDetails, directDependencies);
229308
229393
  }
229394
+ return dependencyType;
229395
+ }
229396
+ async function getGitDataToMetadataIfAvailable(rootWorkingDirectory) {
229397
+ const base = cmdt`git -c safe.directory=${rootWorkingDirectory} rev-parse`;
229309
229398
  try {
229310
- const applyFixesStatus = await upgradePurl(path2, T3(combinedFixes, (fix) => `${fix.purl}${fix.fixedVersion}`).map((fix) => ({
229311
- purl: fix.purl,
229312
- upgradeVersion: fix.fixedVersion
229313
- })), {
229314
- debug: options.debug,
229315
- silent: options.silent,
229316
- runWithoutDocker: options.runWithoutDocker,
229317
- manifestsTarHash: options.manifestsTarHash,
229318
- concurrency: "1",
229319
- globPattern: options.globPattern,
229320
- rangeStyle: options.rangeStyle
229321
- }, void 0, autofixRunId) ?? "fixed-all";
229322
- if (autofixRunId) {
229323
- 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");
229324
- }
229325
229399
  return {
229326
- type: "applied-fixes",
229327
- fixes: Object.fromEntries(fixesFound.map(([ghsa, result]) => [ghsa, result.fixes]))
229400
+ sha: await runCommandResolveStdOut([...base, "HEAD"], rootWorkingDirectory),
229401
+ branchName: await runCommandResolveStdOut([...base, "--abbrev-ref", "HEAD"], rootWorkingDirectory)
229328
229402
  };
229329
- } catch (error) {
229330
- if (autofixRunId) {
229331
- await getSocketAPI().finalizeAutofixRun(autofixRunId, "error", error.stack, await logger.getLogContent(logFile));
229332
- }
229333
- logger.error("Error applying fixes:", error);
229334
- throw error;
229335
- }
229336
- }
229337
- async function computeInputForComputingFixes(path2, options) {
229338
- if (options.manifestsTarHash) {
229339
- const { artifacts: artifacts2 } = await fetchArtifactsFromSocket(path2, options.manifestsTarHash, "autofix");
229340
- const ghsaToVulnerableArtifactIds2 = {};
229341
- for (const [index2, artifact] of artifacts2.entries()) {
229342
- if (!artifact.vulnerabilities)
229343
- continue;
229344
- for (const vulnerability of artifact.vulnerabilities) {
229345
- if (!(ghsaToVulnerableArtifactIds2[vulnerability.ghsaId] ??= []).includes(index2)) {
229346
- ghsaToVulnerableArtifactIds2[vulnerability.ghsaId].push(index2);
229347
- }
229348
- }
229349
- }
229350
- const sbomTaskArtifacts = artifacts2.map((artifact) => ({
229351
- type: artifact.type,
229352
- name: artifact.name ?? "",
229353
- version: artifact.version ?? "",
229354
- namespace: artifact.namespace ?? void 0,
229355
- adj: artifact.dependencies?.map((dep) => artifacts2.findIndex((a4) => a4.id === dep)) ?? []
229356
- }));
229357
- return { artifacts: sbomTaskArtifacts, ghsaToVulnerableArtifactIds: ghsaToVulnerableArtifactIds2 };
229358
- }
229359
- const otherModulesCommunicator = new OtherModulesCommunicator(path2, options, {
229360
- type: "missing"
229361
- });
229362
- const manager = await ProjectManager.create(path2, otherModulesCommunicator);
229363
- const { reachabilitySupport, traditionalScaSupport } = manager.getSubprojectsWithWorkspacePaths();
229364
- const supportedSubprojects = reachabilitySupport.concat(traditionalScaSupport).filter((p3) => getPackageManagerSupport(p3.packageManagerName).supportsApplyingFixes);
229365
- if (supportedSubprojects.length === 0) {
229366
- throw new Error(`No supported projects found in ${path2}.`);
229367
- }
229368
- const cliCore = new CliCore(path2, { ...defaultCliOptions, socketMode: "true" });
229369
- const results = await asyncMap(supportedSubprojects, async (subproject) => cliCore.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subproject));
229370
- const { artifacts, purlToIndex } = computeSBOMTaskArtifacts(results.flatMap((r3) => Object.values(r3.projectInfo).map((info) => info.dataForAnalysis.data.dependencyTree)));
229371
- const ghsaToVulnerableArtifactIds = computeVulnerableArtifactIdsPerVulnerability(results.flatMap((r3) => Object.values(r3.workspaceToVulnerabilities).flat()), purlToIndex);
229372
- return { artifacts, ghsaToVulnerableArtifactIds };
229373
- }
229374
- function computeVulnerableArtifactIdsPerVulnerability(vulnerabilities, purlToIndex) {
229375
- const vulnerableArtifactIdsPerVulnerability = {};
229376
- for (const vulnerability of vulnerabilities) {
229377
- if (!vulnerableArtifactIdsPerVulnerability[vulnerability.url]) {
229378
- vulnerableArtifactIdsPerVulnerability[vulnerability.url] = [];
229379
- }
229380
- if (!vulnerability.purl)
229381
- throw new Error(`Vulnerability ${vulnerability.url} has no purl`);
229382
- if (!purlToIndex.has(vulnerability.purl)) {
229383
- throw new Error(`Vulnerability ${vulnerability.url} has no purl in sbomTaskArtifacts`);
229384
- }
229385
- const index2 = purlToIndex.get(vulnerability.purl);
229386
- if (!vulnerableArtifactIdsPerVulnerability[vulnerability.url].includes(index2)) {
229387
- vulnerableArtifactIdsPerVulnerability[vulnerability.url].push(index2);
229388
- }
229389
- }
229390
- return vulnerableArtifactIdsPerVulnerability;
229391
- }
229392
- function computeSBOMTaskArtifacts(dependencyTrees) {
229393
- const components = [];
229394
- const purlToIndex = /* @__PURE__ */ new Map();
229395
- for (const dependencyTree of dependencyTrees) {
229396
- const depIdentifierToPurl = Object.fromEntries(Object.entries(dependencyTree.transitiveDependencies).filter(([_depIdentifier, dep]) => dep.purlObj).map(([depIdentifier, dep]) => {
229397
- const purl = dep.purlObj.purlString;
229398
- if (purl && !purlToIndex.has(purl)) {
229399
- purlToIndex.set(purl, components.length);
229400
- const depTreeNode = dependencyTree.transitiveDependencies[depIdentifier];
229401
- components[purlToIndex.get(purl)] = {
229402
- type: depTreeNode.purlObj.type,
229403
- name: depTreeNode.purlObj.name,
229404
- version: depTreeNode.purlObj.version,
229405
- namespace: depTreeNode.purlObj.namespace,
229406
- adj: []
229407
- };
229408
- }
229409
- return [depIdentifier, purl];
229410
- }));
229411
- for (const [depIdentifier, purl] of Object.entries(depIdentifierToPurl)) {
229412
- const depTreeNode = dependencyTree.transitiveDependencies[depIdentifier];
229413
- if (!depTreeNode.purlObj) {
229414
- continue;
229415
- }
229416
- const component = components[purlToIndex.get(purl)];
229417
- depTreeNode.dependencies?.forEach((dep) => {
229418
- const depPurl = depIdentifierToPurl[dep];
229419
- const depIndex = purlToIndex.get(depPurl);
229420
- if (depIndex && !component.adj?.includes(depIndex)) {
229421
- component.adj.push(depIndex);
229422
- }
229423
- });
229424
- }
229403
+ } catch (e) {
229404
+ logger.debug("Unable to get git data. Is the folder even in a git repository?", e);
229425
229405
  }
229426
- return { artifacts: components, purlToIndex };
229427
229406
  }
229428
229407
 
229429
229408
  // dist/index.js
@@ -229459,7 +229438,7 @@ upgradePurls.name("upgrade-purls").argument("<path>", "File system path to the f
229459
229438
  });
229460
229439
  }).configureHelp({ sortOptions: true });
229461
229440
  var computeFixesAndUpgradePurlsCmd = new Command();
229462
- computeFixesAndUpgradePurlsCmd.name("compute-fixes-and-upgrade-purls").argument("<path>", "File system path to the folder containing the project").option("-a, --apply-fixes-to <ghsas...>", 'GHSA IDs to compute fixes for. Use "all" to compute fixes for all vulnerabilities.', []).option("--dry-run", "Show what changes would be made without actually making them", false).option("-g, --glob <pattern>", "Glob pattern to filter workspaces by absolute file path").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("--range-style <style>", 'Range style to use for the output. Currently only "pin" is supported and it only works for npm.').option("--disable-major-updates", "Do not suggest major updates. If only major update are available, the fix will not be applied.", false).option("-o, --output-file <file>", "Writes output to a JSON file").option("--minimum-release-age <minimumReleaseAge>", "Do not allow upgrades to package versions that are newer than minimumReleaseAge. Format is 2m, 5h, 3d or 1w").addOption(new Option("--run-without-docker", "Run package managers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).action(async (path2, options) => {
229441
+ computeFixesAndUpgradePurlsCmd.name("compute-fixes-and-upgrade-purls").argument("<path>", "File system path to the folder containing the project").option("-a, --apply-fixes-to <ghsas...>", 'GHSA IDs to compute fixes for. Use "all" to compute fixes for all vulnerabilities.', []).option("--dry-run", "Show what changes would be made without actually making them", false).option("-g, --glob <pattern>", "Glob pattern to filter workspaces by absolute file path").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("--range-style <style>", 'Range style to use for the output. Currently only "pin" is supported and it only works for npm.').option("--disable-major-updates", "Do not suggest major updates. If only major update are available, the fix will not be applied.", false).option("-o, --output-file <file>", "Writes output to a JSON file").option("--minimum-release-age <minimumReleaseAge>", "Do not allow upgrades to package versions that are newer than minimumReleaseAge. Format is 2m, 5h, 3d or 1w").option("--show-affected-direct-dependencies", "Show the affected direct dependencies for each vulnerability and what upgrades could fix them - does not apply the upgrades.", false).addOption(new Option("--run-without-docker", "Run package managers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).action(async (path2, options) => {
229463
229442
  process.env.DOCKER_IMAGE_TAG ??= version2;
229464
229443
  if (options.outputFile && !options.outputFile.endsWith(".json")) {
229465
229444
  throw new Error("Output file must have a .json extension");