@@ -107,7 +107,83 @@ export class DependenciesGraph {
107107 * Returns the edge related to the root component
108108 */
109109 findRootEdge ( ) : DependencyEdge | undefined {
110- return this . edges . find ( ( { id } ) => id === DependenciesGraph . ROOT_EDGE_ID ) ;
110+ return this . findEdgeById ( DependenciesGraph . ROOT_EDGE_ID ) ;
111+ }
112+
113+ findEdgeById ( edgeId : string ) : DependencyEdge | undefined {
114+ return this . edges . find ( ( { id } ) => id === edgeId ) ;
115+ }
116+
117+ /**
118+ * Finds all possible paths from the root to the specified package names
119+ * @param targetPackageNames Array of package names to find paths to
120+ * @returns An object mapping each target package name to an array of paths,
121+ * where each path is an array of node IDs representing the traversal from root to target
122+ */
123+ findPathsToPackages ( targetPackageNames : string [ ] ) : Record < string , string [ ] [ ] > {
124+ const result : Record < string , string [ ] [ ] > = { } ;
125+ const rootEdge = this . findRootEdge ( ) ;
126+
127+ // Initialize result object with empty arrays for each target package
128+ for ( const packageName of targetPackageNames ) {
129+ result [ packageName ] = [ ] ;
130+ }
131+
132+ if ( ! rootEdge ) {
133+ return result ; // Return empty result if no root edge found
134+ }
135+
136+ // Helper function to perform depth-first search
137+ const dfs = (
138+ currentEdgeId : string ,
139+ currentPath : string [ ] ,
140+ visited : Set < string >
141+ ) => {
142+ // Avoid cycles by checking if we've already visited this node
143+ if ( visited . has ( currentEdgeId ) ) {
144+ return ;
145+ }
146+
147+ visited . add ( currentEdgeId ) ;
148+ currentPath . push ( currentEdgeId ) ;
149+
150+ // Find the current edge
151+ const currentEdge = this . findEdgeById ( currentEdgeId ) ;
152+ // console.log(currentEdge)
153+ if ( ! currentEdge ) {
154+ // Remove the node from path and visited if it doesn't exist
155+ currentPath . pop ( ) ;
156+ visited . delete ( currentEdgeId ) ;
157+ return ;
158+ }
159+
160+ // Check if the current edge represents a package in our target list
161+ // const packageAttr = this.packages.get(currentEdge.attr?.pkgId ?? currentEdge.id);
162+ // console.log(currentEdge)
163+ // console.log(packageAttr)
164+ const parsed = dp . parse ( currentEdgeId ) ;
165+ if ( parsed . name ) {
166+ // console.log(packageAttr.name)
167+ if ( targetPackageNames . includes ( parsed . name ) ) {
168+ // Found a path to a target package, add it to results
169+ result [ parsed . name ] . push ( [ ...currentPath ] ) ;
170+ }
171+ }
172+
173+ // Visit all neighbors
174+ for ( const neighbor of currentEdge . neighbours ) {
175+ dfs ( neighbor . id , [ ...currentPath ] , new Set ( visited ) ) ;
176+ }
177+
178+ // Backtrack
179+ currentPath . pop ( ) ;
180+ visited . delete ( currentEdgeId ) ;
181+ } ;
182+
183+ // Start DFS from the root edge
184+ dfs ( rootEdge . id , [ ] , new Set ( ) ) ;
185+
186+ return result ;
111187 }
112188}
113189
0 commit comments