@samiyev/guardian
Version:
Research-backed code quality guardian for AI-assisted development. Detects hardcodes, secrets, circular deps, framework leaks, entity exposure, and 9 architecture violations. Enforces Clean Architecture/DDD principles. Works with GitHub Copilot, Cursor, W
86 lines • 2.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyGraph = void 0;
const BaseEntity_1 = require("./BaseEntity");
/**
* Represents dependency graph of the analyzed project
*/
class DependencyGraph extends BaseEntity_1.BaseEntity {
nodes;
constructor(id) {
super(id);
this.nodes = new Map();
}
addFile(file) {
const fileId = file.path.relative;
if (!this.nodes.has(fileId)) {
this.nodes.set(fileId, {
file,
dependencies: [],
dependents: [],
});
}
this.touch();
}
addDependency(from, to) {
const fromNode = this.nodes.get(from);
const toNode = this.nodes.get(to);
if (fromNode && toNode) {
if (!fromNode.dependencies.includes(to)) {
fromNode.dependencies.push(to);
}
if (!toNode.dependents.includes(from)) {
toNode.dependents.push(from);
}
this.touch();
}
}
getNode(filePath) {
return this.nodes.get(filePath);
}
getAllNodes() {
return Array.from(this.nodes.values());
}
findCycles() {
const cycles = [];
const visited = new Set();
const recursionStack = new Set();
const dfs = (nodeId, path) => {
visited.add(nodeId);
recursionStack.add(nodeId);
path.push(nodeId);
const node = this.nodes.get(nodeId);
if (node) {
for (const dep of node.dependencies) {
if (!visited.has(dep)) {
dfs(dep, [...path]);
}
else if (recursionStack.has(dep)) {
const cycleStart = path.indexOf(dep);
cycles.push(path.slice(cycleStart));
}
}
}
recursionStack.delete(nodeId);
};
for (const nodeId of this.nodes.keys()) {
if (!visited.has(nodeId)) {
dfs(nodeId, []);
}
}
return cycles;
}
getMetrics() {
const nodes = Array.from(this.nodes.values());
const totalFiles = nodes.length;
const totalDependencies = nodes.reduce((sum, node) => sum + node.dependencies.length, 0);
return {
totalFiles,
totalDependencies,
avgDependencies: totalFiles > 0 ? totalDependencies / totalFiles : 0,
maxDependencies: Math.max(...nodes.map((node) => node.dependencies.length), 0),
};
}
}
exports.DependencyGraph = DependencyGraph;
//# sourceMappingURL=DependencyGraph.js.map