ts-analyzer 1.0.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.
package/README.md ADDED
@@ -0,0 +1,356 @@
1
+ # ts-analyzer
2
+
3
+ A comprehensive TypeScript codebase analyzer that provides detailed metrics on type safety, code complexity, and quality. Get actionable insights to improve your TypeScript projects.
4
+
5
+ ![NPM Version](https://img.shields.io/npm/v/ts-analyzer)
6
+ ![License](https://img.shields.io/npm/l/ts-analyzer)
7
+
8
+ > **Note**: This is the new and improved version of the previous `react-loc-analyzer` package, with enhanced TypeScript safety analysis, code complexity metrics, and better reports.
9
+
10
+ ## Features
11
+
12
+ - 🧪 **TypeScript Safety Analysis** with detailed type coverage metrics
13
+ - 📊 **Code Complexity Evaluation** for better maintainability
14
+ - 📏 **Detailed Code Statistics** with file type breakdown
15
+ - 📝 **Actionable Quality Recommendations** based on analysis
16
+ - 🎯 **Framework-Agnostic** works with any TypeScript project (React, Vue, Angular, Node.js)
17
+ - 🎨 **Beautiful Formatted Output** with colored terminal support
18
+ - ⚡ **Fast Performance** with asynchronous file processing
19
+ - ⚙️ **Highly Configurable** with customizable options
20
+
21
+ ## Installation
22
+
23
+ You can use it directly with npx (no installation required):
24
+
25
+ ```bash
26
+ npx ts-analyzer
27
+ ```
28
+
29
+ Or install it globally:
30
+
31
+ ```bash
32
+ npm install -g ts-analyzer
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ### Basic Usage
38
+
39
+ Analyze the current directory:
40
+ ```bash
41
+ npx ts-analyzer
42
+ ```
43
+
44
+ Analyze a specific directory:
45
+ ```bash
46
+ npx ts-analyzer /path/to/your/typescript/project
47
+ ```
48
+
49
+ ### Options
50
+
51
+ ```bash
52
+ npx ts-analyzer [directory] [options]
53
+
54
+ Options:
55
+ -V, --version output version number
56
+ -e, --exclude <patterns> additional patterns to exclude (comma-separated)
57
+ -i, --include <extensions> additional file extensions to include (comma-separated)
58
+ --no-color disable colored output
59
+ --no-safety disable TypeScript safety analysis
60
+ --no-complexity disable code complexity analysis
61
+ -h, --help display help for command
62
+ ```
63
+
64
+ ### Examples
65
+
66
+ Analyze with additional exclude patterns:
67
+ ```bash
68
+ npx ts-analyzer --exclude .cache,public,static
69
+ ```
70
+
71
+ Include additional file extensions:
72
+ ```bash
73
+ npx ts-analyzer --include .vue,.svelte
74
+ ```
75
+
76
+ Disable TypeScript safety analysis:
77
+ ```bash
78
+ npx ts-analyzer --no-safety
79
+ ```
80
+
81
+ ## Output
82
+
83
+ The analyzer provides four main sections of output:
84
+
85
+ ### 1. Project Summary
86
+ Shows overall statistics including:
87
+ - Total Files
88
+ - Total Lines
89
+ - Code Lines
90
+ - Comment Lines
91
+ - Empty Lines
92
+
93
+ ### 2. Files by Type
94
+ Detailed breakdown for each file extension:
95
+ - Number of files
96
+ - Total lines
97
+ - Code lines
98
+ - Comment lines
99
+ - Empty lines
100
+ - Percentage of codebase
101
+
102
+ ### 3. TypeScript Safety Analysis
103
+ Comprehensive TypeScript safety metrics:
104
+ - TypeScript Files Count
105
+ - Type Coverage Percentage
106
+ - Any Type Usage Count
107
+ - Type Assertions Count
108
+ - Type Safety Score
109
+ - Type Safety Rating
110
+
111
+ ### 4. Code Complexity Analysis
112
+ Detailed complexity metrics:
113
+ - Function Count
114
+ - Cyclomatic Complexity
115
+ - Nesting Depth
116
+ - Function Size
117
+ - Overall Complexity Rating
118
+
119
+ ### 5. Code Quality Recommendations
120
+ Actionable suggestions to improve your code quality.
121
+
122
+ ## Example Output
123
+
124
+ ```
125
+ Project Summary:
126
+ ┌───────────────┬────────────┐
127
+ │ Metric │ Value │
128
+ ├───────────────┼────────────┤
129
+ │ Total Files │ 156 │
130
+ │ Total Lines │ 15,234 │
131
+ │ Code Lines │ 12,845 │
132
+ │ Comment Lines │ 1,523 │
133
+ │ Empty Lines │ 866 │
134
+ └───────────────┴────────────┘
135
+
136
+ Files by Type:
137
+ ┌────────────┬───────┬─────────────┬────────────┬───────────────┐
138
+ │ Extension │ Files │ Total Lines │ Code Lines │ % of Codebase │
139
+ ├────────────┼───────┼─────────────┼────────────┼───────────────┤
140
+ │ .ts │ 87 │ 8,456 │ 7,234 │ 56.3% │
141
+ │ .tsx │ 45 │ 4,234 │ 3,845 │ 29.9% │
142
+ │ .js │ 23 │ 2,456 │ 1,923 │ 15.0% │
143
+ └────────────┴───────┴─────────────┴────────────┴───────────────┘
144
+
145
+ TypeScript Safety:
146
+ ┌─────────────────────┬───────────────────────┐
147
+ │ metric │ value │
148
+ ├─────────────────────┼───────────────────────┤
149
+ │ TypeScript Files │ 132 (84.6% of codebase)│
150
+ │ Type Coverage │ 92.3% (Good) │
151
+ │ Any Type Usage │ 12 │
152
+ │ Type Assertions │ 5 │
153
+ │ Non-Null Assertions │ 0 │
154
+ │ Type Safety Score │ 85/100 (Good ✓) │
155
+ │ Type Safety Rating │ Low │
156
+ └─────────────────────┴───────────────────────┘
157
+
158
+ Code Complexity:
159
+ ┌───────────────────────────┬────────────┐
160
+ │ metric │ value │
161
+ ├───────────────────────────┼────────────┤
162
+ │ Analyzed Files │ 110 │
163
+ │ Total Functions │ 345 │
164
+ │ Avg Cyclomatic Complexity │ 3.2 │
165
+ │ Max Cyclomatic Complexity │ 12 │
166
+ │ Avg Nesting Depth │ 2.1 │
167
+ │ Max Nesting Depth │ 6 │
168
+ │ Avg Function Size │ 12.5 lines │
169
+ │ Complex Files │ 3 │
170
+ │ Overall Complexity │ Simple ✓ │
171
+ └───────────────────────────┴────────────┘
172
+
173
+ 📝 Code Quality Recommendations:
174
+ • Reduce usage of 'any' type (found 12 instances) by using more specific types
175
+ • Consider refactoring functions with high complexity (max: 12) to improve maintainability
176
+ ```
177
+
178
+ ## TypeScript Safety Analysis
179
+
180
+ ### How TypeScript Safety Analysis Works
181
+
182
+ The TypeScript safety analyzer evaluates your TypeScript code quality by calculating several metrics. Here's how it works:
183
+
184
+ ```
185
+ ┌─────────────────────┐
186
+ │ TypeScript Files │
187
+ └─────────┬───────────┘
188
+
189
+
190
+ ┌─────────────────────┐ ┌─────────────────────┐
191
+ │ AST Analysis │───>│ Node Classification │
192
+ └─────────┬───────────┘ └─────────┬───────────┘
193
+ │ │
194
+ ▼ ▼
195
+ ┌─────────────────────┐ ┌─────────────────────┐
196
+ │ Explicitly Typed │ │ Implicitly Typed │
197
+ │ Nodes │ │ Nodes │
198
+ └─────────┬───────────┘ └─────────┬───────────┘
199
+ │ │
200
+ └──────────┬──────────────┘
201
+
202
+
203
+ ┌─────────────────────┐ ┌─────────────────────┐
204
+ │ Type Coverage │<───│ tsconfig.json │
205
+ │ Calculation │ │ Analysis │
206
+ └─────────┬───────────┘ └─────────────────────┘
207
+
208
+
209
+ ┌─────────────────────┐
210
+ │ "any" & Assertion │
211
+ │ Penalty Calculation │
212
+ └─────────┬───────────┘
213
+
214
+
215
+ ┌─────────────────────┐
216
+ │ Final Type Safety │
217
+ │ Score & Rating │
218
+ └─────────────────────┘
219
+ ```
220
+
221
+ ### Type Coverage Calculation
222
+
223
+ Type coverage measures what percentage of your code has proper type information, either through explicit type annotations or TypeScript's type inference.
224
+
225
+ ```typescript
226
+ // Example TypeScript code with various levels of typing
227
+
228
+ // Explicitly typed (counts as typed)
229
+ const userName: string = "John";
230
+
231
+ // Implicitly typed through inference (counts as typed)
232
+ const userAge = 30; // TypeScript infers 'number'
233
+
234
+ // Object with explicit interface (counts as typed)
235
+ interface User {
236
+ id: number;
237
+ name: string;
238
+ active: boolean;
239
+ }
240
+ const user: User = { id: 1, name: "Alice", active: true };
241
+
242
+ // Function with explicit type annotations (counts as typed)
243
+ function calculateTotal(prices: number[]): number {
244
+ return prices.reduce((sum, price) => sum + price, 0);
245
+ }
246
+
247
+ // Any type usage (counts as typed, but with penalty)
248
+ const userData: any = fetchUserData();
249
+
250
+ // No type annotation or clear inference (counts as untyped)
251
+ let someData;
252
+
253
+ // Type assertion (counts as typed, but with penalty)
254
+ const userInput = document.getElementById("user-input") as HTMLInputElement;
255
+ ```
256
+
257
+ ### Type Safety Score Formula
258
+
259
+ The type safety score (0-100) is calculated using the following formula:
260
+
261
+ ```
262
+ Type Safety Score = Coverage Score - Any Type Penalty - Type Assertion Penalty
263
+ ```
264
+
265
+ Where:
266
+ - **Coverage Score** = Type Coverage Percentage × 0.6 (60% weight)
267
+ - **Any Type Penalty** = (Any Type Count / Total Nodes) × 100 × 0.2 (20% weight)
268
+ - **Type Assertion Penalty** = (Type Assertions / Total Nodes) × 100 × 0.2 (20% weight)
269
+
270
+ ### TypeScript Configuration Impact
271
+
272
+ The analyzer checks your `tsconfig.json` for strict type checking options and awards bonus points:
273
+
274
+ | Configuration Option | Points |
275
+ |----------------------|--------|
276
+ | `strict: true` | 5 |
277
+ | `noImplicitAny: true`| 3 |
278
+ | `strictNullChecks: true` | 3 |
279
+ | `noImplicitReturns: true` | 2 |
280
+
281
+ ### Rating Scale
282
+
283
+ | Type Safety Score | Rating | Description |
284
+ |-------------------|--------|-------------|
285
+ | ≥ 80 | Good | Your TypeScript code is well-typed and maintains high type safety |
286
+ | 50-79 | Moderate | Your code has reasonable type safety but could be improved |
287
+ | < 50 | Poor | Your code has significant type safety issues that should be addressed |
288
+
289
+ ### Type Coverage Benchmarks
290
+
291
+ | Type Coverage | Rating | Description |
292
+ |---------------|--------|-------------|
293
+ | ≥ 95% | Excellent | Top-tier type safety, comparable to well-maintained libraries |
294
+ | 85-94% | Good | Strong type safety, suitable for production applications |
295
+ | 70-84% | Moderate | Acceptable type safety, but has room for improvement |
296
+ | < 70% | Needs Improvement | Type coverage is too low for reliable code |
297
+
298
+ ## Code Complexity Analysis
299
+
300
+ ### How Code Complexity Analysis Works
301
+
302
+ The complexity analyzer evaluates several aspects of your code structure to determine maintainability:
303
+
304
+ 1. **Cyclomatic Complexity**: Measures the number of independent paths through code
305
+ 2. **Nesting Depth**: Measures how deeply code blocks are nested
306
+ 3. **Function Size**: Measures average lines of code per function
307
+ 4. **Parameter Count**: Analyzes how many parameters functions receive
308
+
309
+ ### Complexity Rating Scale
310
+
311
+ | Complexity Score | Rating | Description |
312
+ |------------------|--------|-------------|
313
+ | < 30 | Simple | Your code is clean and easily maintainable |
314
+ | 30-60 | Moderate | Your code has reasonable complexity but watch for complex areas |
315
+ | > 60 | Complex | Your code may be difficult to maintain and test |
316
+
317
+ ## Why This Is Better Than react-loc-analyzer
318
+
319
+ The `ts-analyzer` is a significant improvement over the previous `react-loc-analyzer`:
320
+
321
+ 1. **TypeScript Specialization**: Built specifically for analyzing TypeScript codebases with deep type safety insights
322
+ 2. **Framework Agnostic**: Works with any TypeScript project, not just React
323
+ 3. **Advanced Metrics**: Provides sophisticated type coverage and code complexity metrics
324
+ 4. **Actionable Insights**: Generates specific recommendations to improve your code quality
325
+ 5. **Modern Implementation**: Fully written in TypeScript with strong typing throughout
326
+ 6. **Better Performance**: Optimized for faster analysis of large TypeScript projects
327
+
328
+ ## Default Configuration
329
+
330
+ ### Included File Extensions
331
+ - `.js`, `.jsx`, `.ts`, `.tsx`
332
+ - `.css`, `.scss`, `.sass`
333
+ - `.html`, `.json`
334
+
335
+ ### Default Ignore Patterns
336
+ - `node_modules`
337
+ - `build`
338
+ - `dist`
339
+ - `.git`
340
+ - `coverage`
341
+ - `.next`
342
+ - `out`
343
+
344
+ ## Contributing
345
+
346
+ Contributions are welcome! Please feel free to submit a Pull Request.
347
+
348
+ 1. Fork the repository
349
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
350
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
351
+ 4. Push to the branch (`git push origin feature/AmazingFeature`)
352
+ 5. Open a Pull Request
353
+
354
+ ## License
355
+
356
+ MIT License - see the [LICENSE](LICENSE) file for details
package/bin/cli.js ADDED
@@ -0,0 +1,4 @@
1
+
2
+ #!/usr/bin/env node
3
+
4
+ import '../dist/bin/cli.js';
package/bin/cli.ts ADDED
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env node
2
+ // bin/cli.ts
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { analyzeProject } from '../src/index.js';
7
+ import { formatTable } from '../src/table-formatter.js';
8
+
9
+ const program = new Command();
10
+
11
+ interface ProgramOptions {
12
+ exclude?: string;
13
+ include?: string;
14
+ color?: boolean;
15
+ safety?: boolean;
16
+ complexity?: boolean;
17
+ }
18
+
19
+ program
20
+ .name('ts-analyzer')
21
+ .description('Comprehensive TypeScript code analyzer with type safety and complexity metrics')
22
+ .version('1.1.2')
23
+ .argument('[dir]', 'project directory to analyze', '.')
24
+ .option('-e, --exclude <patterns>', 'additional patterns to exclude (comma-separated)')
25
+ .option('-i, --include <extensions>', 'additional file extensions to include (comma-separated)')
26
+ .option('--no-color', 'disable colored output')
27
+ .option('--no-safety', 'disable TypeScript safety analysis')
28
+ .option('--no-complexity', 'disable code complexity analysis')
29
+ .action(async (dir: string, options: ProgramOptions) => {
30
+ const spinner = ora('Analyzing React project...').start();
31
+ const useColors = options.color !== false;
32
+
33
+ try {
34
+ const extraExcludes = options.exclude ? options.exclude.split(',') : [];
35
+ const extraExtensions = options.include ? options.include.split(',').map(ext =>
36
+ ext.startsWith('.') ? ext : `.${ext}`
37
+ ) : [];
38
+
39
+ const stats = await analyzeProject(dir, {
40
+ excludePatterns: extraExcludes,
41
+ additionalExtensions: extraExtensions,
42
+ analyzeSafety: options.safety !== false,
43
+ analyzeComplexity: options.complexity !== false
44
+ });
45
+
46
+ spinner.succeed('Analysis complete!');
47
+
48
+ // Print summary table
49
+ console.log('\n' + (useColors ? chalk.bold.green('Project Summary:') : 'Project Summary:'));
50
+ formatTable([
51
+ { metric: 'Total Files', value: stats.formatNumber(stats.files) },
52
+ { metric: 'Total Lines', value: stats.formatNumber(stats.totalLines) },
53
+ { metric: 'Code Lines', value: stats.formatNumber(stats.codeLines) },
54
+ { metric: 'Comment Lines', value: stats.formatNumber(stats.commentLines) },
55
+ { metric: 'Empty Lines', value: stats.formatNumber(stats.emptyLines) }
56
+ ]);
57
+
58
+ // Print file types table
59
+ console.log('\n' + (useColors ? chalk.bold.green('Files by Type:') : 'Files by Type:'));
60
+ formatTable(stats.formattedFileTypes as any[]);
61
+
62
+ // Print TypeScript safety metrics if available
63
+ if (stats.typescriptSafety) {
64
+ console.log('\n' + (useColors ? chalk.bold.green('TypeScript Safety:') : 'TypeScript Safety:'));
65
+
66
+ // Prepare safety indicators
67
+ let safetyIndicator;
68
+ if (stats.typescriptSafety.avgTypeSafetyScore >= 80) {
69
+ safetyIndicator = useColors ? chalk.green('Good ✓') : 'Good ✓';
70
+ } else if (stats.typescriptSafety.avgTypeSafetyScore >= 50) {
71
+ safetyIndicator = useColors ? chalk.yellow('Moderate ⚠') : 'Moderate ⚠';
72
+ } else {
73
+ safetyIndicator = useColors ? chalk.red('Poor ✗') : 'Poor ✗';
74
+ }
75
+
76
+ let safetyRating;
77
+ if (stats.typescriptSafety.overallComplexity === 'Low') {
78
+ safetyRating = useColors ? chalk.green('Low') : 'Low';
79
+ } else if (stats.typescriptSafety.overallComplexity === 'Medium') {
80
+ safetyRating = useColors ? chalk.yellow('Medium') : 'Medium';
81
+ } else {
82
+ safetyRating = useColors ? chalk.red('High') : 'High';
83
+ }
84
+
85
+ // Create coverage evaluation
86
+ let coverageEvaluation;
87
+ const typeCoverage = parseFloat(stats.typescriptSafety.avgTypeCoverage);
88
+ if (typeCoverage >= 95) {
89
+ coverageEvaluation = useColors ? chalk.green('(Excellent)') : '(Excellent)';
90
+ } else if (typeCoverage >= 85) {
91
+ coverageEvaluation = useColors ? chalk.green('(Good)') : '(Good)';
92
+ } else if (typeCoverage >= 70) {
93
+ coverageEvaluation = useColors ? chalk.yellow('(Moderate)') : '(Moderate)';
94
+ } else {
95
+ coverageEvaluation = useColors ? chalk.red('(Needs Improvement)') : '(Needs Improvement)';
96
+ }
97
+
98
+ formatTable([
99
+ { metric: 'TypeScript Files', value: `${stats.formatNumber(stats.typescriptSafety.tsFileCount)} (${stats.typescriptSafety.tsPercentage}% of codebase)` },
100
+ { metric: 'Type Coverage', value: `${stats.typescriptSafety.avgTypeCoverage}% ${coverageEvaluation}` },
101
+ { metric: 'Any Type Usage', value: stats.formatNumber(stats.typescriptSafety.totalAnyCount) },
102
+ { metric: 'Type Assertions', value: stats.formatNumber(stats.typescriptSafety.totalAssertions) },
103
+ { metric: 'Non-Null Assertions', value: stats.formatNumber(stats.typescriptSafety.totalNonNullAssertions) },
104
+ { metric: 'Type Safety Score', value: `${stats.typescriptSafety.avgTypeSafetyScore}/100 (${safetyIndicator})` },
105
+ { metric: 'Type Safety Rating', value: safetyRating }
106
+ ]);
107
+
108
+ // Add explanation about TypeScript metrics
109
+ console.log('\n' + (useColors ? chalk.italic('Type Coverage:') : 'Type Coverage:'));
110
+ console.log(useColors
111
+ ? chalk.italic('• Measures the percentage of code elements that have proper type information')
112
+ : '• Measures the percentage of code elements that have proper type information');
113
+ console.log(useColors
114
+ ? chalk.italic('• Includes both explicit type annotations and TypeScript\'s type inference')
115
+ : '• Includes both explicit type annotations and TypeScript\'s type inference');
116
+ console.log(useColors
117
+ ? chalk.italic('• Industry standard for production TypeScript is 85-95% coverage')
118
+ : '• Industry standard for production TypeScript is 85-95% coverage');
119
+
120
+ console.log('\n' + (useColors ? chalk.italic('Type Safety Score:') : 'Type Safety Score:'));
121
+ console.log(useColors
122
+ ? chalk.italic('• Comprehensive evaluation that considers type coverage, "any" usage, and type assertions')
123
+ : '• Comprehensive evaluation that considers type coverage, "any" usage, and type assertions');
124
+ console.log(useColors
125
+ ? chalk.italic('• Also accounts for TypeScript configuration in tsconfig.json')
126
+ : '• Also accounts for TypeScript configuration in tsconfig.json');
127
+ }
128
+
129
+ // Print code complexity metrics if available
130
+ if (stats.codeComplexity) {
131
+ console.log('\n' + (useColors ? chalk.bold.green('Code Complexity:') : 'Code Complexity:'));
132
+
133
+ // Prepare complexity indicator
134
+ let complexityIndicator;
135
+ if (stats.codeComplexity.overallComplexity === 'Low') {
136
+ complexityIndicator = useColors ? chalk.green('Simple ✓') : 'Simple ✓';
137
+ } else if (stats.codeComplexity.overallComplexity === 'Medium') {
138
+ complexityIndicator = useColors ? chalk.yellow('Moderate ⚠') : 'Moderate ⚠';
139
+ } else {
140
+ complexityIndicator = useColors ? chalk.red('Complex ✗') : 'Complex ✗';
141
+ }
142
+
143
+ formatTable([
144
+ { metric: 'Analyzed Files', value: stats.formatNumber(stats.codeComplexity.analyzedFiles) },
145
+ { metric: 'Total Functions', value: stats.formatNumber(stats.codeComplexity.totalFunctions) },
146
+ { metric: 'Avg Cyclomatic Complexity', value: stats.codeComplexity.avgComplexity },
147
+ { metric: 'Max Cyclomatic Complexity', value: stats.formatNumber(stats.codeComplexity.maxComplexity) },
148
+ { metric: 'Avg Nesting Depth', value: stats.codeComplexity.avgNestingDepth },
149
+ { metric: 'Max Nesting Depth', value: stats.formatNumber(stats.codeComplexity.maxNestingDepth) },
150
+ { metric: 'Avg Function Size', value: `${stats.codeComplexity.avgFunctionSize} lines` },
151
+ { metric: 'Complex Files', value: stats.formatNumber(stats.codeComplexity.complexFiles) },
152
+ { metric: 'Overall Complexity', value: complexityIndicator }
153
+ ]);
154
+ }
155
+
156
+ // Add code quality recommendations
157
+ if (stats.typescriptSafety || stats.codeComplexity) {
158
+ console.log('\n' + (useColors ? chalk.bold.blue('📝 Code Quality Recommendations:') : '📝 Code Quality Recommendations:'));
159
+ const recommendations: string[] = [];
160
+
161
+ if (stats.typescriptSafety) {
162
+ const typeCoverage = parseFloat(stats.typescriptSafety.avgTypeCoverage);
163
+
164
+ // Type safety recommendations - with more specific thresholds
165
+ if (typeCoverage < 85) {
166
+ recommendations.push(useColors
167
+ ? chalk.yellow('• Improve type coverage by adding more explicit type annotations')
168
+ : '• Improve type coverage by adding more explicit type annotations');
169
+ } else if (typeCoverage < 95) {
170
+ recommendations.push(useColors
171
+ ? chalk.yellow('• Consider adding explicit type annotations to remaining untyped areas')
172
+ : '• Consider adding explicit type annotations to remaining untyped areas');
173
+ }
174
+
175
+ if (stats.typescriptSafety.totalAnyCount > 10) {
176
+ recommendations.push(useColors
177
+ ? chalk.yellow(`• Reduce usage of 'any' type (found ${stats.typescriptSafety.totalAnyCount} instances) by using more specific types`)
178
+ : `• Reduce usage of 'any' type (found ${stats.typescriptSafety.totalAnyCount} instances) by using more specific types`);
179
+ } else if (stats.typescriptSafety.totalAnyCount > 0) {
180
+ recommendations.push(useColors
181
+ ? chalk.yellow(`• Consider replacing the ${stats.typescriptSafety.totalAnyCount} 'any' type usage(s) with more specific types`)
182
+ : `• Consider replacing the ${stats.typescriptSafety.totalAnyCount} 'any' type usage(s) with more specific types`);
183
+ }
184
+
185
+ if (stats.typescriptSafety.totalAssertions > 5) {
186
+ recommendations.push(useColors
187
+ ? chalk.yellow(`• Reduce type assertions (${stats.typescriptSafety.totalAssertions} instances) by improving type declarations`)
188
+ : `• Reduce type assertions (${stats.typescriptSafety.totalAssertions} instances) by improving type declarations`);
189
+ }
190
+
191
+ if (stats.typescriptSafety.totalNonNullAssertions > 5) {
192
+ recommendations.push(useColors
193
+ ? chalk.yellow(`• Replace non-null assertions (${stats.typescriptSafety.totalNonNullAssertions} instances) with proper null checks`)
194
+ : `• Replace non-null assertions (${stats.typescriptSafety.totalNonNullAssertions} instances) with proper null checks`);
195
+ }
196
+ }
197
+
198
+ if (stats.codeComplexity) {
199
+ // Code complexity recommendations
200
+ if (parseFloat(stats.codeComplexity.avgComplexity) > 6) {
201
+ recommendations.push(useColors
202
+ ? chalk.yellow('• Reduce function complexity by breaking down complex functions into smaller, more focused ones')
203
+ : '• Reduce function complexity by breaking down complex functions into smaller, more focused ones');
204
+ }
205
+
206
+ if (parseFloat(stats.codeComplexity.avgNestingDepth) > 3) {
207
+ recommendations.push(useColors
208
+ ? chalk.yellow('• Reduce nesting depth by extracting deeply nested code into separate functions')
209
+ : '• Reduce nesting depth by extracting deeply nested code into separate functions');
210
+ }
211
+
212
+ if (parseFloat(stats.codeComplexity.avgFunctionSize) > 15) {
213
+ recommendations.push(useColors
214
+ ? chalk.yellow('• Consider refactoring large functions to improve readability and maintainability')
215
+ : '• Consider refactoring large functions to improve readability and maintainability');
216
+ }
217
+
218
+ if (stats.codeComplexity.complexFiles > 0) {
219
+ recommendations.push(useColors
220
+ ? chalk.yellow(`• Address high complexity in ${stats.codeComplexity.complexFiles} files with potential technical debt`)
221
+ : `• Address high complexity in ${stats.codeComplexity.complexFiles} files with potential technical debt`);
222
+ }
223
+ }
224
+
225
+ if (recommendations.length > 0) {
226
+ console.log(recommendations.join('\n'));
227
+ } else {
228
+ console.log(useColors
229
+ ? chalk.green('✓ Your code looks well structured! Keep up the good work.')
230
+ : '✓ Your code looks well structured! Keep up the good work.');
231
+ }
232
+ }
233
+
234
+ } catch (error) {
235
+ spinner.fail('Analysis failed');
236
+ console.error(useColors ? chalk.red('Error:') : 'Error:', (error as Error).message);
237
+ process.exit(1);
238
+ }
239
+ });
240
+
241
+ program.parse();
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};