Files
puaros/packages/guardian/src/domain/value-objects/FrameworkLeak.ts
imfozilbek a34ca85241 chore: refactor hardcoded values to constants (v0.5.1)
Major internal refactoring to eliminate hardcoded values and improve
maintainability. Guardian now fully passes its own quality checks!

Changes:
- Extract all RepositoryViolation messages to domain constants
- Extract all framework leak template strings to centralized constants
- Extract all layer paths to infrastructure constants
- Extract all regex patterns to IMPORT_PATTERNS constant
- Add 30+ new constants for better maintainability

New files:
- src/infrastructure/constants/paths.ts (layer paths, patterns)
- src/domain/constants/Messages.ts (25+ repository messages)
- src/domain/constants/FrameworkCategories.ts (framework categories)
- src/shared/constants/layers.ts (layer names)

Impact:
- Reduced hardcoded values from 37 to 1 (97% improvement)
- Guardian passes its own src/ directory checks with 0 violations
- All 292 tests still passing (100% pass rate)
- No breaking changes - fully backwards compatible

Test results:
- 292 tests passing (100% pass rate)
- 96.77% statement coverage
- 83.82% branch coverage
2025-11-24 20:12:08 +05:00

97 lines
2.4 KiB
TypeScript

import { ValueObject } from "./ValueObject"
import { FRAMEWORK_LEAK_MESSAGES } from "../../shared/constants/rules"
import {
DEFAULT_FRAMEWORK_CATEGORY_DESCRIPTION,
FRAMEWORK_CATEGORY_DESCRIPTIONS,
} from "../constants/FrameworkCategories"
interface FrameworkLeakProps {
readonly packageName: string
readonly filePath: string
readonly layer: string
readonly category: string
readonly line?: number
}
/**
* Represents a framework leak violation in the codebase
*
* A framework leak occurs when a domain layer file imports a framework-specific package,
* creating tight coupling and violating Clean Architecture principles.
*
* @example
* ```typescript
* // Bad: Domain layer importing Prisma
* const leak = FrameworkLeak.create(
* '@prisma/client',
* 'src/domain/User.ts',
* 'domain',
* 'ORM',
* 5
* )
*
* console.log(leak.getMessage())
* // "Domain layer imports framework-specific package "@prisma/client". Use interfaces and dependency injection instead."
* ```
*/
export class FrameworkLeak extends ValueObject<FrameworkLeakProps> {
private constructor(props: FrameworkLeakProps) {
super(props)
}
public static create(
packageName: string,
filePath: string,
layer: string,
category: string,
line?: number,
): FrameworkLeak {
return new FrameworkLeak({
packageName,
filePath,
layer,
category,
line,
})
}
public get packageName(): string {
return this.props.packageName
}
public get filePath(): string {
return this.props.filePath
}
public get layer(): string {
return this.props.layer
}
public get category(): string {
return this.props.category
}
public get line(): number | undefined {
return this.props.line
}
public getMessage(): string {
return FRAMEWORK_LEAK_MESSAGES.DOMAIN_IMPORT.replace(
FRAMEWORK_LEAK_MESSAGES.PACKAGE_PLACEHOLDER,
this.props.packageName,
)
}
public getSuggestion(): string {
return FRAMEWORK_LEAK_MESSAGES.SUGGESTION
}
public getCategoryDescription(): string {
return (
FRAMEWORK_CATEGORY_DESCRIPTIONS[
this.props.category as keyof typeof FRAMEWORK_CATEGORY_DESCRIPTIONS
] || DEFAULT_FRAMEWORK_CATEGORY_DESCRIPTION
)
}
}