socket 1.1.178 → 1.1.179

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/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@ 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.1.179](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.179) - 2026-09-24
8
+
9
+ ### Changed
10
+ - Updated the Coana CLI to v `15.10.55`.
11
+ - Generated Maven, Gradle and sbt `.socket.facts.json` files are now substantially smaller, making uploads for large JVM projects faster and more reliable.
12
+
13
+ ### Fixed
14
+ - Running `socket manifest maven` or `socket manifest scala` on a directory without a build now fails with a clear message, instead of crashing (Maven) or silently producing a bogus Socket facts file (sbt).
15
+
7
16
  ## [1.1.178](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.178) - 2026-09-23
8
17
 
9
18
  ### 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.1.178/assets/fleet/badge-follow-x.svg)](https://twitter.com/SocketSecurity)
5
- [![Follow @socket.dev on Bluesky](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.178/assets/fleet/badge-follow-bluesky.svg)](https://bsky.app/profile/socket.dev)
4
+ [![Follow @SocketSecurity](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.179/assets/fleet/badge-follow-x.svg)](https://twitter.com/SocketSecurity)
5
+ [![Follow @socket.dev on Bluesky](https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.179/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
 
@@ -138,8 +138,8 @@ MIT
138
138
  <br/>
139
139
  <div align="center">
140
140
  <picture>
141
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.178/assets/fleet/socket-combomark-dark.svg">
142
- <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.178/assets/fleet/socket-combomark-light.svg">
143
- <img width="324" height="104" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.178/assets/fleet/socket-combomark-light.svg">
141
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.179/assets/fleet/socket-combomark-dark.svg">
142
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.179/assets/fleet/socket-combomark-light.svg">
143
+ <img width="324" height="104" alt="Socket" src="https://raw.githubusercontent.com/SocketDev/socket-cli/v1.1.179/assets/fleet/socket-combomark-light.svg">
144
144
  </picture>
145
145
  </div>
package/dist/cli.js CHANGED
@@ -1821,6 +1821,10 @@ function reachMemoryLimitToMb(value) {
1821
1821
  // = classpath entries (jars / module output dirs); `sources` = module source
1822
1822
  // roots.
1823
1823
 
1824
+ function projectClasspathKey(project) {
1825
+ return `${project.subprojectDir} ${project.namespace ?? ''}:${project.name}`;
1826
+ }
1827
+
1824
1828
  // Coordinate-based (not `id`-based) so it also matches foreign SBOMs like
1825
1829
  // CycloneDX. Empty segments dropped.
1826
1830
  function mavenCoordinateKey(groupId, artifactId, type, classifier, version) {
@@ -1877,7 +1881,10 @@ function sortByPurl(entries) {
1877
1881
  function accumulateSidecar(acc, facts, artifactPaths, factsFile) {
1878
1882
  acc.set(factsFile, {
1879
1883
  components: facts.components.map(comp => attachPaths(comp, artifactPaths)),
1880
- projects: (facts.projects ?? []).map(proj => attachPaths(proj, artifactPaths))
1884
+ projects: (facts.projects ?? []).map(proj => ({
1885
+ ...attachPaths(proj, artifactPaths),
1886
+ classpath: [...(artifactPaths.classpathByProject.get(projectClasspathKey(proj)) ?? [])]
1887
+ }))
1881
1888
  });
1882
1889
  }
1883
1890
  function hasResolvedPathsSidecarEntries(sidecar) {
@@ -2283,6 +2290,39 @@ function formatMissingEnvVarRefs(missing) {
2283
2290
  return `references ${names}, which ${verb} not set in this environment`;
2284
2291
  }
2285
2292
 
2293
+ // PATH fallback when no `bin` and no project wrapper.
2294
+ const DEFAULT_BUILD_TOOL_BIN = {
2295
+ __proto__: null,
2296
+ gradle: 'gradle',
2297
+ maven: 'mvn',
2298
+ sbt: 'sbt'
2299
+ };
2300
+
2301
+ // Project-local wrapper, preferred because it pins the expected build-tool
2302
+ // version. sbt has no wrapper convention. POSIX names only (no win32 target).
2303
+ const BUILD_TOOL_WRAPPER = {
2304
+ __proto__: null,
2305
+ gradle: 'gradlew',
2306
+ maven: 'mvnw'
2307
+ };
2308
+
2309
+ // sbt happily runs in any directory, synthesizing a default project from its
2310
+ // name, so an sbt run outside a build yields a plausible but bogus SBOM. Maven
2311
+ // and Gradle refuse such a directory themselves.
2312
+ function looksLikeSbtBuild(projectDir) {
2313
+ return fs$1.existsSync(path.resolve(projectDir, 'build.sbt')) || fs$1.existsSync(path.resolve(projectDir, 'project'));
2314
+ }
2315
+ function resolveBuildToolBin(tool, projectDir, bin) {
2316
+ if (bin) {
2317
+ return bin;
2318
+ }
2319
+ const wrapperName = BUILD_TOOL_WRAPPER[tool];
2320
+ if (wrapperName && fs$1.existsSync(path.resolve(projectDir, wrapperName))) {
2321
+ return `./${wrapperName}`;
2322
+ }
2323
+ return DEFAULT_BUILD_TOOL_BIN[tool];
2324
+ }
2325
+
2286
2326
  // Gradle's variant-aware resolver: distinct exceptions give mutually-exclusive
2287
2327
  // phrasing, so most-specific-first substring checks classify reliably.
2288
2328
  function classifyGradleFailure(detail) {
@@ -2646,10 +2686,10 @@ function assembleFacts(parsed, opts = {}) {
2646
2686
  const {
2647
2687
  directByRoot,
2648
2688
  finalNodes
2649
- } = mergePathSensitive(perRoot);
2689
+ } = mergeByCoordinate(perRoot);
2650
2690
  const tool = parsed.tool || 'gradle';
2651
2691
  const components = buildComponents(finalNodes);
2652
- const projects = opts.emitProjects === false ? [] : buildProjects(parsed, finalNodes, directByRoot, perRoot);
2692
+ const projects = opts.emitProjects === false ? [] : buildProjects(parsed, directByRoot, perRoot);
2653
2693
  const metadata = {
2654
2694
  format: 'socket-facts-sbom',
2655
2695
  tool,
@@ -2669,15 +2709,12 @@ function assembleFacts(parsed, opts = {}) {
2669
2709
  return {
2670
2710
  facts,
2671
2711
  report: buildReport(parsed),
2672
- artifactPaths: buildArtifactPaths(finalNodes, [...parsed.projects.values()], fileExists)
2712
+ artifactPaths: buildArtifactPaths(finalNodes, [...parsed.projects.values()], perRoot, fileExists)
2673
2713
  };
2674
2714
  }
2675
2715
  function gav(group, name, version) {
2676
2716
  return `${group}:${name}:${version}`;
2677
2717
  }
2678
- function shortHash(s) {
2679
- return require$$0.createHash('sha256').update(s, 'utf8').digest('hex').slice(0, 12);
2680
- }
2681
2718
  function buildPerRoot(parsed) {
2682
2719
  const out = new Map();
2683
2720
  for (const [rootId, r] of parsed.roots) {
@@ -2697,7 +2734,7 @@ function buildPerRoot(parsed) {
2697
2734
  for (const [coordId, n] of r.nodes) {
2698
2735
  nodes.set(coordId, {
2699
2736
  coord: n.coord,
2700
- children: [...(childrenByParent.get(coordId) ?? [])].sort(),
2737
+ children: [...(childrenByParent.get(coordId) ?? [])],
2701
2738
  direct: n.direct,
2702
2739
  targets: n.targets
2703
2740
  });
@@ -2711,62 +2748,10 @@ function buildPerRoot(parsed) {
2711
2748
  return out;
2712
2749
  }
2713
2750
 
2714
- // A coordinate with identical subtrees everywhere collapses to one node (id =
2715
- // coordId); divergent subtrees each get a content-addressed id
2716
- // (`<coordId>#<subtree-hash>`) so per-subproject overrides stay distinct.
2717
- function mergePathSensitive(perRoot) {
2718
- const memo = new Map();
2719
- const nodesOf = rootId => perRoot.get(rootId)?.nodes;
2720
- function computeSig(rootId, coordId, onPath) {
2721
- const memoKey = rootId + ' ' + coordId;
2722
- const cached = memo.get(memoKey);
2723
- if (cached !== undefined) {
2724
- return cached;
2725
- }
2726
- if (onPath.has(coordId)) {
2727
- // Cycle: back-edge as leaf.
2728
- return coordId;
2729
- }
2730
- const node = nodesOf(rootId)?.get(coordId);
2731
- if (!node) {
2732
- return coordId;
2733
- }
2734
- onPath.add(coordId);
2735
- const childSigs = node.children.map(c => computeSig(rootId, c, onPath));
2736
- onPath.delete(coordId);
2737
- // Digest, not the raw string: caching expanded subtree strings OOMs on
2738
- // reconverging DAGs; a fixed-size digest keeps the pass O(V+E).
2739
- const sig = coordId + '{' + childSigs.join(',') + '}';
2740
- const digest = require$$0.createHash('sha256').update(sig, 'utf8').digest('hex').slice(0, 16);
2741
- memo.set(memoKey, digest);
2742
- return digest;
2743
- }
2744
-
2745
- // Sorted iteration keeps cyclic-graph signatures stable run-to-run.
2746
- const sigsByCoord = new Map();
2747
- for (const rootId of [...perRoot.keys()].sort()) {
2748
- const nodes = perRoot.get(rootId).nodes;
2749
- for (const coordId of [...nodes.keys()].sort()) {
2750
- const sig = computeSig(rootId, coordId, new Set());
2751
- let set = sigsByCoord.get(coordId);
2752
- if (!set) {
2753
- set = new Set();
2754
- sigsByCoord.set(coordId, set);
2755
- }
2756
- set.add(sig);
2757
- }
2758
- }
2759
- const divergent = coordId => (sigsByCoord.get(coordId)?.size ?? 0) > 1;
2760
- const emittedIdMemo = new Map();
2761
- const emittedIdFor = (rootId, coordId) => {
2762
- const k = rootId + ' ' + coordId;
2763
- let v = emittedIdMemo.get(k);
2764
- if (v === undefined) {
2765
- v = divergent(coordId) ? coordId + '#' + shortHash(computeSig(rootId, coordId, new Set())) : coordId;
2766
- emittedIdMemo.set(k, v);
2767
- }
2768
- return v;
2769
- };
2751
+ // Components are merged by coordinate across every resolution root; which
2752
+ // coordinates belong to which subproject is kept separately (classpathByProject)
2753
+ // for reachability, which needs each subproject's exact classpath.
2754
+ function mergeByCoordinate(perRoot) {
2770
2755
  const finalNodes = new Map();
2771
2756
  const directByRoot = new Map();
2772
2757
  for (const [rootId, {
@@ -2774,8 +2759,7 @@ function mergePathSensitive(perRoot) {
2774
2759
  prod
2775
2760
  }] of perRoot) {
2776
2761
  for (const [coordId, node] of nodes) {
2777
- const eid = emittedIdFor(rootId, coordId);
2778
- let fn = finalNodes.get(eid);
2762
+ let fn = finalNodes.get(coordId);
2779
2763
  if (!fn) {
2780
2764
  fn = {
2781
2765
  coord: node.coord,
@@ -2784,7 +2768,7 @@ function mergePathSensitive(perRoot) {
2784
2768
  direct: false,
2785
2769
  targets: new Set()
2786
2770
  };
2787
- finalNodes.set(eid, fn);
2771
+ finalNodes.set(coordId, fn);
2788
2772
  }
2789
2773
  if (prod) {
2790
2774
  fn.prod = true;
@@ -2793,7 +2777,7 @@ function mergePathSensitive(perRoot) {
2793
2777
  fn.direct = true;
2794
2778
  }
2795
2779
  for (const c of node.children) {
2796
- fn.children.add(emittedIdFor(rootId, c));
2780
+ fn.children.add(c);
2797
2781
  }
2798
2782
  for (const t of node.targets) {
2799
2783
  fn.targets.add(t);
@@ -2804,7 +2788,7 @@ function mergePathSensitive(perRoot) {
2804
2788
  d = new Set();
2805
2789
  directByRoot.set(rootId, d);
2806
2790
  }
2807
- d.add(eid);
2791
+ d.add(coordId);
2808
2792
  }
2809
2793
  }
2810
2794
  }
@@ -2850,17 +2834,7 @@ function buildComponents(finalNodes) {
2850
2834
  return comp;
2851
2835
  });
2852
2836
  }
2853
- function buildProjects(parsed, finalNodes, directByRoot, perRoot) {
2854
- const idsByGav = new Map();
2855
- for (const [id, fn] of finalNodes) {
2856
- const key = gav(fn.coord.group, fn.coord.name, fn.coord.version ?? '');
2857
- let set = idsByGav.get(key);
2858
- if (!set) {
2859
- set = new Set();
2860
- idsByGav.set(key, set);
2861
- }
2862
- set.add(id);
2863
- }
2837
+ function buildProjects(parsed, directByRoot, perRoot) {
2864
2838
  const directByProject = new Map();
2865
2839
  for (const [rootId, ids] of directByRoot) {
2866
2840
  const pk = perRoot.get(rootId)?.projectKey ?? '';
@@ -2882,8 +2856,7 @@ function buildProjects(parsed, finalNodes, directByRoot, perRoot) {
2882
2856
  version: p.version
2883
2857
  } : {}),
2884
2858
  subprojectDir: p.dir,
2885
- dependencies: [...(directByProject.get(p.projectKey) ?? [])].sort(),
2886
- resolvedAs: [...(idsByGav.get(gav(p.group, p.name, p.version)) ?? [])].sort()
2859
+ dependencies: [...(directByProject.get(p.projectKey) ?? [])].sort()
2887
2860
  };
2888
2861
  return entry;
2889
2862
  });
@@ -2909,7 +2882,43 @@ function unionInto(map, key, add) {
2909
2882
  map.set(key, [...add]);
2910
2883
  }
2911
2884
  }
2912
- function buildArtifactPaths(finalNodes, projects, fileExists) {
2885
+ function buildClasspathByProject(projects, perRoot) {
2886
+ const idsByProjectKey = new Map();
2887
+ for (const {
2888
+ nodes,
2889
+ projectKey
2890
+ } of perRoot.values()) {
2891
+ let set = idsByProjectKey.get(projectKey);
2892
+ if (!set) {
2893
+ set = new Set();
2894
+ idsByProjectKey.set(projectKey, set);
2895
+ }
2896
+ for (const coordId of nodes.keys()) {
2897
+ set.add(coordId);
2898
+ }
2899
+ }
2900
+ const classpathByProject = new Map();
2901
+ for (const p of projects) {
2902
+ const key = projectClasspathKey({
2903
+ name: p.name,
2904
+ namespace: p.group,
2905
+ subprojectDir: p.dir
2906
+ });
2907
+ let set = classpathByProject.get(key);
2908
+ if (!set) {
2909
+ set = new Set();
2910
+ classpathByProject.set(key, set);
2911
+ }
2912
+ for (const id of idsByProjectKey.get(p.projectKey) ?? []) {
2913
+ set.add(id);
2914
+ }
2915
+ }
2916
+ return new Map([...classpathByProject].map(({
2917
+ 0: key,
2918
+ 1: ids
2919
+ }) => [key, [...ids].sort()]));
2920
+ }
2921
+ function buildArtifactPaths(finalNodes, projects, perRoot, fileExists) {
2913
2922
  const projectsByGav = new Map();
2914
2923
  for (const p of projects) {
2915
2924
  projectsByGav.set(gav(p.group, p.name, p.version), {
@@ -2970,7 +2979,8 @@ function buildArtifactPaths(finalNodes, projects, fileExists) {
2970
2979
  targetsByCoord,
2971
2980
  targetsByGav,
2972
2981
  sourcesByCoord,
2973
- coords
2982
+ coords,
2983
+ classpathByProject: buildClasspathByProject(projects, perRoot)
2974
2984
  };
2975
2985
  }
2976
2986
  function buildReport(parsed) {
@@ -2999,32 +3009,6 @@ function buildReport(parsed) {
2999
3009
  };
3000
3010
  }
3001
3011
 
3002
- // PATH fallback when no `bin` and no project wrapper.
3003
- const DEFAULT_BUILD_TOOL_BIN = {
3004
- __proto__: null,
3005
- gradle: 'gradle',
3006
- maven: 'mvn',
3007
- sbt: 'sbt'
3008
- };
3009
-
3010
- // Project-local wrapper, preferred because it pins the expected build-tool
3011
- // version. sbt has no wrapper convention. POSIX names only (no win32 target).
3012
- const BUILD_TOOL_WRAPPER = {
3013
- __proto__: null,
3014
- gradle: 'gradlew',
3015
- maven: 'mvnw'
3016
- };
3017
- function resolveBuildToolBin(tool, projectDir, bin) {
3018
- if (bin) {
3019
- return bin;
3020
- }
3021
- const wrapperName = BUILD_TOOL_WRAPPER[tool];
3022
- if (wrapperName && fs$1.existsSync(path.resolve(projectDir, wrapperName))) {
3023
- return `./${wrapperName}`;
3024
- }
3025
- return DEFAULT_BUILD_TOOL_BIN[tool];
3026
- }
3027
-
3028
3012
  // Single source of truth for --exclude-paths glob semantics against a JVM
3029
3013
  // build root's subproject dirs: anchored, relative, case-sensitive; `*`
3030
3014
  // within one path segment, `**` across zero or more segments, `?` within one
@@ -3592,6 +3576,11 @@ async function runManifestFacts({
3592
3576
  }
3593
3577
  resolvedJavaHome = expanded.value;
3594
3578
  }
3579
+ if (ecosystem === 'sbt' && !looksLikeSbtBuild(cwd)) {
3580
+ process.exitCode = 1;
3581
+ logger.logger.fail(`No sbt build found at \`${cwd}\` (expected a build.sbt file or a project directory).`);
3582
+ return null;
3583
+ }
3595
3584
  logger.logger.info(`Generating Socket facts for the ${ecosystem} project at \`${cwd}\` ...`);
3596
3585
  const scriptOpts = {
3597
3586
  bin: bin || undefined,
@@ -3701,7 +3690,11 @@ async function runManifestFacts({
3701
3690
  logger.logger.warn(`No resolvable ${ecosystem} dependencies found; nothing to upload.`);
3702
3691
  return;
3703
3692
  }
3704
- await fs$1.promises.writeFile(factsPath, JSON.stringify(facts, null, 2), 'utf8');
3693
+ const socketCliVersion = constants.default.ENV.INLINED_SOCKET_CLI_VERSION;
3694
+ if (facts.metadata && socketCliVersion) {
3695
+ facts.metadata.socketCliVersion = socketCliVersion;
3696
+ }
3697
+ await fs$1.promises.writeFile(factsPath, JSON.stringify(facts), 'utf8');
3705
3698
  if (withFiles && sidecarAcc) {
3706
3699
  // Key by the symlink-resolved path so the sidecar's keys are comparable
3707
3700
  // regardless of which caller's cwd it was joined against (the recursive
@@ -24138,5 +24131,5 @@ process.on('unhandledRejection', async (reason, promise) => {
24138
24131
  // eslint-disable-next-line n/no-process-exit
24139
24132
  process.exit(1);
24140
24133
  });
24141
- //# debugId=7293854f-1543-486e-ba22-c269ec717113
24134
+ //# debugId=3a134c7c-6936-4bbb-befc-4c0c7084f488
24142
24135
  //# sourceMappingURL=cli.js.map