@wundr.io/analysis-engine-simple 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/.eslintrc.js +10 -0
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/dist/analyzers/BaseAnalysisServiceOptimizations.d.ts +93 -0
- package/dist/analyzers/BaseAnalysisServiceOptimizations.d.ts.map +1 -0
- package/dist/analyzers/BaseAnalysisServiceOptimizations.js +419 -0
- package/dist/analyzers/BaseAnalysisServiceOptimizations.js.map +1 -0
- package/dist/analyzers/index.d.ts +58 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +105 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/engines/DuplicateDetectionEngineSimple.d.ts +46 -0
- package/dist/engines/DuplicateDetectionEngineSimple.d.ts.map +1 -0
- package/dist/engines/DuplicateDetectionEngineSimple.js +135 -0
- package/dist/engines/DuplicateDetectionEngineSimple.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +39 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +42 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/monitoring/MemoryMonitorSimple.d.ts +79 -0
- package/dist/monitoring/MemoryMonitorSimple.d.ts.map +1 -0
- package/dist/monitoring/MemoryMonitorSimple.js +184 -0
- package/dist/monitoring/MemoryMonitorSimple.js.map +1 -0
- package/dist/optimization/PerformanceBenchmarkSuiteSimple.d.ts +37 -0
- package/dist/optimization/PerformanceBenchmarkSuiteSimple.d.ts.map +1 -0
- package/dist/optimization/PerformanceBenchmarkSuiteSimple.js +62 -0
- package/dist/optimization/PerformanceBenchmarkSuiteSimple.js.map +1 -0
- package/dist/reporters/index.d.ts +65 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +211 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/streaming/StreamingFileProcessorSimple.d.ts +58 -0
- package/dist/streaming/StreamingFileProcessorSimple.d.ts.map +1 -0
- package/dist/streaming/StreamingFileProcessorSimple.js +170 -0
- package/dist/streaming/StreamingFileProcessorSimple.js.map +1 -0
- package/package.json +41 -0
- package/src/analyzers/BaseAnalysisServiceOptimizations.ts +555 -0
- package/src/analyzers/index.ts +158 -0
- package/src/engines/DuplicateDetectionEngineSimple.ts +185 -0
- package/src/index.ts +50 -0
- package/src/metrics/index.ts +68 -0
- package/src/monitoring/MemoryMonitorSimple.ts +270 -0
- package/src/optimization/PerformanceBenchmarkSuiteSimple.ts +93 -0
- package/src/reporters/index.ts +266 -0
- package/src/streaming/StreamingFileProcessorSimple.ts +228 -0
- package/tsconfig.json +19 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Report generators for analysis results
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
|
|
8
|
+
import type { AnalysisReport } from '../analyzers';
|
|
9
|
+
import type { MetricsReport } from '../metrics';
|
|
10
|
+
|
|
11
|
+
export interface ReportGenerator {
|
|
12
|
+
generate(data: ReportData): Promise<string>;
|
|
13
|
+
generateToFile(data: ReportData, outputPath: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ReportConfig {
|
|
17
|
+
title?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
includeDetails: boolean;
|
|
20
|
+
includeSummary: boolean;
|
|
21
|
+
includeMetrics: boolean;
|
|
22
|
+
theme?: 'light' | 'dark';
|
|
23
|
+
format?: 'full' | 'summary';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ReportData {
|
|
27
|
+
timestamp: Date;
|
|
28
|
+
projectName?: string;
|
|
29
|
+
projectPath: string;
|
|
30
|
+
analysisReport?: AnalysisReport;
|
|
31
|
+
metricsReport?: MetricsReport;
|
|
32
|
+
config: ReportConfig;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const DEFAULT_REPORT_CONFIG: ReportConfig = {
|
|
36
|
+
title: 'Code Analysis Report',
|
|
37
|
+
description: 'Analysis results',
|
|
38
|
+
includeDetails: true,
|
|
39
|
+
includeSummary: true,
|
|
40
|
+
includeMetrics: true,
|
|
41
|
+
theme: 'light',
|
|
42
|
+
format: 'full',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export class JSONReporter implements ReportGenerator {
|
|
46
|
+
constructor(private config: ReportConfig = DEFAULT_REPORT_CONFIG) {}
|
|
47
|
+
|
|
48
|
+
async generate(data: ReportData): Promise<string> {
|
|
49
|
+
await Promise.resolve(); // Add await expression to satisfy linter
|
|
50
|
+
|
|
51
|
+
const reportData = {
|
|
52
|
+
metadata: {
|
|
53
|
+
title: this.config.title,
|
|
54
|
+
timestamp: data.timestamp.toISOString(),
|
|
55
|
+
projectName: data.projectName ?? path.basename(data.projectPath),
|
|
56
|
+
projectPath: data.projectPath,
|
|
57
|
+
},
|
|
58
|
+
summary: data.analysisReport?.summary,
|
|
59
|
+
metrics: data.metricsReport?.summary,
|
|
60
|
+
issues: data.analysisReport?.results ?? [],
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return JSON.stringify(reportData, null, 2);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async generateToFile(data: ReportData, outputPath: string): Promise<void> {
|
|
67
|
+
const json = await this.generate(data);
|
|
68
|
+
const dir = path.dirname(outputPath);
|
|
69
|
+
|
|
70
|
+
if (!fs.existsSync(dir)) {
|
|
71
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
fs.writeFileSync(outputPath, json, 'utf8');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class HTMLReporter implements ReportGenerator {
|
|
79
|
+
constructor(private config: ReportConfig = DEFAULT_REPORT_CONFIG) {}
|
|
80
|
+
|
|
81
|
+
async generate(data: ReportData): Promise<string> {
|
|
82
|
+
await Promise.resolve(); // Add await expression to satisfy linter
|
|
83
|
+
|
|
84
|
+
const projectName = data.projectName ?? path.basename(data.projectPath);
|
|
85
|
+
const summary = data.analysisReport?.summary;
|
|
86
|
+
|
|
87
|
+
return `
|
|
88
|
+
<!DOCTYPE html>
|
|
89
|
+
<html>
|
|
90
|
+
<head>
|
|
91
|
+
<title>${this.config.title}</title>
|
|
92
|
+
<style>
|
|
93
|
+
body { font-family: Arial, sans-serif; margin: 40px; }
|
|
94
|
+
.header { border-bottom: 2px solid #333; padding-bottom: 20px; }
|
|
95
|
+
.summary { margin: 20px 0; }
|
|
96
|
+
.metric { display: inline-block; margin: 10px; padding: 15px; background: #f5f5f5; border-radius: 5px; }
|
|
97
|
+
</style>
|
|
98
|
+
</head>
|
|
99
|
+
<body>
|
|
100
|
+
<div class="header">
|
|
101
|
+
<h1>${this.config.title}</h1>
|
|
102
|
+
<p>Project: ${projectName}</p>
|
|
103
|
+
<p>Generated: ${data.timestamp.toLocaleString()}</p>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
${summary !== undefined ? `
|
|
107
|
+
<div class="summary">
|
|
108
|
+
<h2>Summary</h2>
|
|
109
|
+
<div class="metric">
|
|
110
|
+
<h3>Total Issues</h3>
|
|
111
|
+
<div>${summary.totalIssues}</div>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="metric">
|
|
114
|
+
<h3>Critical</h3>
|
|
115
|
+
<div>${summary.criticalIssues}</div>
|
|
116
|
+
</div>
|
|
117
|
+
<div class="metric">
|
|
118
|
+
<h3>Errors</h3>
|
|
119
|
+
<div>${summary.errorIssues}</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="metric">
|
|
122
|
+
<h3>Warnings</h3>
|
|
123
|
+
<div>${summary.warningIssues}</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
` : ''}
|
|
127
|
+
|
|
128
|
+
<footer>
|
|
129
|
+
<p>Generated with Wundr Analysis Engine</p>
|
|
130
|
+
</footer>
|
|
131
|
+
</body>
|
|
132
|
+
</html>`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async generateToFile(data: ReportData, outputPath: string): Promise<void> {
|
|
136
|
+
const html = await this.generate(data);
|
|
137
|
+
const dir = path.dirname(outputPath);
|
|
138
|
+
|
|
139
|
+
if (!fs.existsSync(dir)) {
|
|
140
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fs.writeFileSync(outputPath, html, 'utf8');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export class MarkdownReporter implements ReportGenerator {
|
|
148
|
+
constructor(private config: ReportConfig = DEFAULT_REPORT_CONFIG) {}
|
|
149
|
+
|
|
150
|
+
async generate(data: ReportData): Promise<string> {
|
|
151
|
+
await Promise.resolve(); // Add await expression to satisfy linter
|
|
152
|
+
|
|
153
|
+
const projectName = data.projectName ?? path.basename(data.projectPath);
|
|
154
|
+
const summary = data.analysisReport?.summary;
|
|
155
|
+
|
|
156
|
+
let content = `# ${this.config.title}\n\n`;
|
|
157
|
+
content += `**Project:** ${projectName}\n`;
|
|
158
|
+
content += `**Generated:** ${data.timestamp.toLocaleString()}\n\n`;
|
|
159
|
+
|
|
160
|
+
if (summary !== undefined) {
|
|
161
|
+
content += '## Summary\n\n';
|
|
162
|
+
content += '| Metric | Count |\n';
|
|
163
|
+
content += '|--------|-------|\n';
|
|
164
|
+
content += `| Total Issues | ${summary.totalIssues} |\n`;
|
|
165
|
+
content += `| Critical | ${summary.criticalIssues} |\n`;
|
|
166
|
+
content += `| Errors | ${summary.errorIssues} |\n`;
|
|
167
|
+
content += `| Warnings | ${summary.warningIssues} |\n`;
|
|
168
|
+
content += `| Info | ${summary.infoIssues} |\n\n`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
content += '---\n\n*Generated with Wundr Analysis Engine*';
|
|
172
|
+
|
|
173
|
+
return content;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async generateToFile(data: ReportData, outputPath: string): Promise<void> {
|
|
177
|
+
const markdown = await this.generate(data);
|
|
178
|
+
const dir = path.dirname(outputPath);
|
|
179
|
+
|
|
180
|
+
if (!fs.existsSync(dir)) {
|
|
181
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
fs.writeFileSync(outputPath, markdown, 'utf8');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export class MultiFormatReporter {
|
|
189
|
+
private reporters = new Map<string, ReportGenerator>();
|
|
190
|
+
|
|
191
|
+
constructor(formats: { format: 'html' | 'json' | 'markdown'; config?: ReportConfig }[]) {
|
|
192
|
+
formats.forEach(({ format, config }) => {
|
|
193
|
+
switch (format) {
|
|
194
|
+
case 'html':
|
|
195
|
+
this.reporters.set(format, new HTMLReporter(config));
|
|
196
|
+
break;
|
|
197
|
+
case 'json':
|
|
198
|
+
this.reporters.set(format, new JSONReporter(config));
|
|
199
|
+
break;
|
|
200
|
+
case 'markdown':
|
|
201
|
+
this.reporters.set(format, new MarkdownReporter(config));
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async generateAll(data: ReportData, outputDir: string): Promise<Record<string, string>> {
|
|
208
|
+
const results: Record<string, string> = {};
|
|
209
|
+
|
|
210
|
+
if (!fs.existsSync(outputDir)) {
|
|
211
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
for (const [format, reporter] of this.reporters) {
|
|
215
|
+
const extension = format === 'markdown' ? 'md' : format;
|
|
216
|
+
const filename = `analysis-report.${extension}`;
|
|
217
|
+
const outputPath = path.join(outputDir, filename);
|
|
218
|
+
|
|
219
|
+
await reporter.generateToFile(data, outputPath);
|
|
220
|
+
results[format] = outputPath;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return results;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Aliases for main index.ts exports
|
|
228
|
+
export const SimpleHtmlReporter = HTMLReporter;
|
|
229
|
+
export const SimpleMarkdownReporter = MarkdownReporter;
|
|
230
|
+
export const SimpleJsonReporter = JSONReporter;
|
|
231
|
+
|
|
232
|
+
export class ReportFactory {
|
|
233
|
+
static createHTMLReporter(config?: ReportConfig): HTMLReporter {
|
|
234
|
+
return new HTMLReporter(config);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static createJSONReporter(config?: ReportConfig): JSONReporter {
|
|
238
|
+
return new JSONReporter(config);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
static createMarkdownReporter(config?: ReportConfig): MarkdownReporter {
|
|
242
|
+
return new MarkdownReporter(config);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export const ReporterUtils = {
|
|
247
|
+
combineReports(
|
|
248
|
+
analysisReport: AnalysisReport,
|
|
249
|
+
metricsReport: MetricsReport,
|
|
250
|
+
projectName?: string,
|
|
251
|
+
): ReportData {
|
|
252
|
+
const data: ReportData = {
|
|
253
|
+
timestamp: new Date(),
|
|
254
|
+
projectPath: analysisReport.projectPath,
|
|
255
|
+
analysisReport,
|
|
256
|
+
metricsReport,
|
|
257
|
+
config: DEFAULT_REPORT_CONFIG,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
if (projectName !== undefined && projectName.trim() !== '') {
|
|
261
|
+
data.projectName = projectName;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return data;
|
|
265
|
+
},
|
|
266
|
+
};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Simplified Streaming File Processor for immediate functionality
|
|
3
|
+
* Basic file processing with proper TypeScript types
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
|
|
9
|
+
import * as fs from 'fs-extra';
|
|
10
|
+
|
|
11
|
+
export interface ProcessedFile {
|
|
12
|
+
path: string;
|
|
13
|
+
size: number;
|
|
14
|
+
lines: number;
|
|
15
|
+
encoding: string;
|
|
16
|
+
mimeType: string;
|
|
17
|
+
lastModified: Date;
|
|
18
|
+
metadata: {
|
|
19
|
+
language?: string;
|
|
20
|
+
complexity?: number;
|
|
21
|
+
imports?: string[];
|
|
22
|
+
exports?: string[];
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface StreamingConfig {
|
|
27
|
+
chunkSize?: number;
|
|
28
|
+
maxConcurrency?: number;
|
|
29
|
+
outputDir?: string;
|
|
30
|
+
includeMetadata?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ProcessingResult {
|
|
34
|
+
files: ProcessedFile[];
|
|
35
|
+
stats: StreamingStats;
|
|
36
|
+
errors: string[];
|
|
37
|
+
duration: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface StreamingStats {
|
|
41
|
+
filesProcessed: number;
|
|
42
|
+
bytesProcessed: number;
|
|
43
|
+
linesProcessed: number;
|
|
44
|
+
processingRate: number;
|
|
45
|
+
memoryUsage: number;
|
|
46
|
+
averageFileSize: number;
|
|
47
|
+
errorCount: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Simplified streaming file processor
|
|
52
|
+
*/
|
|
53
|
+
export class StreamingFileProcessor extends EventEmitter {
|
|
54
|
+
private stats: StreamingStats;
|
|
55
|
+
|
|
56
|
+
constructor() {
|
|
57
|
+
super();
|
|
58
|
+
this.stats = {
|
|
59
|
+
filesProcessed: 0,
|
|
60
|
+
bytesProcessed: 0,
|
|
61
|
+
linesProcessed: 0,
|
|
62
|
+
processingRate: 0,
|
|
63
|
+
memoryUsage: 0,
|
|
64
|
+
averageFileSize: 0,
|
|
65
|
+
errorCount: 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async processFiles(filePaths: string[]): Promise<ProcessedFile[]> {
|
|
70
|
+
const startTime = Date.now();
|
|
71
|
+
const results: ProcessedFile[] = [];
|
|
72
|
+
|
|
73
|
+
this.resetStats();
|
|
74
|
+
|
|
75
|
+
this.emit('processing-started', {
|
|
76
|
+
totalFiles: filePaths.length,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
for (const filePath of filePaths) {
|
|
81
|
+
try {
|
|
82
|
+
const result = await this.processFile(filePath);
|
|
83
|
+
if (result !== null) {
|
|
84
|
+
results.push(result);
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
this.emit('file-error', { file: filePath, error });
|
|
88
|
+
this.stats.errorCount++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const processingTime = Date.now() - startTime;
|
|
93
|
+
this.stats.processingRate = this.stats.filesProcessed / (processingTime / 1000);
|
|
94
|
+
|
|
95
|
+
this.emit('processing-completed', {
|
|
96
|
+
totalProcessed: results.length,
|
|
97
|
+
totalErrors: this.stats.errorCount,
|
|
98
|
+
processingTime,
|
|
99
|
+
stats: this.stats,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return results;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
this.emit('processing-error', { error });
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async processFile(filePath: string): Promise<ProcessedFile | null> {
|
|
110
|
+
const stats = await fs.stat(filePath);
|
|
111
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
112
|
+
const lines = content.split('\n');
|
|
113
|
+
|
|
114
|
+
this.emit('file-started', {
|
|
115
|
+
file: path.basename(filePath),
|
|
116
|
+
size: stats.size,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const processedFile: ProcessedFile = {
|
|
120
|
+
path: filePath,
|
|
121
|
+
size: stats.size,
|
|
122
|
+
lines: lines.length,
|
|
123
|
+
encoding: 'utf8',
|
|
124
|
+
mimeType: this.detectMimeType(filePath),
|
|
125
|
+
lastModified: stats.mtime,
|
|
126
|
+
metadata: {
|
|
127
|
+
language: this.detectLanguage(filePath),
|
|
128
|
+
complexity: this.calculateComplexity(content),
|
|
129
|
+
imports: this.extractImports(content),
|
|
130
|
+
exports: this.extractExports(content),
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
this.stats.filesProcessed++;
|
|
135
|
+
this.stats.bytesProcessed += stats.size;
|
|
136
|
+
this.stats.linesProcessed += lines.length;
|
|
137
|
+
this.stats.memoryUsage = process.memoryUsage().heapUsed;
|
|
138
|
+
|
|
139
|
+
if (this.stats.filesProcessed > 0) {
|
|
140
|
+
this.stats.averageFileSize = this.stats.bytesProcessed / this.stats.filesProcessed;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.emit('file-completed', {
|
|
144
|
+
file: path.basename(filePath),
|
|
145
|
+
lines: processedFile.lines,
|
|
146
|
+
size: processedFile.size,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return processedFile;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private detectMimeType(filePath: string): string {
|
|
153
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
154
|
+
const mimeTypes: Record<string, string> = {
|
|
155
|
+
'.js': 'text/javascript',
|
|
156
|
+
'.ts': 'text/typescript',
|
|
157
|
+
'.jsx': 'text/jsx',
|
|
158
|
+
'.tsx': 'text/tsx',
|
|
159
|
+
'.json': 'application/json',
|
|
160
|
+
'.md': 'text/markdown',
|
|
161
|
+
};
|
|
162
|
+
return mimeTypes[ext] ?? 'text/plain';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private detectLanguage(filePath: string): string {
|
|
166
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
167
|
+
const languages: Record<string, string> = {
|
|
168
|
+
'.js': 'javascript',
|
|
169
|
+
'.ts': 'typescript',
|
|
170
|
+
'.jsx': 'javascript',
|
|
171
|
+
'.tsx': 'typescript',
|
|
172
|
+
};
|
|
173
|
+
return languages[ext] ?? 'unknown';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private calculateComplexity(content: string): number {
|
|
177
|
+
const complexityKeywords = /\b(if|for|while|switch|try|catch)\b/g;
|
|
178
|
+
return (content.match(complexityKeywords) ?? []).length;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private extractImports(content: string): string[] {
|
|
182
|
+
const imports: string[] = [];
|
|
183
|
+
const importRegex = /import.*from\s+['"]([^'"]+)['"]|require\(['"]([^'"]+)['"]\)/g;
|
|
184
|
+
let match;
|
|
185
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
186
|
+
const importPath = match[1] ?? match[2];
|
|
187
|
+
if (importPath !== undefined && importPath.trim() !== '') {
|
|
188
|
+
imports.push(importPath);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return imports;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private extractExports(content: string): string[] {
|
|
195
|
+
const exports: string[] = [];
|
|
196
|
+
const exportRegex = /export\s+(?:default\s+)?(?:class|function|const|let|var)\s+(\w+)/g;
|
|
197
|
+
let match;
|
|
198
|
+
while ((match = exportRegex.exec(content)) !== null) {
|
|
199
|
+
const exportName = match[1];
|
|
200
|
+
if (exportName !== undefined && exportName.trim() !== '') {
|
|
201
|
+
exports.push(exportName);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return exports;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private resetStats(): void {
|
|
208
|
+
this.stats = {
|
|
209
|
+
filesProcessed: 0,
|
|
210
|
+
bytesProcessed: 0,
|
|
211
|
+
linesProcessed: 0,
|
|
212
|
+
processingRate: 0,
|
|
213
|
+
memoryUsage: 0,
|
|
214
|
+
averageFileSize: 0,
|
|
215
|
+
errorCount: 0,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
getStats(): StreamingStats {
|
|
220
|
+
return { ...this.stats };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async cleanup(): Promise<void> {
|
|
224
|
+
await Promise.resolve(); // Add await expression to satisfy linter
|
|
225
|
+
this.resetStats();
|
|
226
|
+
this.emit('cleanup-complete');
|
|
227
|
+
}
|
|
228
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../config/typescript/tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"composite": true,
|
|
10
|
+
"incremental": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*"],
|
|
13
|
+
"exclude": ["node_modules", "dist", "**/*.test.*", "**/*.spec.*"],
|
|
14
|
+
"references": [
|
|
15
|
+
{
|
|
16
|
+
"path": "../core"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|