tech-debt-score 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/DEVELOPMENT.md +147 -0
  2. package/LICENSE +21 -0
  3. package/README.md +200 -0
  4. package/SETUP_COMPLETE.md +188 -0
  5. package/TECHNICAL_DESIGN.md +563 -0
  6. package/dist/adapters/input/FileSystemReader.d.ts +11 -0
  7. package/dist/adapters/input/FileSystemReader.d.ts.map +1 -0
  8. package/dist/adapters/input/FileSystemReader.js +41 -0
  9. package/dist/adapters/input/FileSystemReader.js.map +1 -0
  10. package/dist/adapters/input/TypeScriptParser.d.ts +17 -0
  11. package/dist/adapters/input/TypeScriptParser.d.ts.map +1 -0
  12. package/dist/adapters/input/TypeScriptParser.js +305 -0
  13. package/dist/adapters/input/TypeScriptParser.js.map +1 -0
  14. package/dist/adapters/output/JsonExporter.d.ts +11 -0
  15. package/dist/adapters/output/JsonExporter.d.ts.map +1 -0
  16. package/dist/adapters/output/JsonExporter.js +46 -0
  17. package/dist/adapters/output/JsonExporter.js.map +1 -0
  18. package/dist/adapters/output/TerminalReporter.d.ts +13 -0
  19. package/dist/adapters/output/TerminalReporter.d.ts.map +1 -0
  20. package/dist/adapters/output/TerminalReporter.js +82 -0
  21. package/dist/adapters/output/TerminalReporter.js.map +1 -0
  22. package/dist/application/config/AnalysisConfig.d.ts +36 -0
  23. package/dist/application/config/AnalysisConfig.d.ts.map +1 -0
  24. package/dist/application/config/AnalysisConfig.js +19 -0
  25. package/dist/application/config/AnalysisConfig.js.map +1 -0
  26. package/dist/application/ports/IFileReader.d.ts +32 -0
  27. package/dist/application/ports/IFileReader.d.ts.map +1 -0
  28. package/dist/application/ports/IFileReader.js +6 -0
  29. package/dist/application/ports/IFileReader.js.map +1 -0
  30. package/dist/application/ports/IParser.d.ts +35 -0
  31. package/dist/application/ports/IParser.d.ts.map +1 -0
  32. package/dist/application/ports/IParser.js +6 -0
  33. package/dist/application/ports/IParser.js.map +1 -0
  34. package/dist/application/ports/IReporter.d.ts +24 -0
  35. package/dist/application/ports/IReporter.d.ts.map +1 -0
  36. package/dist/application/ports/IReporter.js +6 -0
  37. package/dist/application/ports/IReporter.js.map +1 -0
  38. package/dist/application/services/AnalysisService.d.ts +31 -0
  39. package/dist/application/services/AnalysisService.d.ts.map +1 -0
  40. package/dist/application/services/AnalysisService.js +161 -0
  41. package/dist/application/services/AnalysisService.js.map +1 -0
  42. package/dist/application/services/DependencyAnalyzer.d.ts +29 -0
  43. package/dist/application/services/DependencyAnalyzer.d.ts.map +1 -0
  44. package/dist/application/services/DependencyAnalyzer.js +128 -0
  45. package/dist/application/services/DependencyAnalyzer.js.map +1 -0
  46. package/dist/application/services/DuplicationDetector.d.ts +46 -0
  47. package/dist/application/services/DuplicationDetector.d.ts.map +1 -0
  48. package/dist/application/services/DuplicationDetector.js +165 -0
  49. package/dist/application/services/DuplicationDetector.js.map +1 -0
  50. package/dist/cli/commands/analyze.d.ts +2 -0
  51. package/dist/cli/commands/analyze.d.ts.map +1 -0
  52. package/dist/cli/commands/analyze.js +58 -0
  53. package/dist/cli/commands/analyze.js.map +1 -0
  54. package/dist/cli/index.d.ts +9 -0
  55. package/dist/cli/index.d.ts.map +1 -0
  56. package/dist/cli/index.js +76 -0
  57. package/dist/cli/index.js.map +1 -0
  58. package/dist/domain/entities/Finding.d.ts +42 -0
  59. package/dist/domain/entities/Finding.d.ts.map +1 -0
  60. package/dist/domain/entities/Finding.js +40 -0
  61. package/dist/domain/entities/Finding.js.map +1 -0
  62. package/dist/domain/entities/Metric.d.ts +38 -0
  63. package/dist/domain/entities/Metric.d.ts.map +1 -0
  64. package/dist/domain/entities/Metric.js +36 -0
  65. package/dist/domain/entities/Metric.js.map +1 -0
  66. package/dist/domain/entities/Rule.d.ts +41 -0
  67. package/dist/domain/entities/Rule.d.ts.map +1 -0
  68. package/dist/domain/entities/Rule.js +15 -0
  69. package/dist/domain/entities/Rule.js.map +1 -0
  70. package/dist/domain/entities/Score.d.ts +62 -0
  71. package/dist/domain/entities/Score.d.ts.map +1 -0
  72. package/dist/domain/entities/Score.js +40 -0
  73. package/dist/domain/entities/Score.js.map +1 -0
  74. package/dist/domain/index.d.ts +12 -0
  75. package/dist/domain/index.d.ts.map +1 -0
  76. package/dist/domain/index.js +14 -0
  77. package/dist/domain/index.js.map +1 -0
  78. package/dist/domain/rules/CircularDependencyRule.d.ts +13 -0
  79. package/dist/domain/rules/CircularDependencyRule.d.ts.map +1 -0
  80. package/dist/domain/rules/CircularDependencyRule.js +47 -0
  81. package/dist/domain/rules/CircularDependencyRule.js.map +1 -0
  82. package/dist/domain/rules/ComplexityRule.d.ts +15 -0
  83. package/dist/domain/rules/ComplexityRule.d.ts.map +1 -0
  84. package/dist/domain/rules/ComplexityRule.js +63 -0
  85. package/dist/domain/rules/ComplexityRule.js.map +1 -0
  86. package/dist/domain/rules/DuplicationRule.d.ts +15 -0
  87. package/dist/domain/rules/DuplicationRule.d.ts.map +1 -0
  88. package/dist/domain/rules/DuplicationRule.js +51 -0
  89. package/dist/domain/rules/DuplicationRule.js.map +1 -0
  90. package/dist/domain/rules/SizeRule.d.ts +16 -0
  91. package/dist/domain/rules/SizeRule.d.ts.map +1 -0
  92. package/dist/domain/rules/SizeRule.js +70 -0
  93. package/dist/domain/rules/SizeRule.js.map +1 -0
  94. package/dist/domain/rules/TypeSafetyRule.d.ts +13 -0
  95. package/dist/domain/rules/TypeSafetyRule.d.ts.map +1 -0
  96. package/dist/domain/rules/TypeSafetyRule.js +45 -0
  97. package/dist/domain/rules/TypeSafetyRule.js.map +1 -0
  98. package/dist/index.d.ts +2 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +2 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/shared/types.d.ts +16 -0
  103. package/dist/shared/types.d.ts.map +1 -0
  104. package/dist/shared/types.js +5 -0
  105. package/dist/shared/types.js.map +1 -0
  106. package/package.json +47 -0
  107. package/src/adapters/input/FileSystemReader.ts +51 -0
  108. package/src/adapters/input/TypeScriptParser.ts +367 -0
  109. package/src/adapters/output/JsonExporter.ts +48 -0
  110. package/src/adapters/output/TerminalReporter.ts +88 -0
  111. package/src/application/config/AnalysisConfig.ts +50 -0
  112. package/src/application/ports/IFileReader.ts +36 -0
  113. package/src/application/ports/IParser.ts +40 -0
  114. package/src/application/ports/IReporter.ts +26 -0
  115. package/src/application/services/AnalysisService.ts +199 -0
  116. package/src/application/services/DependencyAnalyzer.ts +158 -0
  117. package/src/application/services/DuplicationDetector.ts +207 -0
  118. package/src/cli/commands/analyze.ts +76 -0
  119. package/src/cli/index.ts +81 -0
  120. package/src/domain/entities/Finding.ts +79 -0
  121. package/src/domain/entities/Metric.ts +70 -0
  122. package/src/domain/entities/Rule.ts +49 -0
  123. package/src/domain/entities/Score.ts +94 -0
  124. package/src/domain/index.ts +15 -0
  125. package/src/domain/rules/CircularDependencyRule.ts +65 -0
  126. package/src/domain/rules/ComplexityRule.ts +88 -0
  127. package/src/domain/rules/DuplicationRule.ts +70 -0
  128. package/src/domain/rules/SizeRule.ts +98 -0
  129. package/src/domain/rules/TypeSafetyRule.ts +63 -0
  130. package/src/index.ts +0 -0
  131. package/src/shared/types.ts +18 -0
  132. package/tests/application/index.test.ts +12 -0
  133. package/tests/domain/index.test.ts +14 -0
  134. package/tests/e2e/index.test.ts +13 -0
  135. package/tsconfig.json +31 -0
@@ -0,0 +1,58 @@
1
+ import { resolve } from 'node:path';
2
+ import { AnalysisService } from '../../application/services/AnalysisService.js';
3
+ import { FileSystemReader } from '../../adapters/input/FileSystemReader.js';
4
+ import { TypeScriptParser } from '../../adapters/input/TypeScriptParser.js';
5
+ import { TerminalReporter } from '../../adapters/output/TerminalReporter.js';
6
+ import { JsonExporter } from '../../adapters/output/JsonExporter.js';
7
+ import { ComplexityRule } from '../../domain/rules/ComplexityRule.js';
8
+ import { SizeRule } from '../../domain/rules/SizeRule.js';
9
+ import { TypeSafetyRule } from '../../domain/rules/TypeSafetyRule.js';
10
+ import { DuplicationRule } from '../../domain/rules/DuplicationRule.js';
11
+ import { CircularDependencyRule } from '../../domain/rules/CircularDependencyRule.js';
12
+ import { DEFAULT_CONFIG } from '../../application/config/AnalysisConfig.js';
13
+ // Helper to broadcast to multiple reporters
14
+ class CompositeReporter {
15
+ constructor(reporters) {
16
+ this.reporters = reporters;
17
+ }
18
+ async generate(report) {
19
+ await Promise.all(this.reporters.map(r => r.generate(report)));
20
+ }
21
+ }
22
+ export async function analyzeCommand(rootPath, jsonOutputPath) {
23
+ console.log('🚀 Starting technical debt analysis...\n');
24
+ // Wiring: Create all adapters and services (dependency injection)
25
+ const fileReader = new FileSystemReader();
26
+ const parser = new TypeScriptParser();
27
+ // Use both terminal and JSON reporters
28
+ const reporter = new CompositeReporter([
29
+ new TerminalReporter(),
30
+ new JsonExporter(jsonOutputPath)
31
+ ]);
32
+ const rules = [
33
+ // ... rules
34
+ new ComplexityRule(),
35
+ new SizeRule(),
36
+ new TypeSafetyRule(),
37
+ new DuplicationRule(),
38
+ new CircularDependencyRule(),
39
+ ];
40
+ const analysisService = new AnalysisService(fileReader, parser, rules, reporter);
41
+ // Build configuration
42
+ // Smart pattern detection:
43
+ // - If scanning CWD, default to looking in 'src/'
44
+ // - If scanning a specific directory (e.g. ./src), look for files inside it
45
+ const isCwd = resolve(rootPath) === process.cwd();
46
+ const defaultPatterns = isCwd
47
+ ? DEFAULT_CONFIG.patterns
48
+ : ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];
49
+ const config = {
50
+ rootPath,
51
+ ...DEFAULT_CONFIG,
52
+ patterns: defaultPatterns,
53
+ };
54
+ // Execute analysis
55
+ await analysisService.analyze(config);
56
+ console.log('✅ Analysis complete!\n');
57
+ }
58
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../../src/cli/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAG5E,4CAA4C;AAC5C,MAAM,iBAAiB;IACrB,YAAoB,SAAsB;QAAtB,cAAS,GAAT,SAAS,CAAa;IAAG,CAAC;IAE9C,KAAK,CAAC,QAAQ,CAAC,MAAsB;QACnC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB,EAAE,cAAuB;IAC5E,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,kEAAkE;IAClE,MAAM,UAAU,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAEtC,uCAAuC;IACvC,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,IAAI,gBAAgB,EAAE;QACtB,IAAI,YAAY,CAAC,cAAc,CAAC;KACjC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG;QACZ,YAAY;QAEZ,IAAI,cAAc,EAAE;QACpB,IAAI,QAAQ,EAAE;QACd,IAAI,cAAc,EAAE;QACpB,IAAI,eAAe,EAAE;QACrB,IAAI,sBAAsB,EAAE;KAC7B,CAAC;IAEF,MAAM,eAAe,GAAG,IAAI,eAAe,CACzC,UAAU,EACV,MAAM,EACN,KAAK,EACL,QAAQ,CACT,CAAC;IAEF,sBAAsB;IACtB,2BAA2B;IAC3B,kDAAkD;IAClD,4EAA4E;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;IAElD,MAAM,eAAe,GAAG,KAAK;QAC3B,CAAC,CAAC,cAAc,CAAC,QAAQ;QACzB,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAmB;QAC7B,QAAQ;QACR,GAAG,cAAc;QACjB,QAAQ,EAAE,eAAe;KAC1B,CAAC;IAEF,mBAAmB;IACnB,MAAM,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point
4
+ * Command-line interface for tech-debt-score
5
+ *
6
+ * NO BUSINESS LOGIC HERE - just argument parsing and delegation
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI Entry Point
4
+ * Command-line interface for tech-debt-score
5
+ *
6
+ * NO BUSINESS LOGIC HERE - just argument parsing and delegation
7
+ */
8
+ import { analyzeCommand } from './commands/analyze.js';
9
+ async function main() {
10
+ const args = process.argv.slice(2);
11
+ if (args.includes('--help') || args.includes('-h')) {
12
+ printHelp();
13
+ process.exit(0);
14
+ }
15
+ // Parse arguments
16
+ let rootPath = process.cwd();
17
+ let jsonOutputPath;
18
+ for (let i = 0; i < args.length; i++) {
19
+ const arg = args[i];
20
+ if (!arg)
21
+ continue;
22
+ if (arg === '--json' || arg === '-j') {
23
+ const nextArg = args[i + 1];
24
+ if (nextArg && !nextArg.startsWith('-')) {
25
+ jsonOutputPath = nextArg;
26
+ i++; // Skip next arg
27
+ }
28
+ }
29
+ else if (!arg.startsWith('-')) {
30
+ rootPath = arg;
31
+ }
32
+ }
33
+ try {
34
+ await analyzeCommand(rootPath, jsonOutputPath);
35
+ process.exit(0);
36
+ }
37
+ catch (error) {
38
+ console.error('❌ Analysis failed:', error instanceof Error ? error.message : error);
39
+ process.exit(1);
40
+ }
41
+ }
42
+ function printHelp() {
43
+ console.log(`
44
+ ┌─────────────────────────────────────────────┐
45
+ │ tech-debt-score - Quantify Technical Debt │
46
+ │ Built by developers, for developers │
47
+ └─────────────────────────────────────────────┘
48
+
49
+ Usage:
50
+ tech-debt-score [path]
51
+
52
+ Arguments:
53
+ path Path to analyze (default: current directory)
54
+
55
+ Options:
56
+ -h, --help Show this help message
57
+
58
+ Examples:
59
+ tech-debt-score # Analyze current directory
60
+ tech-debt-score ./my-project # Analyze specific directory
61
+ tech-debt-score /path/to/code # Analyze absolute path
62
+
63
+ Options:
64
+ -h, --help Show this help message
65
+ -j, --json <file> Output JSON report to specific file
66
+
67
+
68
+ For more information, visit:
69
+ https://github.com/panduken/tech-debt-score
70
+ `);
71
+ }
72
+ // Run if executed directly
73
+ if (import.meta.url === `file://${process.argv[1]}`) {
74
+ main();
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kBAAkB;IAClB,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,cAAkC,CAAC;IAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,cAAc,GAAG,OAAO,CAAC;gBACzB,CAAC,EAAE,CAAC,CAAC,gBAAgB;YACvB,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,QAAQ,GAAG,GAAG,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BX,CAAC,CAAC;AACL,CAAC;AAED,2BAA2B;AAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Domain Entity: Finding
3
+ * Represents an identified issue or code smell in the codebase
4
+ */
5
+ import type { SourceLocation, Severity } from '../../shared/types.js';
6
+ export interface Finding {
7
+ /**
8
+ * ID of the rule that generated this finding
9
+ */
10
+ ruleId: string;
11
+ /**
12
+ * Severity level of the issue
13
+ */
14
+ severity: Severity;
15
+ /**
16
+ * Human-readable message describing the issue
17
+ */
18
+ message: string;
19
+ /**
20
+ * File path where the issue was found
21
+ */
22
+ filePath: string;
23
+ /**
24
+ * Optional exact location in the source code
25
+ */
26
+ location?: SourceLocation;
27
+ /**
28
+ * Optional suggestion for fixing the issue
29
+ */
30
+ suggestion?: string;
31
+ }
32
+ export declare class FindingBuilder {
33
+ private finding;
34
+ withRuleId(ruleId: string): this;
35
+ withSeverity(severity: Severity): this;
36
+ withMessage(message: string): this;
37
+ withFilePath(filePath: string): this;
38
+ withLocation(location: SourceLocation): this;
39
+ withSuggestion(suggestion: string): this;
40
+ build(): Finding;
41
+ }
42
+ //# sourceMappingURL=Finding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Finding.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/Finding.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtE,MAAM,WAAW,OAAO;IACtB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAwB;IAEvC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhC,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAKtC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAK5C,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKxC,KAAK,IAAI,OAAO;CAMjB"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Domain Entity: Finding
3
+ * Represents an identified issue or code smell in the codebase
4
+ */
5
+ export class FindingBuilder {
6
+ constructor() {
7
+ this.finding = {};
8
+ }
9
+ withRuleId(ruleId) {
10
+ this.finding.ruleId = ruleId;
11
+ return this;
12
+ }
13
+ withSeverity(severity) {
14
+ this.finding.severity = severity;
15
+ return this;
16
+ }
17
+ withMessage(message) {
18
+ this.finding.message = message;
19
+ return this;
20
+ }
21
+ withFilePath(filePath) {
22
+ this.finding.filePath = filePath;
23
+ return this;
24
+ }
25
+ withLocation(location) {
26
+ this.finding.location = location;
27
+ return this;
28
+ }
29
+ withSuggestion(suggestion) {
30
+ this.finding.suggestion = suggestion;
31
+ return this;
32
+ }
33
+ build() {
34
+ if (!this.finding.ruleId || !this.finding.severity || !this.finding.message || !this.finding.filePath) {
35
+ throw new Error('Finding requires ruleId, severity, message, and filePath');
36
+ }
37
+ return this.finding;
38
+ }
39
+ }
40
+ //# sourceMappingURL=Finding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Finding.js","sourceRoot":"","sources":["../../../src/domain/entities/Finding.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoCH,MAAM,OAAO,cAAc;IAA3B;QACU,YAAO,GAAqB,EAAE,CAAC;IAsCzC,CAAC;IApCC,UAAU,CAAC,MAAc;QACvB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAkB;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAwB;QACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,cAAc,CAAC,UAAkB;QAC/B,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtG,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,IAAI,CAAC,OAAkB,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Domain Entity: Metric
3
+ * Represents a single measurement extracted from code analysis
4
+ */
5
+ import type { SourceLocation } from '../../shared/types.js';
6
+ export interface Metric {
7
+ /**
8
+ * Unique identifier for the metric type
9
+ * e.g., 'cyclomatic-complexity', 'function-length', 'any-usage'
10
+ */
11
+ name: string;
12
+ /**
13
+ * The measured value
14
+ */
15
+ value: number;
16
+ /**
17
+ * File path where this metric was measured
18
+ */
19
+ filePath: string;
20
+ /**
21
+ * Optional location in the source code
22
+ */
23
+ location?: SourceLocation;
24
+ /**
25
+ * Optional context (e.g., function name, class name)
26
+ */
27
+ context?: string;
28
+ }
29
+ export declare class MetricBuilder {
30
+ private metric;
31
+ withName(name: string): this;
32
+ withValue(value: number): this;
33
+ withFilePath(filePath: string): this;
34
+ withLocation(location: SourceLocation): this;
35
+ withContext(context: string): this;
36
+ build(): Metric;
37
+ }
38
+ //# sourceMappingURL=Metric.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Metric.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/Metric.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,MAAM;IACrB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAuB;IAErC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK5B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAK5C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlC,KAAK,IAAI,MAAM;CAMhB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Domain Entity: Metric
3
+ * Represents a single measurement extracted from code analysis
4
+ */
5
+ export class MetricBuilder {
6
+ constructor() {
7
+ this.metric = {};
8
+ }
9
+ withName(name) {
10
+ this.metric.name = name;
11
+ return this;
12
+ }
13
+ withValue(value) {
14
+ this.metric.value = value;
15
+ return this;
16
+ }
17
+ withFilePath(filePath) {
18
+ this.metric.filePath = filePath;
19
+ return this;
20
+ }
21
+ withLocation(location) {
22
+ this.metric.location = location;
23
+ return this;
24
+ }
25
+ withContext(context) {
26
+ this.metric.context = context;
27
+ return this;
28
+ }
29
+ build() {
30
+ if (!this.metric.name || this.metric.value === undefined || !this.metric.filePath) {
31
+ throw new Error('Metric requires name, value, and filePath');
32
+ }
33
+ return this.metric;
34
+ }
35
+ }
36
+ //# sourceMappingURL=Metric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Metric.js","sourceRoot":"","sources":["../../../src/domain/entities/Metric.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgCH,MAAM,OAAO,aAAa;IAA1B;QACU,WAAM,GAAoB,EAAE,CAAC;IAiCvC,CAAC;IA/BC,QAAQ,CAAC,IAAY;QACnB,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAC,KAAa;QACrB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAgB;QAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,QAAwB;QACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC,MAAgB,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Domain Entity: Rule
3
+ * Represents an evaluation rule that processes metrics and generates findings
4
+ */
5
+ import type { Metric } from './Metric.js';
6
+ import type { Finding } from './Finding.js';
7
+ export interface Rule {
8
+ /**
9
+ * Unique identifier for this rule
10
+ */
11
+ id: string;
12
+ /**
13
+ * Human-readable name
14
+ */
15
+ name: string;
16
+ /**
17
+ * Description of what this rule evaluates
18
+ */
19
+ description: string;
20
+ /**
21
+ * Evaluate metrics and produce findings
22
+ */
23
+ evaluate(metrics: Metric[]): Finding[];
24
+ /**
25
+ * Calculate a score (0-100) based on findings
26
+ * where 100 = no issues, 0 = maximum issues
27
+ */
28
+ calculateScore(findings: Finding[]): number;
29
+ }
30
+ /**
31
+ * Abstract base class for rules
32
+ */
33
+ export declare abstract class BaseRule implements Rule {
34
+ readonly id: string;
35
+ readonly name: string;
36
+ readonly description: string;
37
+ constructor(id: string, name: string, description: string);
38
+ abstract evaluate(metrics: Metric[]): Finding[];
39
+ abstract calculateScore(findings: Finding[]): number;
40
+ }
41
+ //# sourceMappingURL=Rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rule.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/Rule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,IAAI;IACnB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;IAEvC;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;CAC7C;AAED;;GAEG;AACH,8BAAsB,QAAS,YAAW,IAAI;aAE1B,EAAE,EAAE,MAAM;aACV,IAAI,EAAE,MAAM;aACZ,WAAW,EAAE,MAAM;gBAFnB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM;IAGrC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IAC/C,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;CACrD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Domain Entity: Rule
3
+ * Represents an evaluation rule that processes metrics and generates findings
4
+ */
5
+ /**
6
+ * Abstract base class for rules
7
+ */
8
+ export class BaseRule {
9
+ constructor(id, name, description) {
10
+ this.id = id;
11
+ this.name = name;
12
+ this.description = description;
13
+ }
14
+ }
15
+ //# sourceMappingURL=Rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rule.js","sourceRoot":"","sources":["../../../src/domain/entities/Rule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiCH;;GAEG;AACH,MAAM,OAAgB,QAAQ;IAC5B,YACkB,EAAU,EACV,IAAY,EACZ,WAAmB;QAFnB,OAAE,GAAF,EAAE,CAAQ;QACV,SAAI,GAAJ,IAAI,CAAQ;QACZ,gBAAW,GAAX,WAAW,CAAQ;IAClC,CAAC;CAIL"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Domain Entity: Score
3
+ * Represents the technical debt score and category breakdowns
4
+ */
5
+ export interface CategoryScore {
6
+ /**
7
+ * Category name (e.g., 'Complexity', 'Size', 'Type Safety')
8
+ */
9
+ name: string;
10
+ /**
11
+ * Score for this category (0-100, where 100 = no debt)
12
+ */
13
+ score: number;
14
+ /**
15
+ * Weight of this category in the overall score (0-1)
16
+ */
17
+ weight: number;
18
+ /**
19
+ * Optional description of what this category measures
20
+ */
21
+ description?: string;
22
+ }
23
+ export interface Score {
24
+ /**
25
+ * Overall technical debt score (0-100, where 100 = no debt)
26
+ */
27
+ overall: number;
28
+ /**
29
+ * Breakdown by category
30
+ */
31
+ categories: CategoryScore[];
32
+ /**
33
+ * When this score was calculated
34
+ */
35
+ timestamp: Date;
36
+ /**
37
+ * Optional metadata about the analysis
38
+ */
39
+ metadata?: {
40
+ filesAnalyzed: number;
41
+ totalMetrics: number;
42
+ totalFindings: number;
43
+ };
44
+ }
45
+ export declare class ScoreCalculator {
46
+ /**
47
+ * Calculate overall score from category scores
48
+ *
49
+ * Formula: Σ(category_score × category_weight)
50
+ */
51
+ static calculateOverall(categories: CategoryScore[]): number;
52
+ /**
53
+ * Normalize a raw value to 0-100 scale
54
+ *
55
+ * @param value - The raw value to normalize
56
+ * @param min - Minimum value (maps to 100)
57
+ * @param max - Maximum value (maps to 0)
58
+ * @param invert - If true, higher values = better score
59
+ */
60
+ static normalize(value: number, min: number, max: number, invert?: boolean): number;
61
+ }
62
+ //# sourceMappingURL=Score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Score.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/Score.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,UAAU,EAAE,aAAa,EAAE,CAAC;IAE5B;;OAEG;IACH,SAAS,EAAE,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,qBAAa,eAAe;IAC1B;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,MAAM;IAiB5D;;;;;;;OAOG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM;CASlF"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Domain Entity: Score
3
+ * Represents the technical debt score and category breakdowns
4
+ */
5
+ export class ScoreCalculator {
6
+ /**
7
+ * Calculate overall score from category scores
8
+ *
9
+ * Formula: Σ(category_score × category_weight)
10
+ */
11
+ static calculateOverall(categories) {
12
+ // Validate weights sum to 1.0 (or close to it)
13
+ const totalWeight = categories.reduce((sum, cat) => sum + cat.weight, 0);
14
+ if (Math.abs(totalWeight - 1.0) > 0.01) {
15
+ throw new Error(`Category weights must sum to 1.0, got ${totalWeight}`);
16
+ }
17
+ // Calculate weighted average
18
+ const weightedSum = categories.reduce((sum, cat) => sum + (cat.score * cat.weight), 0);
19
+ // Round to 2 decimal places
20
+ return Math.round(weightedSum * 100) / 100;
21
+ }
22
+ /**
23
+ * Normalize a raw value to 0-100 scale
24
+ *
25
+ * @param value - The raw value to normalize
26
+ * @param min - Minimum value (maps to 100)
27
+ * @param max - Maximum value (maps to 0)
28
+ * @param invert - If true, higher values = better score
29
+ */
30
+ static normalize(value, min, max, invert = false) {
31
+ if (value <= min)
32
+ return invert ? 0 : 100;
33
+ if (value >= max)
34
+ return invert ? 100 : 0;
35
+ const normalized = ((value - min) / (max - min)) * 100;
36
+ const score = invert ? normalized : 100 - normalized;
37
+ return Math.round(score * 100) / 100;
38
+ }
39
+ }
40
+ //# sourceMappingURL=Score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Score.js","sourceRoot":"","sources":["../../../src/domain/entities/Score.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkDH,MAAM,OAAO,eAAe;IAC1B;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,UAA2B;QACjD,+CAA+C;QAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACzE,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,yCAAyC,WAAW,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,6BAA6B;QAC7B,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CACnC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAC5C,CAAC,CACF,CAAC;QAEF,4BAA4B;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC7C,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,SAAS,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,MAAM,GAAG,KAAK;QACtE,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1C,IAAI,KAAK,IAAI,GAAG;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1C,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC;QAErD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Domain Layer - Public API
3
+ * Exports all domain entities and services
4
+ */
5
+ export * from './entities/Metric.js';
6
+ export * from './entities/Finding.js';
7
+ export * from './entities/Score.js';
8
+ export * from './entities/Rule.js';
9
+ export * from './rules/ComplexityRule.js';
10
+ export * from './rules/SizeRule.js';
11
+ export * from './rules/TypeSafetyRule.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Domain Layer - Public API
3
+ * Exports all domain entities and services
4
+ */
5
+ // Entities
6
+ export * from './entities/Metric.js';
7
+ export * from './entities/Finding.js';
8
+ export * from './entities/Score.js';
9
+ export * from './entities/Rule.js';
10
+ // Rules
11
+ export * from './rules/ComplexityRule.js';
12
+ export * from './rules/SizeRule.js';
13
+ export * from './rules/TypeSafetyRule.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,WAAW;AACX,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AAEnC,QAAQ;AACR,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Domain Rule: Circular Dependency Rule
3
+ * Detects circular dependencies between modules
4
+ */
5
+ import { BaseRule } from '../entities/Rule.js';
6
+ import type { Metric } from '../entities/Metric.js';
7
+ import type { Finding } from '../entities/Finding.js';
8
+ export declare class CircularDependencyRule extends BaseRule {
9
+ constructor();
10
+ evaluate(metrics: Metric[]): Finding[];
11
+ calculateScore(findings: Finding[]): number;
12
+ }
13
+ //# sourceMappingURL=CircularDependencyRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CircularDependencyRule.d.ts","sourceRoot":"","sources":["../../../src/domain/rules/CircularDependencyRule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,qBAAa,sBAAuB,SAAQ,QAAQ;;IASlD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IA6BtC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;CAgB5C"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Domain Rule: Circular Dependency Rule
3
+ * Detects circular dependencies between modules
4
+ */
5
+ import { BaseRule } from '../entities/Rule.js';
6
+ import { FindingBuilder } from '../entities/Finding.js';
7
+ export class CircularDependencyRule extends BaseRule {
8
+ constructor() {
9
+ super('circular-dependency', 'Circular Dependency Rule', 'Detects circular dependencies between modules that can cause maintenance issues');
10
+ }
11
+ evaluate(metrics) {
12
+ const findings = [];
13
+ // Find circular dependency metrics
14
+ const circularDepMetrics = metrics.filter(m => m.name === 'circular-dependency');
15
+ for (const metric of circularDepMetrics) {
16
+ if (metric.value > 0) {
17
+ // Extract cycle information from context
18
+ const cycleLength = metric.value;
19
+ const severity = cycleLength >= 4 ? 'high' : cycleLength >= 3 ? 'medium' : 'low';
20
+ findings.push(new FindingBuilder()
21
+ .withRuleId(this.id)
22
+ .withSeverity(severity)
23
+ .withMessage(`Circular dependency detected: ${metric.context || 'module cycle'} (${cycleLength} files in cycle)`)
24
+ .withFilePath(metric.filePath)
25
+ .withSuggestion('Refactor to break the circular dependency by introducing interfaces or dependency injection')
26
+ .build());
27
+ }
28
+ }
29
+ return findings;
30
+ }
31
+ calculateScore(findings) {
32
+ if (findings.length === 0)
33
+ return 100;
34
+ // Circular dependencies are serious - heavy penalty
35
+ const penalty = findings.reduce((sum, finding) => {
36
+ switch (finding.severity) {
37
+ case 'high': return sum + 20; // Very bad
38
+ case 'medium': return sum + 12;
39
+ case 'low': return sum + 6;
40
+ default: return sum;
41
+ }
42
+ }, 0);
43
+ const score = Math.max(0, 100 - penalty);
44
+ return Math.round(score * 100) / 100;
45
+ }
46
+ }
47
+ //# sourceMappingURL=CircularDependencyRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CircularDependencyRule.js","sourceRoot":"","sources":["../../../src/domain/rules/CircularDependencyRule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;IAClD;QACE,KAAK,CACH,qBAAqB,EACrB,0BAA0B,EAC1B,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,QAAQ,CAAC,OAAiB;QACxB,MAAM,QAAQ,GAAc,EAAE,CAAC;QAE/B,mCAAmC;QACnC,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC;QAEjF,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,CAAC;YACxC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACrB,yCAAyC;gBACzC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;gBACjC,MAAM,QAAQ,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;gBAEjF,QAAQ,CAAC,IAAI,CACX,IAAI,cAAc,EAAE;qBACjB,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;qBACnB,YAAY,CAAC,QAAQ,CAAC;qBACtB,WAAW,CACV,iCAAiC,MAAM,CAAC,OAAO,IAAI,cAAc,KAAK,WAAW,kBAAkB,CACpG;qBACA,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;qBAC7B,cAAc,CAAC,6FAA6F,CAAC;qBAC7G,KAAK,EAAE,CACX,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,cAAc,CAAC,QAAmB;QAChC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QAEtC,oDAAoD;QACpD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YAC/C,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACzB,KAAK,MAAM,CAAC,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC,WAAW;gBACzC,KAAK,QAAQ,CAAC,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;gBAC/B,KAAK,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;gBAC3B,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC;YACtB,CAAC;QACH,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Domain Rule: Complexity Rule
3
+ * Evaluates cyclomatic complexity and nesting depth
4
+ */
5
+ import { BaseRule } from '../entities/Rule.js';
6
+ import type { Metric } from '../entities/Metric.js';
7
+ import type { Finding } from '../entities/Finding.js';
8
+ export declare class ComplexityRule extends BaseRule {
9
+ private readonly COMPLEXITY_THRESHOLD;
10
+ private readonly NESTING_THRESHOLD;
11
+ constructor();
12
+ evaluate(metrics: Metric[]): Finding[];
13
+ calculateScore(findings: Finding[]): number;
14
+ }
15
+ //# sourceMappingURL=ComplexityRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComplexityRule.d.ts","sourceRoot":"","sources":["../../../src/domain/rules/ComplexityRule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,qBAAa,cAAe,SAAQ,QAAQ;IAE1C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAM;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAK;;IAUvC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IA+CtC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;CAiB5C"}