@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
92 lines • 3.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FrameworkLeakDetector = void 0;
const FrameworkLeak_1 = require("../../domain/value-objects/FrameworkLeak");
const rules_1 = require("../../shared/constants/rules");
/**
* Detects framework-specific imports in domain layer
*
* This detector identifies violations where domain layer files import framework-specific packages,
* which creates tight coupling and violates Clean Architecture principles.
*
* The domain layer should only contain business logic and domain interfaces.
* Framework implementations should be in the infrastructure layer.
*
* @example
* ```typescript
* const detector = new FrameworkLeakDetector()
*
* // Detect leaks in a domain file
* const imports = ['@prisma/client', 'express', '../entities/User']
* const leaks = detector.detectLeaks(imports, 'src/domain/User.ts', 'domain')
*
* // leaks will contain violations for '@prisma/client' and 'express'
* console.log(leaks.length) // 2
* console.log(leaks[0].packageName) // '@prisma/client'
* console.log(leaks[0].category) // 'ORM'
* ```
*/
class FrameworkLeakDetector {
frameworkPackages;
constructor() {
this.frameworkPackages = this.buildFrameworkPackageMap();
}
/**
* Detects framework leaks in the given file
*
* @param imports - Array of import paths from the file
* @param filePath - Path to the file being analyzed
* @param layer - The architectural layer of the file (domain, application, infrastructure, shared)
* @returns Array of detected framework leaks
*/
detectLeaks(imports, filePath, layer) {
if (layer !== rules_1.LAYERS.DOMAIN) {
return [];
}
const leaks = [];
for (const importPath of imports) {
const category = this.getFrameworkCategory(importPath);
if (category) {
leaks.push(FrameworkLeak_1.FrameworkLeak.create(importPath, filePath, layer, category));
}
}
return leaks;
}
/**
* Checks if a specific import is a framework package
*
* @param importPath - The import path to check
* @returns True if the import is a framework package
*/
isFrameworkPackage(importPath) {
return this.frameworkPackages.has(importPath);
}
/**
* Gets the category of a framework package
*
* @param importPath - The import path to check
* @returns The category name if it's a framework package, undefined otherwise
*/
getFrameworkCategory(importPath) {
if (importPath.startsWith(".") || importPath.startsWith("/")) {
return undefined;
}
return this.frameworkPackages.get(importPath);
}
/**
* Builds a map of framework packages to their categories
*
* @returns Map of package names to category names
*/
buildFrameworkPackageMap() {
const map = new Map();
for (const [category, packages] of Object.entries(rules_1.FRAMEWORK_PACKAGES)) {
for (const pkg of packages) {
map.set(pkg, category);
}
}
return map;
}
}
exports.FrameworkLeakDetector = FrameworkLeakDetector;
//# sourceMappingURL=FrameworkLeakDetector.js.map