1import { DefaultDependencyKind, DependencyKind, Package } from '../Packages'; 2import PackagesGraphEdge from './PackagesGraphEdge'; 3 4/** 5 * A graph node that refers to the single package. 6 */ 7export default class PackagesGraphNode { 8 /** 9 * The package represented by the node. 10 */ 11 pkg: Package; 12 13 /** 14 * The package name. 15 */ 16 name: string; 17 18 /** 19 * Indicates how deep the node is placed in the graph. 20 * Depth of nodes without incoming edges is equal to `0`. 21 */ 22 depth: number = 0; 23 24 /** 25 * Edges connecting this node with its dependencies. 26 */ 27 outgoingEdges: PackagesGraphEdge[] = []; 28 29 /** 30 * Edges connecting this node with its dependents. 31 */ 32 incomingEdges: PackagesGraphEdge[] = []; 33 34 constructor(pkg: Package) { 35 this.pkg = pkg; 36 this.name = pkg.packageName; 37 } 38 39 getOutgoingEdgeForNode(node: PackagesGraphNode): PackagesGraphEdge | null { 40 return this.outgoingEdges.find((edge) => edge.destination === node) ?? null; 41 } 42 43 getIncomingEdgeForNode(node: PackagesGraphNode): PackagesGraphEdge | null { 44 return this.incomingEdges.find((edge) => edge.origin === node) ?? null; 45 } 46 47 getAllDependentEdges(kinds: DependencyKind[] = DefaultDependencyKind): PackagesGraphEdge[] { 48 const allDependentEdges = this.incomingEdges 49 .map((edge) => { 50 if (!edge.isCyclic && kinds.includes(edge.getDominantKind())) { 51 return [edge, ...edge.origin.getAllDependentEdges(kinds)]; 52 } 53 return []; 54 }) 55 .flat(); 56 57 return [...new Set(allDependentEdges)]; 58 } 59 60 getAllDependents(kinds: DependencyKind[] = DefaultDependencyKind): PackagesGraphNode[] { 61 return [...new Set(this.getAllDependentEdges(kinds).map((edge) => edge.origin))]; 62 } 63 64 getAllDependencyEdges(kinds: DependencyKind[] = DefaultDependencyKind): PackagesGraphEdge[] { 65 const allDependencyEdges = this.outgoingEdges 66 .map((edge) => { 67 if (!edge.isCyclic && kinds.includes(edge.getDominantKind())) { 68 return [edge, ...edge.destination.getAllDependencyEdges(kinds)]; 69 } 70 return []; 71 }) 72 .flat(); 73 74 return [...new Set(allDependencyEdges)]; 75 } 76 77 getAllDependencies(kinds: DependencyKind[] = DefaultDependencyKind): PackagesGraphNode[] { 78 return [...new Set(this.getAllDependencyEdges(kinds).map((edge) => edge.destination))]; 79 } 80 81 getOutgoingEdgesOfKinds(kinds: DependencyKind[]): PackagesGraphEdge[] { 82 return this.outgoingEdges.filter((edge) => { 83 return kinds.some((kind) => edge.isOfKind(kind)); 84 }); 85 } 86 87 isDependentOf(node: PackagesGraphNode): boolean { 88 return !!this.getOutgoingEdgeForNode(node); 89 } 90 91 isDependencyOf(node: PackagesGraphNode): boolean { 92 return !!this.getIncomingEdgeForNode(node); 93 } 94} 95