@socketsecurity/cli-with-sentry 1.7.0 → 1.8.1

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.
Files changed (27) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +5 -5
  3. package/dist/cli.js +268 -213
  4. package/dist/cli.js.map +1 -1
  5. package/dist/constants.js +4 -4
  6. package/dist/constants.js.map +1 -1
  7. package/dist/manifest-scripts/maven-extension/coana-maven-extension.jar +0 -0
  8. package/dist/manifest-scripts/socket-facts.init.gradle +2 -65
  9. package/dist/manifest-scripts/socket-facts.plugin.scala +75 -41
  10. package/dist/tsconfig.dts.tsbuildinfo +1 -1
  11. package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
  12. package/dist/types/commands/fix/generated-socket-facts.d.mts +4 -2
  13. package/dist/types/commands/fix/generated-socket-facts.d.mts.map +1 -1
  14. package/dist/types/commands/manifest/scripts/assemble.d.mts +1 -5
  15. package/dist/types/commands/manifest/scripts/assemble.d.mts.map +1 -1
  16. package/dist/types/commands/manifest/scripts/facts.d.mts +15 -9
  17. package/dist/types/commands/manifest/scripts/facts.d.mts.map +1 -1
  18. package/dist/types/commands/manifest/scripts/records.d.mts +2 -7
  19. package/dist/types/commands/manifest/scripts/records.d.mts.map +1 -1
  20. package/dist/types/commands/manifest/scripts/run.d.mts.map +1 -1
  21. package/dist/types/commands/manifest/scripts/sidecar.d.mts +3 -1
  22. package/dist/types/commands/manifest/scripts/sidecar.d.mts.map +1 -1
  23. package/external/blessed/vendor/tng.js +1 -1
  24. package/external/blessed-contrib/lib/widget/charts/bar.js +2 -2
  25. package/external/blessed-contrib/lib/widget/charts/line.js +2 -2
  26. package/external/blessed-contrib/lib/widget/table.js +3 -3
  27. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.8.1](https://github.com/SocketDev/socket-cli/releases/tag/v1.8.1) - 2026-10-12
8
+
9
+ ### Changed
10
+ - Updated the Coana CLI to v `15.12.7`.
11
+
12
+ ## [1.8.0](https://github.com/SocketDev/socket-cli/releases/tag/v1.8.0) - 2026-10-12
13
+
14
+ ### Changed
15
+ - Socket facts for Maven, Gradle and sbt builds now record each subproject's own dependency tree, so a package is attributed only to the subprojects that actually pull it in.
16
+ - `socket fix` now accepts existing Socket facts files instead of asking you to delete them first.
17
+ - Updated the Coana CLI to v `15.12.5`.
18
+
19
+ ### Fixed
20
+ - Socket facts for sbt builds now match sbt's own classpaths: dependencies pulled in by a version-conflict winner are no longer dropped, and sibling subprojects appear only in the configurations that actually depend on them.
21
+
7
22
  ## [1.7.0](https://github.com/SocketDev/socket-cli/releases/tag/v1.7.0) - 2026-10-09
8
23
 
9
24
  ### Changed
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Socket CLI
2
2
 
3
3
  [![Socket Badge](https://socket.dev/api/badge/npm/package/socket)](https://socket.dev/npm/package/socket)
4
- [![Follow @SocketSecurity](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.7.0/assets/fleet/badge-follow-x.svg)](https://twitter.com/SocketSecurity)
5
- [![Follow @socket.dev on Bluesky](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.7.0/assets/fleet/badge-follow-bluesky.svg)](https://bsky.app/profile/socket.dev)
4
+ [![Follow @SocketSecurity](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.8.1/assets/fleet/badge-follow-x.svg)](https://twitter.com/SocketSecurity)
5
+ [![Follow @socket.dev on Bluesky](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.8.1/assets/fleet/badge-follow-bluesky.svg)](https://bsky.app/profile/socket.dev)
6
6
 
7
7
  CLI for [Socket.dev](https://socket.dev) — scan dependencies, audit packages, apply security patches, and gate installs from your terminal or CI. This is the 1.x line of the published `socket` package on npm.
8
8
 
@@ -171,8 +171,8 @@ MIT
171
171
  <br/>
172
172
  <div align="center">
173
173
  <picture>
174
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.7.0/assets/fleet/socket-combomark-dark.svg">
175
- <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.7.0/assets/fleet/socket-combomark-light.svg">
176
- <img width="324" height="104" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.7.0/assets/fleet/socket-combomark-light.svg">
174
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.8.1/assets/fleet/socket-combomark-dark.svg">
175
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.8.1/assets/fleet/socket-combomark-light.svg">
176
+ <img width="324" height="104" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.8.1/assets/fleet/socket-combomark-light.svg">
177
177
  </picture>
178
178
  </div>
package/dist/cli.js CHANGED
@@ -1857,8 +1857,12 @@ withPaths = true) {
1857
1857
  };
1858
1858
  acc.set(factsFile, {
1859
1859
  components: facts.components.map(paths),
1860
- projects: (facts.projects ?? []).map(proj => ({
1860
+ projects: (facts.projects ?? []).map(({
1861
+ children: _children,
1862
+ ...proj
1863
+ }) => ({
1861
1864
  ...paths(proj),
1865
+ dependencies: [...(artifactPaths.directDependenciesByProject.get(proj.id) ?? [])],
1862
1866
  classpath: [...(artifactPaths.classpathByProject.get(proj.id) ?? [])]
1863
1867
  }))
1864
1868
  });
@@ -2670,16 +2674,17 @@ function renderResolutionErrorReport(failures, scannedConfigs = [], tool = 'grad
2670
2674
  }
2671
2675
 
2672
2676
  const PURL_TYPE_MAVEN = 'maven';
2673
- function assembleFacts(parsed, opts) {
2677
+ function assembleFacts(parsed, opts = {}) {
2674
2678
  const fileExists = opts.fileExists ?? fs$1.existsSync;
2675
2679
  const perRoot = buildPerRoot(parsed);
2676
- const {
2677
- directByRoot,
2678
- finalNodes
2679
- } = mergeById(perRoot);
2680
+ const finalNodes = mergeById(perRoot);
2681
+ const graphs = buildSubprojectGraphs(perRoot);
2680
2682
  const tool = parsed.tool || 'gradle';
2681
- const components = buildComponents(finalNodes, buildManifestFilesById(parsed, directByRoot, perRoot, opts.factsFileName));
2682
- const projects = opts.emitProjects === false ? [] : buildProjects(parsed, directByRoot, perRoot);
2683
+ const components = buildComponents(finalNodes);
2684
+ const {
2685
+ dependencies,
2686
+ projects
2687
+ } = buildDependencyGraph(parsed, graphs, components);
2683
2688
  const metadata = {
2684
2689
  format: 'socket-facts-sbom',
2685
2690
  tool,
@@ -2691,7 +2696,8 @@ function assembleFacts(parsed, opts) {
2691
2696
  const facts = projects.length ? {
2692
2697
  metadata,
2693
2698
  projects,
2694
- components
2699
+ components,
2700
+ dependencies
2695
2701
  } : {
2696
2702
  metadata,
2697
2703
  components
@@ -2699,7 +2705,7 @@ function assembleFacts(parsed, opts) {
2699
2705
  return {
2700
2706
  facts,
2701
2707
  report: buildReport(parsed),
2702
- artifactPaths: buildArtifactPaths(finalNodes, [...parsed.projects.values()], perRoot, fileExists)
2708
+ artifactPaths: buildArtifactPaths(finalNodes, [...parsed.projects.values()], graphs, fileExists)
2703
2709
  };
2704
2710
  }
2705
2711
 
@@ -2758,17 +2764,15 @@ function buildPerRoot(parsed) {
2758
2764
  // reachability, which needs each subproject's exact classpath.
2759
2765
  function mergeById(perRoot) {
2760
2766
  const finalNodes = new Map();
2761
- const directByRoot = new Map();
2762
- for (const [rootId, {
2767
+ for (const {
2763
2768
  nodes,
2764
2769
  prod
2765
- }] of perRoot) {
2770
+ } of perRoot.values()) {
2766
2771
  for (const [coordId, node] of nodes) {
2767
2772
  let fn = finalNodes.get(coordId);
2768
2773
  if (!fn) {
2769
2774
  fn = {
2770
2775
  coord: node.coord,
2771
- children: new Set(),
2772
2776
  prod: false,
2773
2777
  direct: false,
2774
2778
  project: node.project,
@@ -2782,56 +2786,14 @@ function mergeById(perRoot) {
2782
2786
  if (node.direct) {
2783
2787
  fn.direct = true;
2784
2788
  }
2785
- for (const c of node.children) {
2786
- fn.children.add(c);
2787
- }
2788
2789
  for (const t of node.targets) {
2789
2790
  fn.targets.add(t);
2790
2791
  }
2791
- if (node.direct) {
2792
- let d = directByRoot.get(rootId);
2793
- if (!d) {
2794
- d = new Set();
2795
- directByRoot.set(rootId, d);
2796
- }
2797
- d.add(coordId);
2798
- }
2799
- }
2800
- }
2801
- return {
2802
- finalNodes,
2803
- directByRoot
2804
- };
2805
- }
2806
- function buildManifestFilesById(parsed, directByRoot, perRoot, factsFileName) {
2807
- const buildFilesByCoord = new Map();
2808
- for (const [rootId, ids] of directByRoot) {
2809
- const root = perRoot.get(rootId);
2810
- const project = parsed.projects.get(root?.projectKey ?? '');
2811
- for (const id of ids) {
2812
- let set = buildFilesByCoord.get(id);
2813
- if (!set) {
2814
- set = new Set();
2815
- buildFilesByCoord.set(id, set);
2816
- }
2817
- const coord = root?.nodes.get(id)?.coord;
2818
- // Without a known declaring script, the project's build file, even one
2819
- // absent on disk: its presence marks the dependency direct here.
2820
- const declared = coord && project?.declaredIn.get(`${coord.group}:${coord.name}`);
2821
- const files = declared ?? [...(project?.buildFiles ?? []), ...(project?.missingBuildFiles ?? [])];
2822
- for (const f of files) {
2823
- set.add(f);
2824
- }
2825
2792
  }
2826
2793
  }
2827
- return new Map([...buildFilesByCoord].map(({
2828
- 0: id,
2829
- 1: buildFiles
2830
- }) => [id, [...(factsFileName ? [factsFileName] : []), ...[...buildFiles].sort()].map(file => ({
2831
- file
2832
- }))]));
2794
+ return finalNodes;
2833
2795
  }
2834
- function buildComponents(finalNodes, manifestFilesById) {
2796
+ function buildComponents(finalNodes) {
2835
2797
  return [...finalNodes.keys()].sort().map(id => {
2836
2798
  const fn = finalNodes.get(id);
2837
2799
  const c = fn.coord;
@@ -2865,92 +2827,188 @@ function buildComponents(finalNodes, manifestFilesById) {
2865
2827
  if (fn.project) {
2866
2828
  comp.firstParty = true;
2867
2829
  }
2868
- if (fn.children.size) {
2869
- comp.dependencies = [...fn.children].sort();
2870
- }
2871
- const manifestFiles = manifestFilesById.get(id);
2872
- if (manifestFiles) {
2873
- comp.manifestFiles = manifestFiles;
2874
- }
2875
2830
  return comp;
2876
2831
  });
2877
2832
  }
2878
- function buildProjects(parsed, directByRoot, perRoot) {
2879
- const directByProject = new Map();
2880
- for (const [rootId, ids] of directByRoot) {
2881
- const pk = perRoot.get(rootId)?.projectKey ?? '';
2882
- let set = directByProject.get(pk);
2883
- if (!set) {
2884
- set = new Set();
2885
- directByProject.set(pk, set);
2833
+
2834
+ // One graph per subproject, its configurations merged.
2835
+ function buildSubprojectGraphs(perRoot) {
2836
+ const graphs = new Map();
2837
+ for (const {
2838
+ nodes,
2839
+ projectKey
2840
+ } of perRoot.values()) {
2841
+ let g = graphs.get(projectKey);
2842
+ if (!g) {
2843
+ g = {
2844
+ children: new Map(),
2845
+ direct: new Set()
2846
+ };
2847
+ graphs.set(projectKey, g);
2886
2848
  }
2887
- for (const id of ids) {
2888
- set.add(id);
2849
+ for (const [coordId, node] of nodes) {
2850
+ let set = g.children.get(coordId);
2851
+ if (!set) {
2852
+ set = new Set();
2853
+ g.children.set(coordId, set);
2854
+ }
2855
+ for (const c of node.children) {
2856
+ set.add(c);
2857
+ }
2858
+ if (node.direct) {
2859
+ g.direct.add(coordId);
2860
+ }
2889
2861
  }
2890
2862
  }
2891
- const projects = [...parsed.projects.values()].map(p => {
2892
- const entry = {
2893
- id: p.projectKey,
2894
- type: PURL_TYPE_MAVEN,
2895
- namespace: p.group,
2896
- name: p.name,
2897
- ...(p.version ? {
2898
- version: p.version
2899
- } : {}),
2900
- subprojectDir: p.dir,
2901
- dependencies: [...(directByProject.get(p.projectKey) ?? [])].sort()
2902
- };
2903
- // A project without a build file of its own is defined by the scripts
2904
- // declaring its dependencies, e.g. the root build script.
2905
- const declared = [...new Set([...p.declaredIn.values()].flat())];
2906
- const files = p.buildFiles.length ? p.buildFiles : declared.length ? declared : p.missingBuildFiles;
2907
- if (files.length) {
2908
- entry.manifestFiles = [...files].sort().map(file => ({
2909
- file
2910
- }));
2863
+ return graphs;
2864
+ }
2865
+
2866
+ // Equal subtrees share an entry; partition refinement (coarsest bisimulation)
2867
+ // keeps that exact on cycles too.
2868
+ function buildDependencyGraph(parsed, graphs, components) {
2869
+ const componentIndex = new Map(components.map((c, i) => [c.id, i]));
2870
+ const vertexIds = new Map();
2871
+ const labels = [];
2872
+ const edges = [];
2873
+ const vertex = (projectKey, coordId) => {
2874
+ const key = `${projectKey}\t${coordId}`;
2875
+ let v = vertexIds.get(key);
2876
+ if (v === undefined) {
2877
+ v = labels.length;
2878
+ vertexIds.set(key, v);
2879
+ labels.push(componentIndex.get(coordId));
2880
+ edges.push([]);
2881
+ }
2882
+ return v;
2883
+ };
2884
+ for (const [projectKey, {
2885
+ children
2886
+ }] of graphs) {
2887
+ for (const [coordId, kids] of children) {
2888
+ const v = vertex(projectKey, coordId);
2889
+ for (const c of kids) {
2890
+ edges[v].push(vertex(projectKey, c));
2891
+ }
2911
2892
  }
2912
- return entry;
2913
- });
2914
- projects.sort((a, b) => {
2915
- const ka = `${a.subprojectDir} ${a.namespace}:${a.name}`;
2916
- const kb = `${b.subprojectDir} ${b.namespace}:${b.name}`;
2893
+ }
2894
+
2895
+ // Each round splits blocks by their children's blocks; a round that splits
2896
+ // nothing is stable.
2897
+ let block = [...labels];
2898
+ let blockCount = new Set(block).size;
2899
+ for (;;) {
2900
+ const ids = new Map();
2901
+ block = block.map((b, v) => {
2902
+ const childBlocks = [...new Set(edges[v].map(c => block[c]))].sort((x, y) => x - y);
2903
+ const sig = `${b}:${childBlocks.join(',')}`;
2904
+ let id = ids.get(sig);
2905
+ if (id === undefined) {
2906
+ id = ids.size;
2907
+ ids.set(sig, id);
2908
+ }
2909
+ return id;
2910
+ });
2911
+ if (ids.size === blockCount) {
2912
+ break;
2913
+ }
2914
+ blockCount = ids.size;
2915
+ }
2916
+ const byComponent = (a, b) => componentIndex.get(a) - componentIndex.get(b);
2917
+ const projects = [...parsed.projects.values()].map(p => ({
2918
+ p,
2919
+ roots: treeRoots(p.projectKey, graphs.get(p.projectKey), byComponent)
2920
+ })).sort((a, b) => {
2921
+ const ka = `${a.p.dir} ${a.p.group}:${a.p.name}`;
2922
+ const kb = `${b.p.dir} ${b.p.group}:${b.p.name}`;
2917
2923
  return ka < kb ? -1 : ka > kb ? 1 : 0;
2918
2924
  });
2919
- return projects;
2920
- }
2921
- function buildClasspathByProject(projects, perRoot) {
2922
- const idsByProjectKey = new Map();
2923
- for (const {
2924
- nodes,
2925
- projectKey
2926
- } of perRoot.values()) {
2927
- let set = idsByProjectKey.get(projectKey);
2928
- if (!set) {
2929
- set = new Set();
2930
- idsByProjectKey.set(projectKey, set);
2925
+
2926
+ // Post-order over the sorted projects, so the numbering is stable.
2927
+ const indexOfBlock = new Map();
2928
+ const vertexOfBlock = new Map();
2929
+ const dependencies = [];
2930
+ const visit = v => {
2931
+ const b = block[v];
2932
+ if (vertexOfBlock.has(b)) {
2933
+ return;
2931
2934
  }
2932
- for (const coordId of nodes.keys()) {
2933
- set.add(coordId);
2935
+ vertexOfBlock.set(b, v);
2936
+ for (const c of [...edges[v]].sort((x, y) => labels[x] - labels[y])) {
2937
+ visit(c);
2938
+ }
2939
+ indexOfBlock.set(b, dependencies.length);
2940
+ dependencies.push({
2941
+ component: labels[v]
2942
+ });
2943
+ };
2944
+ const indexOf = v => indexOfBlock.get(block[v]);
2945
+ for (const {
2946
+ p,
2947
+ roots
2948
+ } of projects) {
2949
+ for (const coordId of roots) {
2950
+ visit(vertex(p.projectKey, coordId));
2934
2951
  }
2935
2952
  }
2936
- const classpathByProject = new Map();
2937
- for (const p of projects) {
2938
- const key = p.projectKey;
2939
- let set = classpathByProject.get(key);
2940
- if (!set) {
2941
- set = new Set();
2942
- classpathByProject.set(key, set);
2953
+ for (const [b, v] of vertexOfBlock) {
2954
+ const children = [...new Set(edges[v].map(indexOf))].sort((x, y) => x - y);
2955
+ if (children.length) {
2956
+ dependencies[indexOfBlock.get(b)].children = children;
2943
2957
  }
2944
- for (const id of idsByProjectKey.get(p.projectKey) ?? []) {
2945
- set.add(id);
2958
+ }
2959
+ return {
2960
+ dependencies,
2961
+ projects: projects.map(({
2962
+ p,
2963
+ roots
2964
+ }) => {
2965
+ const entry = {
2966
+ id: p.projectKey,
2967
+ type: PURL_TYPE_MAVEN,
2968
+ namespace: p.group,
2969
+ name: p.name,
2970
+ ...(p.version ? {
2971
+ version: p.version
2972
+ } : {}),
2973
+ subprojectDir: p.dir,
2974
+ children: roots.map(coordId => indexOf(vertex(p.projectKey, coordId))).sort((x, y) => x - y)
2975
+ };
2976
+ if (p.buildFiles.length) {
2977
+ entry.manifestFiles = [...new Set(p.buildFiles)].sort().map(file => ({
2978
+ file
2979
+ }));
2980
+ }
2981
+ return entry;
2982
+ })
2983
+ };
2984
+ }
2985
+ function treeRoots(projectKey, graph, byComponent) {
2986
+ if (!graph) {
2987
+ return [];
2988
+ }
2989
+ const roots = [...graph.direct].sort(byComponent);
2990
+ const reached = new Set();
2991
+ const stack = [...roots];
2992
+ while (stack.length) {
2993
+ const id = stack.pop();
2994
+ if (!reached.has(id)) {
2995
+ reached.add(id);
2996
+ stack.push(...graph.children.get(id));
2946
2997
  }
2947
2998
  }
2948
- return new Map([...classpathByProject].map(({
2949
- 0: key,
2950
- 1: ids
2951
- }) => [key, [...ids].sort()]));
2999
+ const unreached = [...graph.children.keys()].filter(id => !reached.has(id));
3000
+ if (unreached.length) {
3001
+ throw new Error(`Resolved dependencies of ${projectKey} are not reachable from its direct dependencies: ${unreached.sort(byComponent).join(', ')}`);
3002
+ }
3003
+ return roots;
3004
+ }
3005
+ function byProject(projects, graphs, ids) {
3006
+ return new Map(projects.map(p => {
3007
+ const g = graphs.get(p.projectKey);
3008
+ return [p.projectKey, g ? [...ids(g)].sort() : []];
3009
+ }));
2952
3010
  }
2953
- function buildArtifactPaths(finalNodes, projects, perRoot, fileExists) {
3011
+ function buildArtifactPaths(finalNodes, projects, graphs, fileExists) {
2954
3012
  const pathsById = new Map();
2955
3013
  for (const [id, fn] of finalNodes) {
2956
3014
  if (!fn.project) {
@@ -2970,7 +3028,8 @@ function buildArtifactPaths(finalNodes, projects, perRoot, fileExists) {
2970
3028
  }
2971
3029
  return {
2972
3030
  pathsById,
2973
- classpathByProject: buildClasspathByProject(projects, perRoot)
3031
+ classpathByProject: byProject(projects, graphs, g => g.children.keys()),
3032
+ directDependenciesByProject: byProject(projects, graphs, g => g.direct)
2974
3033
  };
2975
3034
  }
2976
3035
  function buildReport(parsed) {
@@ -3146,8 +3205,7 @@ function serializeExcludePathPatterns(paths) {
3146
3205
  // project projectKey group name version dir
3147
3206
  // projectSrc projectKey path (--with-files only)
3148
3207
  // projectTgt projectKey path (--with-files only)
3149
- // projectBuild projectKey path [missing] (build-root-relative; `missing`: configured, absent on disk)
3150
- // declared projectKey group name path (script declaring the dependency; build-root-relative)
3208
+ // projectBuild projectKey path (build-root-relative; may be absent on disk)
3151
3209
  // root rootId projectKey config prod(0|1)
3152
3210
  // node rootId coordId group name version ext classifier direct(0|1) project
3153
3211
  // edge rootId parentCoordId childCoordId
@@ -3222,9 +3280,7 @@ function parseRecords(text) {
3222
3280
  dir: '',
3223
3281
  sources: [],
3224
3282
  targets: [],
3225
- buildFiles: [],
3226
- missingBuildFiles: [],
3227
- declaredIn: new Map()
3283
+ buildFiles: []
3228
3284
  };
3229
3285
  result.projects.set(key, p);
3230
3286
  }
@@ -3268,17 +3324,7 @@ function parseRecords(text) {
3268
3324
  break;
3269
3325
  case 'projectBuild':
3270
3326
  if (f[2]) {
3271
- const p = project(f[1] ?? '');
3272
- (f[3] === 'missing' ? p.missingBuildFiles : p.buildFiles).push(f[2]);
3273
- }
3274
- break;
3275
- case 'declared':
3276
- if (f[4]) {
3277
- const {
3278
- declaredIn
3279
- } = project(f[1] ?? '');
3280
- const ga = `${f[2] ?? ''}:${f[3] ?? ''}`;
3281
- declaredIn.set(ga, [...(declaredIn.get(ga) ?? []), f[4]]);
3327
+ project(f[1] ?? '').buildFiles.push(f[2]);
3282
3328
  }
3283
3329
  break;
3284
3330
  case 'root':
@@ -3419,9 +3465,7 @@ async function assembleFromRecords(tool, out, recordsFile) {
3419
3465
  artifactPaths,
3420
3466
  facts,
3421
3467
  report
3422
- } = assembleFacts(parsed, {
3423
- factsFileName
3424
- });
3468
+ } = assembleFacts(parsed);
3425
3469
  return {
3426
3470
  buildRoot: parsed.buildRoot || undefined,
3427
3471
  code: out.code,
@@ -8868,49 +8912,75 @@ async function getFixEnv() {
8868
8912
  };
8869
8913
  }
8870
8914
 
8871
- // Backed up so each fix attempt sees the pre-fix build after `git clean`.
8872
- async function generateSocketFactsForFix({
8873
- cwd,
8874
- excludePaths,
8875
- tmpDir
8876
- }) {
8877
- const {
8878
- factsPaths,
8879
- resolvedPathsSidecar
8880
- } = await runDynamicSbomInference({
8881
- cwd,
8882
- excludePaths,
8883
- sbtTmpDir: undefined,
8884
- sidecar: true,
8885
- withFiles: false
8915
+ async function backUp(sources, dir) {
8916
+ await fs.mkdir(dir, {
8917
+ recursive: true
8886
8918
  });
8887
- const sidecarFile = resolvedPathsSidecar ? path.join(tmpDir, 'sidecar.json') : undefined;
8888
- if (sidecarFile) {
8889
- await fs.writeFile(sidecarFile, JSON.stringify(resolvedPathsSidecar));
8890
- }
8891
- const paths = factsPaths.map(p => path.resolve(cwd, p));
8892
- const backups = await Promise.all(paths.map(async (source, index) => {
8893
- const backup = path.join(tmpDir, `${index}.json`);
8919
+ return await Promise.all(sources.map(async (source, index) => {
8920
+ const backup = path.join(dir, `${index}.json`);
8894
8921
  await fs.copyFile(source, backup);
8895
8922
  return {
8896
8923
  backup,
8897
8924
  source
8898
8925
  };
8899
8926
  }));
8927
+ }
8928
+ async function restoreAll(backups) {
8929
+ await Promise.all(backups.map(({
8930
+ backup,
8931
+ source
8932
+ }) => fs.copyFile(backup, source)));
8933
+ }
8934
+
8935
+ // Backed up so each fix attempt sees the pre-fix build after `git clean`, and
8936
+ // facts files already present are left as they were found.
8937
+ async function generateSocketFactsForFix({
8938
+ cwd,
8939
+ excludePaths,
8940
+ findFactsPaths,
8941
+ tmpDir
8942
+ }) {
8943
+ const existingPaths = await findFactsPaths();
8944
+ const originals = await backUp(existingPaths, path.join(tmpDir, 'existing'));
8945
+ const existing = new Set(existingPaths);
8946
+ const reset = async written => {
8947
+ await Promise.all(written.filter(p => !existing.has(p)).map(p => fs.rm(p, {
8948
+ force: true
8949
+ })));
8950
+ await restoreAll(originals);
8951
+ };
8952
+ let paths;
8953
+ let sidecarFile;
8954
+ try {
8955
+ const {
8956
+ factsPaths,
8957
+ resolvedPathsSidecar
8958
+ } = await runDynamicSbomInference({
8959
+ cwd,
8960
+ excludePaths,
8961
+ sbtTmpDir: undefined,
8962
+ sidecar: true,
8963
+ withFiles: false
8964
+ });
8965
+ paths = factsPaths.map(p => path.resolve(cwd, p));
8966
+ if (resolvedPathsSidecar) {
8967
+ sidecarFile = path.join(tmpDir, 'sidecar.json');
8968
+ await fs.writeFile(sidecarFile, JSON.stringify(resolvedPathsSidecar));
8969
+ }
8970
+ } catch (e) {
8971
+ // A failed build root aborts inference after others wrote their facts.
8972
+ await reset(await findFactsPaths());
8973
+ throw e;
8974
+ }
8975
+ const generated = new Set(paths);
8976
+ const backups = [...originals.filter(({
8977
+ source
8978
+ }) => !generated.has(source)), ...(await backUp(paths, path.join(tmpDir, 'generated')))];
8900
8979
  return {
8901
8980
  paths,
8902
8981
  sidecarFile,
8903
- async remove() {
8904
- await Promise.all(paths.map(p => fs.rm(p, {
8905
- force: true
8906
- })));
8907
- },
8908
- async restore() {
8909
- await Promise.all(backups.map(({
8910
- backup,
8911
- source
8912
- }) => fs.copyFile(backup, source)));
8913
- }
8982
+ remove: () => reset(paths),
8983
+ restore: () => restoreAll(backups)
8914
8984
  };
8915
8985
  }
8916
8986
 
@@ -9121,51 +9191,36 @@ async function coanaFixWithFacts(fixConfig, factsSlot) {
9121
9191
  // sibling manifest's references). --exclude stays separate as a hidden
9122
9192
  // legacy escape hatch for the narrower "fix-application only" semantic.
9123
9193
  const coanaExcludePatterns = [...exclude, ...excludePaths];
9124
- const findScanFilepaths = () => utils.getPackageFilesForScan(['.'], supportedFiles, {
9194
+ const findScanFilepaths = async () => (await utils.getPackageFilesForScan(['.'], supportedFiles, {
9125
9195
  additionalIgnores,
9126
9196
  config: socketConfig,
9127
9197
  cwd
9128
- });
9198
+ })).filter(p => !utils.isReachabilityReportPath(p, {
9199
+ cwd,
9200
+ outputPath: constants.DOT_SOCKET_DOT_FACTS_JSON
9201
+ }));
9129
9202
  const scanFilepaths = await findScanFilepaths();
9130
- // Facts files are analysis artifacts and must be removed before re-running fix.
9131
- const factsFiles = scanFilepaths.filter(utils.isSocketFactsFile);
9132
- if (factsFiles.length) {
9133
- if (!silence) {
9134
- spinner?.stop();
9135
- }
9136
- return {
9137
- ok: false,
9138
- message: 'Found Socket facts files in manifest files',
9139
- cause: `Delete the following ${words.pluralize('file', factsFiles.length)} before running socket fix again:\n` + factsFiles.map(p => ` - ${p}`).join('\n')
9140
- };
9141
- }
9142
9203
  if (factsSlot) {
9143
9204
  if (!silence) {
9144
9205
  spinner?.stop();
9145
9206
  logger.logger.info('Generating Socket facts for Gradle, sbt and Maven builds ...');
9146
9207
  }
9147
- try {
9148
- factsSlot.generated = await generateSocketFactsForFix({
9149
- cwd,
9150
- excludePaths,
9151
- tmpDir: factsSlot.tmpDir
9152
- });
9153
- } catch (e) {
9154
- // A failed build root aborts inference after others wrote their facts.
9155
- const partial = (await findScanFilepaths()).filter(utils.isSocketFactsFile);
9156
- await Promise.all(partial.map(p => fs$1.promises.rm(p, {
9157
- force: true
9158
- })));
9159
- throw e;
9160
- }
9161
- scanFilepaths.push(...factsSlot.generated.paths);
9208
+ factsSlot.generated = await generateSocketFactsForFix({
9209
+ cwd,
9210
+ excludePaths,
9211
+ findFactsPaths: async () => (await findScanFilepaths()).filter(utils.isSocketFactsFile),
9212
+ tmpDir: factsSlot.tmpDir
9213
+ });
9214
+ const known = new Set(scanFilepaths);
9215
+ scanFilepaths.push(...factsSlot.generated.paths.filter(p => !known.has(p)));
9162
9216
  if (!silence) {
9163
9217
  spinner?.start();
9164
9218
  }
9165
9219
  }
9166
9220
  const sidecarFile = factsSlot?.generated?.sidecarFile;
9167
- // Discovery only needs which artifacts the facts files resolve; applying
9168
- // fixes also needs each project's exact classpath from the sidecar.
9221
+ // Discovery only needs which artifacts the facts files resolve. Applying
9222
+ // fixes reads each project's tree; a Coana predating facts trees can only
9223
+ // tell from the sidecar's classpaths which projects resolve an artifact.
9169
9224
  const discoveryFlags = factsSlot ? ['--maven-use-only-socket-facts'] : [];
9170
9225
  const factsFlags = [...discoveryFlags, ...(sidecarFile ? ['--compute-artifacts-sidecar', sidecarFile] : [])];
9171
9226
  const uploadCResult = await utils.handleApiCall(sockSdk.uploadManifestFiles(orgSlug, scanFilepaths, {
@@ -24505,5 +24560,5 @@ process.on('unhandledRejection', async (reason, promise) => {
24505
24560
  // eslint-disable-next-line n/no-process-exit
24506
24561
  process.exit(1);
24507
24562
  });
24508
- //# debugId=679b39e8-2ace-4602-9ad0-c5cf11bec9e3
24563
+ //# debugId=e5b43908-d002-4c63-b2f7-4c7336aacdb4
24509
24564
  //# sourceMappingURL=cli.js.map