codeguard-testgen 1.0.9 → 1.0.11

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.
@@ -0,0 +1,82 @@
1
+ import { ReviewStep, ToolConfig } from './config';
2
+ /**
3
+ * Semgrep finding structure
4
+ */
5
+ export interface SemgrepFinding {
6
+ check_id: string;
7
+ path: string;
8
+ start: {
9
+ line: number;
10
+ col: number;
11
+ };
12
+ end: {
13
+ line: number;
14
+ col: number;
15
+ };
16
+ extra: {
17
+ message: string;
18
+ severity: string;
19
+ metadata?: any;
20
+ lines?: string;
21
+ };
22
+ }
23
+ /**
24
+ * Semgrep result structure
25
+ */
26
+ export interface SemgrepResult {
27
+ results: SemgrepFinding[];
28
+ errors: any[];
29
+ }
30
+ /**
31
+ * Structured finding for review
32
+ */
33
+ export interface ToolFinding {
34
+ tool: string;
35
+ severity: 'critical' | 'high' | 'medium' | 'low';
36
+ category: string;
37
+ message: string;
38
+ file: string;
39
+ line: number;
40
+ code?: string;
41
+ ruleId: string;
42
+ validated?: boolean;
43
+ aiExplanation?: string;
44
+ }
45
+ /**
46
+ * Execute semgrep on specified files
47
+ */
48
+ export declare function executeSemgrep(files: string[], config: ToolConfig, stepConfig?: any): Promise<SemgrepResult>;
49
+ /**
50
+ * Parse semgrep results into structured findings
51
+ */
52
+ export declare function parseSemgrepResults(semgrepResult: SemgrepResult, changedFunctions: Map<string, {
53
+ start: number;
54
+ end: number;
55
+ }[]>): ToolFinding[];
56
+ /**
57
+ * Validate tool findings using AI to filter false positives
58
+ */
59
+ export declare function validateToolFindings(findings: ToolFinding[], validationPrompt: string, aiValidationFunction: (prompt: string) => Promise<any>): Promise<ToolFinding[]>;
60
+ /**
61
+ * Execute a tool-based review step
62
+ */
63
+ export declare function executeToolStep(step: ReviewStep, files: Array<{
64
+ filePath: string;
65
+ diff: string;
66
+ functions: string[];
67
+ }>, toolConfig: ToolConfig, changedFunctions: Map<string, {
68
+ start: number;
69
+ end: number;
70
+ }[]>, aiValidationFunction?: (prompt: string) => Promise<string>): Promise<ToolFinding[]>;
71
+ /**
72
+ * Extract changed function line ranges from git diff
73
+ */
74
+ export declare function extractChangedFunctionRanges(files: Array<{
75
+ filePath: string;
76
+ diff: string;
77
+ functions: string[];
78
+ }>): Map<string, {
79
+ start: number;
80
+ end: number;
81
+ }[]>;
82
+ //# sourceMappingURL=toolExecutors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolExecutors.d.ts","sourceRoot":"","sources":["../src/toolExecutors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAIlD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,GAAG,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,GAAG,EAAE,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,UAAU,EAClB,UAAU,CAAC,EAAE,GAAG,GACf,OAAO,CAAC,aAAa,CAAC,CA2ExB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,GAC9D,WAAW,EAAE,CA2Df;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,WAAW,EAAE,EACvB,gBAAgB,EAAE,MAAM,EACxB,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,GACrD,OAAO,CAAC,WAAW,EAAE,CAAC,CA8FxB;AAmDD;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,EACnE,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,EAC/D,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACzD,OAAO,CAAC,WAAW,EAAE,CAAC,CAqCxB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,GAClE,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA0B/C"}
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.executeSemgrep = executeSemgrep;
37
+ exports.parseSemgrepResults = parseSemgrepResults;
38
+ exports.validateToolFindings = validateToolFindings;
39
+ exports.executeToolStep = executeToolStep;
40
+ exports.extractChangedFunctionRanges = extractChangedFunctionRanges;
41
+ const child_process_1 = require("child_process");
42
+ const util_1 = require("util");
43
+ const fs = __importStar(require("fs"));
44
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
45
+ /**
46
+ * Execute semgrep on specified files
47
+ */
48
+ async function executeSemgrep(files, config, stepConfig) {
49
+ if (files.length === 0) {
50
+ return { results: [], errors: [] };
51
+ }
52
+ const rulesets = stepConfig?.rulesets || ['p/default'];
53
+ const severity = stepConfig?.severity || ['ERROR', 'WARNING'];
54
+ const excludeRules = stepConfig?.excludeRules || [];
55
+ try {
56
+ // Build semgrep command
57
+ const configArgs = rulesets.map(r => `--config ${r}`).join(' ');
58
+ const severityArgs = severity.map(s => `--severity ${s}`).join(' ');
59
+ const excludeArgs = excludeRules.length > 0
60
+ ? excludeRules.map(r => `--exclude-rule ${r}`).join(' ')
61
+ : '';
62
+ const fileArgs = files.join(' ');
63
+ const timeoutMs = (config.timeout || 60) * 1000;
64
+ const cmd = `${config.binaryPath} ${configArgs} ${severityArgs} ${excludeArgs} --json ${fileArgs}`;
65
+ console.log(` Running: semgrep with ${rulesets.join(', ')}`);
66
+ const { stdout, stderr } = await execAsync(cmd, {
67
+ timeout: timeoutMs,
68
+ maxBuffer: 10 * 1024 * 1024 // 10MB buffer
69
+ });
70
+ if (stderr && !stderr.includes('Scanning')) {
71
+ console.warn(` Semgrep warnings: ${stderr}`);
72
+ }
73
+ const result = JSON.parse(stdout);
74
+ // Filter out warnings (level: 'warn') from errors - these are Pro-only rules
75
+ if (result.errors && result.errors.length > 0) {
76
+ const actualErrors = result.errors.filter((e) => e.level !== 'warn');
77
+ const warnings = result.errors.filter((e) => e.level === 'warn');
78
+ if (warnings.length > 0) {
79
+ console.log(` ā„¹ļø ${warnings.length} Pro-only rule(s) skipped (upgrade for full coverage)`);
80
+ }
81
+ // Only keep actual errors
82
+ result.errors = actualErrors;
83
+ }
84
+ return result;
85
+ }
86
+ catch (error) {
87
+ // Check if semgrep is not installed
88
+ if (error.code === 'ENOENT' || error.message.includes('not found')) {
89
+ console.warn(`āš ļø Semgrep not found. Please install: pip install semgrep`);
90
+ return { results: [], errors: [{ message: 'Semgrep not installed' }] };
91
+ }
92
+ // Timeout error
93
+ if (error.killed || error.signal === 'SIGTERM') {
94
+ console.warn(`āš ļø Semgrep timeout after ${config.timeout}s`);
95
+ return { results: [], errors: [{ message: 'Timeout' }] };
96
+ }
97
+ // Try to parse partial results
98
+ if (error.stdout) {
99
+ try {
100
+ const result = JSON.parse(error.stdout);
101
+ return result;
102
+ }
103
+ catch {
104
+ // Couldn't parse, return error
105
+ }
106
+ }
107
+ console.error(` Semgrep error: ${error.message}`);
108
+ return { results: [], errors: [{ message: error.message }] };
109
+ }
110
+ }
111
+ /**
112
+ * Parse semgrep results into structured findings
113
+ */
114
+ function parseSemgrepResults(semgrepResult, changedFunctions) {
115
+ const findings = [];
116
+ for (const result of semgrepResult.results) {
117
+ // Normalize file path
118
+ const filePath = result.path.startsWith('./')
119
+ ? result.path.substring(2)
120
+ : result.path;
121
+ // Check if finding is in a changed function
122
+ const functionRanges = changedFunctions.get(filePath) || [];
123
+ const isInChangedFunction = functionRanges.some(range => result.start.line >= range.start && result.start.line <= range.end);
124
+ // Only include findings in changed code
125
+ if (!isInChangedFunction && functionRanges.length > 0) {
126
+ continue;
127
+ }
128
+ // Map semgrep severity to our severity levels
129
+ let severity;
130
+ const semgrepSev = result.extra.severity?.toUpperCase();
131
+ if (semgrepSev === 'ERROR') {
132
+ severity = 'high';
133
+ }
134
+ else if (semgrepSev === 'WARNING') {
135
+ severity = 'medium';
136
+ }
137
+ else if (semgrepSev === 'INFO') {
138
+ severity = 'low';
139
+ }
140
+ else {
141
+ severity = 'medium';
142
+ }
143
+ // Determine category from metadata or rule ID
144
+ let category = 'security';
145
+ const ruleId = result.check_id.toLowerCase();
146
+ if (ruleId.includes('performance')) {
147
+ category = 'performance';
148
+ }
149
+ else if (ruleId.includes('bug') || ruleId.includes('correctness')) {
150
+ category = 'bugs';
151
+ }
152
+ else if (ruleId.includes('style') || ruleId.includes('best-practice')) {
153
+ category = 'quality';
154
+ }
155
+ findings.push({
156
+ tool: 'semgrep',
157
+ severity,
158
+ category,
159
+ message: result.extra.message,
160
+ file: filePath,
161
+ line: result.start.line,
162
+ code: result.extra.lines,
163
+ ruleId: result.check_id,
164
+ validated: false
165
+ });
166
+ }
167
+ return findings;
168
+ }
169
+ /**
170
+ * Validate tool findings using AI to filter false positives
171
+ */
172
+ async function validateToolFindings(findings, validationPrompt, aiValidationFunction) {
173
+ if (findings.length === 0) {
174
+ return [];
175
+ }
176
+ // Group findings by file for efficient validation
177
+ const findingsByFile = new Map();
178
+ for (const finding of findings) {
179
+ if (!findingsByFile.has(finding.file)) {
180
+ findingsByFile.set(finding.file, []);
181
+ }
182
+ findingsByFile.get(finding.file).push(finding);
183
+ }
184
+ const validatedFindings = [];
185
+ // Validate findings file by file
186
+ for (const [file, fileFindings] of findingsByFile.entries()) {
187
+ try {
188
+ // Read file content for context
189
+ let fileContent = '';
190
+ try {
191
+ fileContent = fs.readFileSync(file, 'utf-8');
192
+ }
193
+ catch {
194
+ // If can't read file, skip validation for these findings
195
+ validatedFindings.push(...fileFindings.map(f => ({ ...f, validated: true })));
196
+ continue;
197
+ }
198
+ // Build validation prompt
199
+ const findingsDescription = fileFindings.map((f, idx) => `${idx + 1}. [${f.severity.toUpperCase()}] ${f.ruleId}
200
+ Line ${f.line}: ${f.message}
201
+ Code: ${f.code || 'N/A'}`).join('\n\n');
202
+ const prompt = `${validationPrompt}
203
+
204
+ File: ${file}
205
+ Total findings: ${fileFindings.length}
206
+
207
+ Findings to validate:
208
+ ${findingsDescription}
209
+
210
+ File content (relevant sections):
211
+ \`\`\`
212
+ ${getRelevantCodeSections(fileContent, fileFindings)}
213
+ \`\`\`
214
+
215
+ For each finding, respond with:
216
+ 1. Finding number
217
+ 2. Status: REAL or FALSE_POSITIVE
218
+ 3. Brief explanation (one sentence)
219
+
220
+ Format:
221
+ 1. REAL - [explanation]
222
+ 2. FALSE_POSITIVE - [explanation]
223
+ ...`;
224
+ // Call AI for validation
225
+ const response = await aiValidationFunction(prompt);
226
+ // Parse AI response to determine which are false positives
227
+ const validationResults = parseValidationResponse(response);
228
+ // Mark findings based on AI validation
229
+ for (let i = 0; i < fileFindings.length; i++) {
230
+ const validation = validationResults.get(i + 1);
231
+ if (validation) {
232
+ fileFindings[i].validated = validation.isReal;
233
+ fileFindings[i].aiExplanation = validation.explanation;
234
+ if (validation.isReal) {
235
+ validatedFindings.push(fileFindings[i]);
236
+ }
237
+ }
238
+ else {
239
+ // If AI didn't validate, include it to be safe
240
+ fileFindings[i].validated = true;
241
+ validatedFindings.push(fileFindings[i]);
242
+ }
243
+ }
244
+ }
245
+ catch (error) {
246
+ console.warn(` Warning: Could not validate findings for ${file}, including all`);
247
+ // On error, include all findings to be safe
248
+ validatedFindings.push(...fileFindings.map(f => ({ ...f, validated: true })));
249
+ }
250
+ }
251
+ const filteredCount = findings.length - validatedFindings.length;
252
+ if (filteredCount > 0) {
253
+ console.log(` AI filtered out ${filteredCount} false positive(s)`);
254
+ }
255
+ return validatedFindings;
256
+ }
257
+ /**
258
+ * Get relevant code sections around findings
259
+ */
260
+ function getRelevantCodeSections(fileContent, findings) {
261
+ const lines = fileContent.split('\n');
262
+ const sections = [];
263
+ const contextLines = 5;
264
+ for (const finding of findings) {
265
+ const startLine = Math.max(0, finding.line - contextLines - 1);
266
+ const endLine = Math.min(lines.length, finding.line + contextLines);
267
+ const section = lines.slice(startLine, endLine)
268
+ .map((line, idx) => {
269
+ const lineNum = startLine + idx + 1;
270
+ const marker = lineNum === finding.line ? '>' : ' ';
271
+ return `${marker} ${lineNum.toString().padStart(4)} | ${line}`;
272
+ })
273
+ .join('\n');
274
+ sections.push(`\n// Around line ${finding.line}:\n${section}`);
275
+ }
276
+ return sections.join('\n\n');
277
+ }
278
+ /**
279
+ * Parse AI validation response
280
+ */
281
+ function parseValidationResponse(response) {
282
+ const results = new Map();
283
+ // Look for patterns like "1. REAL - explanation" or "2. FALSE_POSITIVE - explanation"
284
+ const lines = response.split('\n');
285
+ for (const line of lines) {
286
+ const match = line.match(/^(\d+)\.\s*(REAL|FALSE_POSITIVE)\s*[-:]\s*(.+)$/i);
287
+ if (match) {
288
+ const findingNum = parseInt(match[1], 10);
289
+ const isReal = match[2].toUpperCase() === 'REAL';
290
+ const explanation = match[3].trim();
291
+ results.set(findingNum, { isReal, explanation });
292
+ }
293
+ }
294
+ return results;
295
+ }
296
+ /**
297
+ * Execute a tool-based review step
298
+ */
299
+ async function executeToolStep(step, files, toolConfig, changedFunctions, aiValidationFunction) {
300
+ console.log(`\nšŸ”§ Executing tool step: ${step.name}`);
301
+ if (step.tool === 'semgrep') {
302
+ // Execute semgrep
303
+ const filePaths = files.map(f => f.filePath);
304
+ const semgrepResult = await executeSemgrep(filePaths, toolConfig, step.config);
305
+ if (semgrepResult.errors.length > 0) {
306
+ console.error(` āŒ ${semgrepResult.errors.length} error(s) during scan`);
307
+ for (const error of semgrepResult.errors.slice(0, 2)) {
308
+ console.error(` ${error.message?.substring(0, 80)}...`);
309
+ }
310
+ }
311
+ console.log(` āœ“ Found ${semgrepResult.results.length} potential issue(s)`);
312
+ // Parse results
313
+ const findings = parseSemgrepResults(semgrepResult, changedFunctions);
314
+ console.log(` ${findings.length} finding(s) in changed code`);
315
+ // Validate with AI if enabled
316
+ if (step.config?.aiValidation && aiValidationFunction && findings.length > 0) {
317
+ console.log(` Validating findings with AI...`);
318
+ const validationPrompt = step.config.aiValidationPrompt ||
319
+ 'Review these static analysis findings and determine which are real issues vs false positives.';
320
+ const validated = await validateToolFindings(findings, validationPrompt, aiValidationFunction);
321
+ console.log(` āœ“ ${validated.length} validated finding(s)`);
322
+ return validated;
323
+ }
324
+ return findings;
325
+ }
326
+ console.warn(` Unknown tool: ${step.tool}`);
327
+ return [];
328
+ }
329
+ /**
330
+ * Extract changed function line ranges from git diff
331
+ */
332
+ function extractChangedFunctionRanges(files) {
333
+ const rangeMap = new Map();
334
+ for (const file of files) {
335
+ const ranges = [];
336
+ // Parse diff to find changed line ranges
337
+ const diffLines = file.diff.split('\n');
338
+ let currentLine = 0;
339
+ for (const line of diffLines) {
340
+ // Look for chunk headers like @@ -10,5 +10,7 @@
341
+ const chunkMatch = line.match(/^@@\s+-\d+,?\d*\s+\+(\d+),?(\d*)\s+@@/);
342
+ if (chunkMatch) {
343
+ currentLine = parseInt(chunkMatch[1], 10);
344
+ const count = chunkMatch[2] ? parseInt(chunkMatch[2], 10) : 1;
345
+ ranges.push({ start: currentLine, end: currentLine + count });
346
+ }
347
+ }
348
+ if (ranges.length > 0) {
349
+ rangeMap.set(file.filePath, ranges);
350
+ }
351
+ }
352
+ return rangeMap;
353
+ }
354
+ //# sourceMappingURL=toolExecutors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolExecutors.js","sourceRoot":"","sources":["../src/toolExecutors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface ToolCheckResult {
2
+ available: boolean;
3
+ success: boolean;
4
+ errors: string[];
5
+ }
6
+ export interface ValidationResult {
7
+ success: boolean;
8
+ hasErrors: boolean;
9
+ typescript: ToolCheckResult;
10
+ eslint: ToolCheckResult;
11
+ formattedErrors: string;
12
+ }
13
+ /**
14
+ * Check if TypeScript compiler is available and run type checking on a file
15
+ */
16
+ export declare function checkTypeScriptCompilation(testFilePath: string): ToolCheckResult;
17
+ /**
18
+ * Check if ESLint is available and run linting on a file
19
+ */
20
+ export declare function checkESLint(testFilePath: string): ToolCheckResult;
21
+ /**
22
+ * Main validation function that checks both TypeScript and ESLint
23
+ */
24
+ export declare function validateTestFile(testFilePath: string): ValidationResult;
25
+ //# sourceMappingURL=typeValidator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeValidator.d.ts","sourceRoot":"","sources":["../src/typeValidator.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CAmChF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CAmCjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,gBAAgB,CA0CvE"}
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkTypeScriptCompilation = checkTypeScriptCompilation;
4
+ exports.checkESLint = checkESLint;
5
+ exports.validateTestFile = validateTestFile;
6
+ const child_process_1 = require("child_process");
7
+ /**
8
+ * Check if TypeScript compiler is available and run type checking on a file
9
+ */
10
+ function checkTypeScriptCompilation(testFilePath) {
11
+ // Check if TypeScript is available
12
+ try {
13
+ (0, child_process_1.execSync)('npx tsc --version', { stdio: 'pipe' });
14
+ }
15
+ catch (error) {
16
+ return {
17
+ available: false,
18
+ success: true, // Consider it a success if not available (graceful degradation)
19
+ errors: []
20
+ };
21
+ }
22
+ // Run TypeScript compilation check
23
+ try {
24
+ (0, child_process_1.execSync)(`npx tsc --noEmit ${testFilePath}`, {
25
+ encoding: 'utf-8',
26
+ stdio: 'pipe'
27
+ });
28
+ return {
29
+ available: true,
30
+ success: true,
31
+ errors: []
32
+ };
33
+ }
34
+ catch (error) {
35
+ // Parse TypeScript errors from stderr/stdout
36
+ const output = error.stdout || error.stderr || error.message || '';
37
+ const errors = parseTypeScriptErrors(output);
38
+ return {
39
+ available: true,
40
+ success: false,
41
+ errors
42
+ };
43
+ }
44
+ }
45
+ /**
46
+ * Check if ESLint is available and run linting on a file
47
+ */
48
+ function checkESLint(testFilePath) {
49
+ // Check if ESLint is available
50
+ try {
51
+ (0, child_process_1.execSync)('npx eslint --version', { stdio: 'pipe' });
52
+ }
53
+ catch (error) {
54
+ return {
55
+ available: false,
56
+ success: true, // Consider it a success if not available (graceful degradation)
57
+ errors: []
58
+ };
59
+ }
60
+ // Run ESLint check
61
+ try {
62
+ (0, child_process_1.execSync)(`npx eslint ${testFilePath}`, {
63
+ encoding: 'utf-8',
64
+ stdio: 'pipe'
65
+ });
66
+ return {
67
+ available: true,
68
+ success: true,
69
+ errors: []
70
+ };
71
+ }
72
+ catch (error) {
73
+ // Parse ESLint errors from stderr/stdout
74
+ const output = error.stdout || error.stderr || error.message || '';
75
+ const errors = parseESLintErrors(output);
76
+ return {
77
+ available: true,
78
+ success: false,
79
+ errors
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * Main validation function that checks both TypeScript and ESLint
85
+ */
86
+ function validateTestFile(testFilePath) {
87
+ console.log(`\nšŸ” Running type checking and linting validation on: ${testFilePath}`);
88
+ const typescript = checkTypeScriptCompilation(testFilePath);
89
+ const eslint = checkESLint(testFilePath);
90
+ const hasErrors = (typescript.available && !typescript.success) ||
91
+ (eslint.available && !eslint.success);
92
+ const success = !hasErrors;
93
+ // Format errors for AI consumption
94
+ const formattedErrors = formatValidationErrors(typescript, eslint);
95
+ // Log results
96
+ if (!typescript.available && !eslint.available) {
97
+ console.log(' ā„¹ļø TypeScript and ESLint not available - skipping validation');
98
+ }
99
+ else {
100
+ if (typescript.available) {
101
+ if (typescript.success) {
102
+ console.log(' āœ… TypeScript compilation: PASSED');
103
+ }
104
+ else {
105
+ console.log(` āŒ TypeScript compilation: FAILED (${typescript.errors.length} error(s))`);
106
+ }
107
+ }
108
+ if (eslint.available) {
109
+ if (eslint.success) {
110
+ console.log(' āœ… ESLint: PASSED');
111
+ }
112
+ else {
113
+ console.log(` āŒ ESLint: FAILED (${eslint.errors.length} error(s))`);
114
+ }
115
+ }
116
+ }
117
+ return {
118
+ success,
119
+ hasErrors,
120
+ typescript,
121
+ eslint,
122
+ formattedErrors
123
+ };
124
+ }
125
+ /**
126
+ * Parse TypeScript compiler errors into a readable array
127
+ */
128
+ function parseTypeScriptErrors(output) {
129
+ const errors = [];
130
+ const lines = output.split('\n');
131
+ for (const line of lines) {
132
+ // TypeScript errors typically follow pattern: filename(line,col): error TS####: message
133
+ if (line.includes('error TS') || line.includes(': error')) {
134
+ errors.push(line.trim());
135
+ }
136
+ }
137
+ // If no specific errors found, return the full output (may be a general error)
138
+ if (errors.length === 0 && output.trim()) {
139
+ errors.push(output.trim());
140
+ }
141
+ return errors;
142
+ }
143
+ /**
144
+ * Parse ESLint errors into a readable array
145
+ */
146
+ function parseESLintErrors(output) {
147
+ const errors = [];
148
+ const lines = output.split('\n');
149
+ for (const line of lines) {
150
+ // ESLint errors typically show line:col and rule name
151
+ if (line.includes('error') || line.includes('warning')) {
152
+ const trimmed = line.trim();
153
+ if (trimmed) {
154
+ errors.push(trimmed);
155
+ }
156
+ }
157
+ }
158
+ // If no specific errors found, return the full output
159
+ if (errors.length === 0 && output.trim()) {
160
+ errors.push(output.trim());
161
+ }
162
+ return errors;
163
+ }
164
+ /**
165
+ * Format validation errors for AI consumption
166
+ */
167
+ function formatValidationErrors(typescript, eslint) {
168
+ const sections = [];
169
+ if (typescript.available && !typescript.success) {
170
+ sections.push('## TypeScript Compilation Errors\n\n' + typescript.errors.join('\n'));
171
+ }
172
+ if (eslint.available && !eslint.success) {
173
+ sections.push('## ESLint Errors\n\n' + eslint.errors.join('\n'));
174
+ }
175
+ if (sections.length === 0) {
176
+ return 'No validation errors found.';
177
+ }
178
+ return sections.join('\n\n');
179
+ }
180
+ //# sourceMappingURL=typeValidator.js.map