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

90 lines (89 loc) 2.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EntityExposure = void 0; const ValueObject_1 = require("./ValueObject"); const Messages_1 = require("../constants/Messages"); /** * Represents an entity exposure violation in the codebase * * Entity exposure occurs when a domain entity is directly exposed in API responses * instead of using DTOs (Data Transfer Objects). This violates the separation of concerns * and can lead to exposing internal domain logic to external clients. * * @example * ```typescript * // Bad: Controller returning domain entity * const exposure = EntityExposure.create( * 'User', * 'User', * 'src/infrastructure/controllers/UserController.ts', * 'infrastructure', * 25, * 'getUser' * ) * * console.log(exposure.getMessage()) * // "Method 'getUser' returns domain entity 'User' instead of DTO" * ``` */ class EntityExposure extends ValueObject_1.ValueObject { constructor(props) { super(props); } static create(entityName, returnType, filePath, layer, line, methodName) { return new EntityExposure({ entityName, returnType, filePath, layer, line, methodName, }); } get entityName() { return this.props.entityName; } get returnType() { return this.props.returnType; } get filePath() { return this.props.filePath; } get layer() { return this.props.layer; } get line() { return this.props.line; } get methodName() { return this.props.methodName; } getMessage() { const method = this.props.methodName ? `Method '${this.props.methodName}'` : Messages_1.ENTITY_EXPOSURE_MESSAGES.METHOD_DEFAULT; return `${method} returns domain entity '${this.props.entityName}' instead of DTO`; } getSuggestion() { const suggestions = [ `Create a DTO class (e.g., ${this.props.entityName}ResponseDto) in the application layer`, `Create a mapper to convert ${this.props.entityName} to ${this.props.entityName}ResponseDto`, `Update the method to return ${this.props.entityName}ResponseDto instead of ${this.props.entityName}`, ]; return suggestions.join("\n"); } getExampleFix() { return ` // ❌ Bad: Exposing domain entity async ${this.props.methodName || Messages_1.ENTITY_EXPOSURE_MESSAGES.METHOD_DEFAULT_NAME}(): Promise<${this.props.entityName}> { return await this.service.find() } // ✅ Good: Using DTO async ${this.props.methodName || Messages_1.ENTITY_EXPOSURE_MESSAGES.METHOD_DEFAULT_NAME}(): Promise<${this.props.entityName}ResponseDto> { const entity = await this.service.find() return ${this.props.entityName}Mapper.toDto(entity) }`; } } exports.EntityExposure = EntityExposure; //# sourceMappingURL=EntityExposure.js.map