@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
53 lines • 2.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AstInterfaceNameAnalyzer = void 0;
const NamingViolation_1 = require("../../../domain/value-objects/NamingViolation");
const constants_1 = require("../../../shared/constants");
const rules_1 = require("../../../shared/constants/rules");
const detectorPatterns_1 = require("../../constants/detectorPatterns");
/**
* AST-based analyzer for detecting interface naming violations
*
* Analyzes interface declaration nodes to ensure proper naming conventions:
* - Domain layer: Repository interfaces must start with 'I' (e.g., IUserRepository)
* - All layers: Interfaces should be PascalCase
*/
class AstInterfaceNameAnalyzer {
/**
* Analyzes an interface declaration node
*/
analyze(node, layer, filePath, _lines) {
if (node.type !== constants_1.AST_CLASS_TYPES.INTERFACE_DECLARATION) {
return null;
}
const nameNode = node.childForFieldName(constants_1.AST_FIELD_NAMES.NAME);
if (!nameNode) {
return null;
}
const interfaceName = nameNode.text;
const lineNumber = nameNode.startPosition.row + 1;
if (!/^[A-Z][a-zA-Z0-9]*$/.test(interfaceName)) {
return NamingViolation_1.NamingViolation.create(interfaceName, rules_1.NAMING_VIOLATION_TYPES.WRONG_CASE, layer, `${filePath}:${String(lineNumber)}`, detectorPatterns_1.NAMING_ERROR_MESSAGES.INTERFACE_PASCAL_CASE, interfaceName, detectorPatterns_1.NAMING_ERROR_MESSAGES.USE_PASCAL_CASE_INTERFACE);
}
if (layer === rules_1.LAYERS.DOMAIN) {
return this.checkDomainInterface(interfaceName, filePath, lineNumber);
}
return null;
}
/**
* Checks domain layer interface naming
*/
checkDomainInterface(interfaceName, filePath, lineNumber) {
if (interfaceName.endsWith(detectorPatterns_1.PATTERN_WORDS.REPOSITORY)) {
if (!interfaceName.startsWith(detectorPatterns_1.PATTERN_WORDS.I_PREFIX)) {
return NamingViolation_1.NamingViolation.create(interfaceName, rules_1.NAMING_VIOLATION_TYPES.WRONG_PREFIX, rules_1.LAYERS.DOMAIN, `${filePath}:${String(lineNumber)}`, detectorPatterns_1.NAMING_ERROR_MESSAGES.REPOSITORY_INTERFACE_I_PREFIX, interfaceName, `Rename to I${interfaceName}`);
}
if (!/^I[A-Z][a-zA-Z0-9]*Repository$/.test(interfaceName)) {
return NamingViolation_1.NamingViolation.create(interfaceName, rules_1.NAMING_VIOLATION_TYPES.WRONG_CASE, rules_1.LAYERS.DOMAIN, `${filePath}:${String(lineNumber)}`, detectorPatterns_1.NAMING_ERROR_MESSAGES.REPOSITORY_INTERFACE_PATTERN, interfaceName);
}
}
return null;
}
}
exports.AstInterfaceNameAnalyzer = AstInterfaceNameAnalyzer;
//# sourceMappingURL=AstInterfaceNameAnalyzer.js.map