@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
JavaScript
"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