UNPKG

@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

93 lines 3.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AstConfigObjectAnalyzer = void 0; const HardcodedValue_1 = require("../../domain/value-objects/HardcodedValue"); const rules_1 = require("../../shared/constants/rules"); const ast_node_types_1 = require("../../shared/constants/ast-node-types"); const defaults_1 = require("../constants/defaults"); /** * AST-based analyzer for detecting configuration objects with hardcoded values * * Detects objects that contain multiple hardcoded values that should be * extracted to a configuration file. * * Example: * const config = { timeout: 5000, retries: 3, url: "http://..." } */ class AstConfigObjectAnalyzer { contextChecker; MIN_HARDCODED_VALUES = 2; constructor(contextChecker) { this.contextChecker = contextChecker; } /** * Analyzes an object expression and returns a violation if it contains many hardcoded values */ analyze(node, lines) { if (node.type !== "object") { return null; } if (this.contextChecker.isInExportedConstant(node)) { return null; } if (this.contextChecker.isInTypeContext(node)) { return null; } const hardcodedCount = this.countHardcodedValues(node); if (hardcodedCount < this.MIN_HARDCODED_VALUES) { return null; } return this.createViolation(node, hardcodedCount, lines); } /** * Counts hardcoded values in an object */ countHardcodedValues(objectNode) { let count = 0; for (const child of objectNode.children) { if (child.type === "pair") { const value = child.childForFieldName("value"); if (value && this.isHardcodedValue(value)) { count++; } } } return count; } /** * Checks if a node is a hardcoded value */ isHardcodedValue(node) { if (node.type === "number") { const value = parseInt(node.text, 10); return !defaults_1.ALLOWED_NUMBERS.has(value) && value >= 100; } if (node.type === "string") { const stringFragment = node.children.find((c) => c.type === ast_node_types_1.AST_STRING_TYPES.STRING_FRAGMENT); return stringFragment !== undefined && stringFragment.text.length > 3; } return false; } /** * Creates a HardcodedValue violation for a config object */ createViolation(node, hardcodedCount, lines) { const lineNumber = node.startPosition.row + 1; const column = node.startPosition.column; const context = lines[node.startPosition.row]?.trim() ?? ""; const objectPreview = this.getObjectPreview(node); return HardcodedValue_1.HardcodedValue.create(`Configuration object with ${String(hardcodedCount)} hardcoded values: ${objectPreview}`, rules_1.HARDCODE_TYPES.MAGIC_CONFIG, lineNumber, column, context); } /** * Gets a preview of the object for the violation message */ getObjectPreview(node) { const text = node.text; if (text.length <= 50) { return text; } return `${text.substring(0, 47)}...`; } } exports.AstConfigObjectAnalyzer = AstConfigObjectAnalyzer; //# sourceMappingURL=AstConfigObjectAnalyzer.js.map