@@ -21,6 +21,30 @@ type Vulnerability = {
2121 reachabilityData ?: unknown
2222}
2323
24+ type ReachabilityEntry = {
25+ type : 'reachable' | 'unreachable' | string
26+ workspacePath : string
27+ subprojectPath : string
28+ affectedPurls ?: Array < { type : string ; name : string ; version : string } >
29+ analysisLevel ?: string
30+ matches ?: Array <
31+ Array < {
32+ package : string
33+ sourceLocation : {
34+ start : { line : number ; column : number }
35+ end : { line : number ; column : number }
36+ filename : string
37+ }
38+ confidence : number
39+ } >
40+ >
41+ }
42+
43+ type ComponentReachability = {
44+ ghsa_id : string
45+ reachability : ReachabilityEntry [ ]
46+ }
47+
2448type Component = {
2549 id : string
2650 name : string
@@ -32,15 +56,7 @@ type Component = {
3256 dependencies : string [ ]
3357 manifestFiles : Array < { file : string ; start : number ; end : number } >
3458 vulnerabilities ?: Vulnerability [ ]
35- reachability ?: Array < {
36- ghsa_id : string
37- reachability : Array < {
38- type : string
39- affectedPurls : string [ ]
40- workspacePath : string
41- subprojectPath : string
42- } >
43- } >
59+ reachability ?: ComponentReachability [ ]
4460}
4561
4662type WorkspaceDiagnostic = {
@@ -181,6 +197,26 @@ function findComponent(
181197 return facts . components . find ( c => c . name === name && c . version === version )
182198}
183199
200+ /**
201+ * Find reachability entry for a specific GHSA ID and workspace path.
202+ */
203+ function findReachabilityForGhsa (
204+ component : Component ,
205+ ghsaId : string ,
206+ workspacePath : string ,
207+ ) : ReachabilityEntry | undefined {
208+ if ( ! component . reachability ) {
209+ return undefined
210+ }
211+ const ghsaReachability = component . reachability . find ( r => r . ghsa_id === ghsaId )
212+ if ( ! ghsaReachability ) {
213+ return undefined
214+ }
215+ return ghsaReachability . reachability . find (
216+ r => r . workspacePath === workspacePath ,
217+ )
218+ }
219+
184220/**
185221 * Helper to log command output for debugging.
186222 * Logs stdout and stderr to help diagnose test failures.
@@ -275,17 +311,60 @@ describe('socket scan reach (E2E tests)', async () => {
275311 // Verify specific known vulnerabilities are detected.
276312 const ghsaIds = getAllGhsaIds ( facts )
277313
278- // lodash@3.10.1 in package-b should have GHSA-35jh-r3h4-6jhm .
279- expect ( ghsaIds ) . toContain ( 'GHSA-35jh-r3h4-6jhm ' )
314+ // lodash@3.10.1 in package-b should have GHSA-fvqr-27wr-82fm .
315+ expect ( ghsaIds ) . toContain ( 'GHSA-fvqr-27wr-82fm ' )
280316
281317 // Verify lodash@3.10.1 is present and has vulnerabilities.
282- const lodash = findComponent ( facts , 'lodash' , '3.10.1' )
283- expect ( lodash , 'lodash@3.10.1 should be present' ) . toBeDefined ( )
318+ const lodash3 = findComponent ( facts , 'lodash' , '3.10.1' )
319+ expect ( lodash3 , 'lodash@3.10.1 should be present' ) . toBeDefined ( )
284320 expect (
285- lodash ?. vulnerabilities ?. length ,
321+ lodash3 ?. vulnerabilities ?. length ,
286322 'lodash@3.10.1 should have vulnerabilities' ,
287323 ) . toBeGreaterThan ( 0 )
288324
325+ // Verify reachability analysis was performed on lodash@3.10.1.
326+ expect (
327+ lodash3 ?. reachability ,
328+ 'lodash@3.10.1 should have reachability data' ,
329+ ) . toBeDefined ( )
330+ expect (
331+ lodash3 ?. reachability ?. length ,
332+ 'lodash@3.10.1 should have reachability entries' ,
333+ ) . toBeGreaterThan ( 0 )
334+
335+ // Verify GHSA-fvqr-27wr-82fm is reachable in packages/package-b.
336+ const ghsaFvqrReachabilityPkgB = findReachabilityForGhsa (
337+ lodash3 ! ,
338+ 'GHSA-fvqr-27wr-82fm' ,
339+ 'packages/package-b' ,
340+ )
341+ expect (
342+ ghsaFvqrReachabilityPkgB ,
343+ 'GHSA-fvqr-27wr-82fm should have reachability data for packages/package-b' ,
344+ ) . toBeDefined ( )
345+ expect (
346+ ghsaFvqrReachabilityPkgB ?. type ,
347+ 'GHSA-fvqr-27wr-82fm should be reachable in packages/package-b' ,
348+ ) . toBe ( 'reachable' )
349+ expect ( ghsaFvqrReachabilityPkgB ?. analysisLevel ) . toBe ( 'function-level' )
350+ expect ( ghsaFvqrReachabilityPkgB ?. matches ) . toBeDefined ( )
351+
352+ // Verify GHSA-35jh-r3h4-6jhm is unreachable in packages/package-b.
353+ const ghsaFvqrReachabilityPkgA = findReachabilityForGhsa (
354+ lodash3 ! ,
355+ 'GHSA-35jh-r3h4-6jhm' ,
356+ 'packages/package-b' ,
357+ )
358+ expect (
359+ ghsaFvqrReachabilityPkgA ,
360+ 'GHSA-35jh-r3h4-6jhm should have reachability data for packages/package-b' ,
361+ ) . toBeDefined ( )
362+ expect (
363+ ghsaFvqrReachabilityPkgA ?. type ,
364+ 'GHSA-35jh-r3h4-6jhm should be unreachable in packages/package-b' ,
365+ ) . toBe ( 'unreachable' )
366+
367+
289368 // Verify component structure.
290369 for ( const component of facts . components . slice ( 0 , 5 ) ) {
291370 expect ( component ) . toHaveProperty ( 'id' )
0 commit comments