@tayo-dev/rtl 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 +250 -0
- package/dist/analyzer/mocks/detector.d.ts +59 -0
- package/dist/analyzer/mocks/detector.d.ts.map +1 -0
- package/dist/analyzer/mocks/detector.js +264 -0
- package/dist/analyzer/mocks/detector.js.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts +92 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.js +305 -0
- package/dist/analyzer/mocks/target-analyzer.js.map +1 -0
- package/dist/analyzer/visual/element-analyzer.d.ts +44 -0
- package/dist/analyzer/visual/element-analyzer.d.ts.map +1 -0
- package/dist/analyzer/visual/element-analyzer.js +176 -0
- package/dist/analyzer/visual/element-analyzer.js.map +1 -0
- package/dist/analyzer/visual/inspector.d.ts +49 -0
- package/dist/analyzer/visual/inspector.d.ts.map +1 -0
- package/dist/analyzer/visual/inspector.js +109 -0
- package/dist/analyzer/visual/inspector.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +13 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +417 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/core/generator.d.ts +32 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +173 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/js-parser.d.ts +48 -0
- package/dist/core/js-parser.d.ts.map +1 -0
- package/dist/core/js-parser.js +244 -0
- package/dist/core/js-parser.js.map +1 -0
- package/dist/core/mock-intelligence.d.ts +14 -0
- package/dist/core/mock-intelligence.d.ts.map +1 -0
- package/dist/core/mock-intelligence.js +140 -0
- package/dist/core/mock-intelligence.js.map +1 -0
- package/dist/core/orchestrator.d.ts +49 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +315 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/parser.d.ts +9 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +120 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/recording-intelligence.d.ts +15 -0
- package/dist/core/recording-intelligence.d.ts.map +1 -0
- package/dist/core/recording-intelligence.js +178 -0
- package/dist/core/recording-intelligence.js.map +1 -0
- package/dist/core/resolver.d.ts +58 -0
- package/dist/core/resolver.d.ts.map +1 -0
- package/dist/core/resolver.js +291 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/scanner.d.ts +51 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +310 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/scorer.d.ts +8 -0
- package/dist/core/scorer.d.ts.map +1 -0
- package/dist/core/scorer.js +76 -0
- package/dist/core/scorer.js.map +1 -0
- package/dist/core/validator.d.ts +134 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +44 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/verifier.d.ts +10 -0
- package/dist/core/verifier.d.ts.map +1 -0
- package/dist/core/verifier.js +30 -0
- package/dist/core/verifier.js.map +1 -0
- package/dist/core/writer.d.ts +15 -0
- package/dist/core/writer.d.ts.map +1 -0
- package/dist/core/writer.js +43 -0
- package/dist/core/writer.js.map +1 -0
- package/dist/generator/mocks/builder.d.ts +47 -0
- package/dist/generator/mocks/builder.d.ts.map +1 -0
- package/dist/generator/mocks/builder.js +335 -0
- package/dist/generator/mocks/builder.js.map +1 -0
- package/dist/generator/transforms/dialog-transform.d.ts +35 -0
- package/dist/generator/transforms/dialog-transform.d.ts.map +1 -0
- package/dist/generator/transforms/dialog-transform.js +293 -0
- package/dist/generator/transforms/dialog-transform.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/learner/analyzer.d.ts +13 -0
- package/dist/learner/analyzer.d.ts.map +1 -0
- package/dist/learner/analyzer.js +484 -0
- package/dist/learner/analyzer.js.map +1 -0
- package/dist/learner/index.d.ts +66 -0
- package/dist/learner/index.d.ts.map +1 -0
- package/dist/learner/index.js +247 -0
- package/dist/learner/index.js.map +1 -0
- package/dist/learner/storage.d.ts +68 -0
- package/dist/learner/storage.d.ts.map +1 -0
- package/dist/learner/storage.js +201 -0
- package/dist/learner/storage.js.map +1 -0
- package/dist/learner/types.d.ts +41 -0
- package/dist/learner/types.d.ts.map +1 -0
- package/dist/learner/types.js +31 -0
- package/dist/learner/types.js.map +1 -0
- package/dist/parser/recorder-parser.d.ts +40 -0
- package/dist/parser/recorder-parser.d.ts.map +1 -0
- package/dist/parser/recorder-parser.js +139 -0
- package/dist/parser/recorder-parser.js.map +1 -0
- package/dist/parser/steps/deduplicator.d.ts +19 -0
- package/dist/parser/steps/deduplicator.d.ts.map +1 -0
- package/dist/parser/steps/deduplicator.js +75 -0
- package/dist/parser/steps/deduplicator.js.map +1 -0
- package/dist/parser/steps/dialog-detector.d.ts +38 -0
- package/dist/parser/steps/dialog-detector.d.ts.map +1 -0
- package/dist/parser/steps/dialog-detector.js +290 -0
- package/dist/parser/steps/dialog-detector.js.map +1 -0
- package/dist/parser/steps/noise-filter.d.ts +21 -0
- package/dist/parser/steps/noise-filter.d.ts.map +1 -0
- package/dist/parser/steps/noise-filter.js +138 -0
- package/dist/parser/steps/noise-filter.js.map +1 -0
- package/dist/scorer/index.d.ts +43 -0
- package/dist/scorer/index.d.ts.map +1 -0
- package/dist/scorer/index.js +82 -0
- package/dist/scorer/index.js.map +1 -0
- package/dist/scorer/post-verify.d.ts +17 -0
- package/dist/scorer/post-verify.d.ts.map +1 -0
- package/dist/scorer/post-verify.js +163 -0
- package/dist/scorer/post-verify.js.map +1 -0
- package/dist/scorer/pre-audit.d.ts +32 -0
- package/dist/scorer/pre-audit.d.ts.map +1 -0
- package/dist/scorer/pre-audit.js +99 -0
- package/dist/scorer/pre-audit.js.map +1 -0
- package/dist/scorer/quality-gates.d.ts +17 -0
- package/dist/scorer/quality-gates.d.ts.map +1 -0
- package/dist/scorer/quality-gates.js +304 -0
- package/dist/scorer/quality-gates.js.map +1 -0
- package/dist/scorer/types.d.ts +27 -0
- package/dist/scorer/types.d.ts.map +1 -0
- package/dist/scorer/types.js +5 -0
- package/dist/scorer/types.js.map +1 -0
- package/dist/templates/test-template.d.ts +21 -0
- package/dist/templates/test-template.d.ts.map +1 -0
- package/dist/templates/test-template.js +92 -0
- package/dist/templates/test-template.js.map +1 -0
- package/dist/types/conventions.d.ts +49 -0
- package/dist/types/conventions.d.ts.map +1 -0
- package/dist/types/conventions.js +13 -0
- package/dist/types/conventions.js.map +1 -0
- package/dist/types/recording.d.ts +143 -0
- package/dist/types/recording.d.ts.map +1 -0
- package/dist/types/recording.js +5 -0
- package/dist/types/recording.js.map +1 -0
- package/dist/types/score.d.ts +18 -0
- package/dist/types/score.d.ts.map +1 -0
- package/dist/types/score.js +2 -0
- package/dist/types/score.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase convention scanner
|
|
3
|
+
* Scans project for test file conventions and persists to .taro/conventions.json
|
|
4
|
+
*/
|
|
5
|
+
import { readdir, readFile, mkdir, writeFile, access } from 'node:fs/promises';
|
|
6
|
+
import { join, extname, relative, isAbsolute } from 'node:path';
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
import { DEFAULT_CONVENTIONS } from '../types/conventions.js';
|
|
9
|
+
const SKIP_DIRS = new Set([
|
|
10
|
+
'node_modules',
|
|
11
|
+
'.git',
|
|
12
|
+
'dist',
|
|
13
|
+
'.taro',
|
|
14
|
+
'coverage',
|
|
15
|
+
'.next',
|
|
16
|
+
'.nuxt',
|
|
17
|
+
]);
|
|
18
|
+
const TEST_FILE_REGEX = /\.(test|spec)\.(ts|tsx|js|jsx)$/;
|
|
19
|
+
/**
|
|
20
|
+
* Recursively find all test files in a directory
|
|
21
|
+
* @param root - Root directory to scan
|
|
22
|
+
* @returns Array of absolute paths to test files
|
|
23
|
+
*/
|
|
24
|
+
export async function findTestFiles(root) {
|
|
25
|
+
const results = [];
|
|
26
|
+
async function walk(dir) {
|
|
27
|
+
let entries;
|
|
28
|
+
try {
|
|
29
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Skip directories we can't read
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
const fullPath = join(dir, entry.name);
|
|
37
|
+
if (entry.isDirectory()) {
|
|
38
|
+
if (!SKIP_DIRS.has(entry.name)) {
|
|
39
|
+
await walk(fullPath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (entry.isFile() && TEST_FILE_REGEX.test(entry.name)) {
|
|
43
|
+
results.push(fullPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
await walk(root);
|
|
48
|
+
return results;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load discovered test files with content for downstream analyzers.
|
|
52
|
+
*/
|
|
53
|
+
export async function readTestFiles(root) {
|
|
54
|
+
const files = await findTestFiles(root);
|
|
55
|
+
const loaded = await Promise.all(files.map(async (path) => {
|
|
56
|
+
try {
|
|
57
|
+
const content = await readFile(path, 'utf-8');
|
|
58
|
+
return { path, content };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}));
|
|
64
|
+
return loaded.filter((entry) => entry !== null);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Analyze a single test file to detect its conventions
|
|
68
|
+
* @param filePath - Absolute path to the test file
|
|
69
|
+
* @returns ConventionFile with detected conventions
|
|
70
|
+
*/
|
|
71
|
+
async function analyzeTestFile(filePath) {
|
|
72
|
+
let content;
|
|
73
|
+
try {
|
|
74
|
+
content = await readFile(filePath, 'utf-8');
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// If we can't read the file, return defaults
|
|
78
|
+
return {
|
|
79
|
+
path: filePath,
|
|
80
|
+
importStyle: 'esm',
|
|
81
|
+
hasDescribeBlock: false,
|
|
82
|
+
mockPattern: 'none',
|
|
83
|
+
hasHelperWithExpect: false,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Detect import style: require() indicates CJS
|
|
87
|
+
const importStyle = content.includes('require(') ? 'cjs' : 'esm';
|
|
88
|
+
// Detect describe block
|
|
89
|
+
const hasDescribeBlock = content.includes('describe(');
|
|
90
|
+
// Detect mock pattern
|
|
91
|
+
let mockPattern = 'none';
|
|
92
|
+
if (content.includes('vi.mock(')) {
|
|
93
|
+
mockPattern = 'vi.mock';
|
|
94
|
+
}
|
|
95
|
+
else if (content.includes('jest.mock(')) {
|
|
96
|
+
mockPattern = 'jest.mock';
|
|
97
|
+
}
|
|
98
|
+
// Detect helper functions with expect() - simplified heuristic
|
|
99
|
+
// Look for function declarations that contain expect( but are not in it/test/describe blocks
|
|
100
|
+
const hasHelperWithExpect = detectHelperWithExpect(content);
|
|
101
|
+
return {
|
|
102
|
+
path: filePath,
|
|
103
|
+
importStyle,
|
|
104
|
+
hasDescribeBlock,
|
|
105
|
+
mockPattern,
|
|
106
|
+
hasHelperWithExpect,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Detect if file has helper functions containing expect()
|
|
111
|
+
* Uses simple heuristic: has expect( and a function declaration
|
|
112
|
+
*/
|
|
113
|
+
function detectHelperWithExpect(content) {
|
|
114
|
+
// If no expect at all, return false
|
|
115
|
+
if (!content.includes('expect(')) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// Simple heuristic: has function declaration/arrow function AND expect
|
|
119
|
+
// This catches most helper patterns
|
|
120
|
+
const hasFunction = /function\s+\w+|const\s+\w+\s*=\s*(?:async\s+)?\(|const\s+\w+\s*:\s*(?:Promise<)?\w+>?\s*=\s*(?:async\s+)?\(/.test(content);
|
|
121
|
+
return hasFunction && content.includes('expect(');
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Derive conventions from analyzed files
|
|
125
|
+
* @param files - Array of analyzed ConventionFile objects
|
|
126
|
+
* @param projectRoot - Root directory of the project
|
|
127
|
+
* @returns ConventionsSchema with derived conventions
|
|
128
|
+
*/
|
|
129
|
+
export function deriveConventions(files, projectRoot) {
|
|
130
|
+
if (files.length === 0) {
|
|
131
|
+
return {
|
|
132
|
+
...DEFAULT_CONVENTIONS,
|
|
133
|
+
scannedAt: new Date().toISOString(),
|
|
134
|
+
projectRoot,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Majority vote for import style
|
|
138
|
+
const esmCount = files.filter((f) => f.importStyle === 'esm').length;
|
|
139
|
+
const cjsCount = files.filter((f) => f.importStyle === 'cjs').length;
|
|
140
|
+
const importStyle = cjsCount > esmCount ? 'cjs' : 'esm';
|
|
141
|
+
// Mock pattern: any vi.mock wins, then jest.mock, else none
|
|
142
|
+
const hasViMock = files.some((f) => f.mockPattern === 'vi.mock');
|
|
143
|
+
const hasJestMock = files.some((f) => f.mockPattern === 'jest.mock');
|
|
144
|
+
let mockPattern = 'none';
|
|
145
|
+
if (hasViMock) {
|
|
146
|
+
mockPattern = 'vi.mock';
|
|
147
|
+
}
|
|
148
|
+
else if (hasJestMock) {
|
|
149
|
+
mockPattern = 'jest.mock';
|
|
150
|
+
}
|
|
151
|
+
// Folder pattern detection
|
|
152
|
+
const folderPattern = detectFolderPattern(files, projectRoot);
|
|
153
|
+
// File extension majority
|
|
154
|
+
const fileExtension = detectFileExtension(files);
|
|
155
|
+
return {
|
|
156
|
+
scannedAt: new Date().toISOString(),
|
|
157
|
+
projectRoot,
|
|
158
|
+
importStyle,
|
|
159
|
+
mockPattern,
|
|
160
|
+
testFiles: files,
|
|
161
|
+
folderPattern,
|
|
162
|
+
fileExtension,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Detect folder pattern from test files
|
|
167
|
+
*/
|
|
168
|
+
function detectFolderPattern(files, projectRoot) {
|
|
169
|
+
if (files.length === 0) {
|
|
170
|
+
return 'unknown';
|
|
171
|
+
}
|
|
172
|
+
let hasColocated = false;
|
|
173
|
+
let hasTestsDir = false;
|
|
174
|
+
for (const file of files) {
|
|
175
|
+
const relativePath = relative(projectRoot, file.path);
|
|
176
|
+
if (relativePath.includes('__tests__') || relativePath.includes('__test__')) {
|
|
177
|
+
hasTestsDir = true;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
hasColocated = true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (hasColocated && hasTestsDir) {
|
|
184
|
+
return 'mixed';
|
|
185
|
+
}
|
|
186
|
+
else if (hasTestsDir) {
|
|
187
|
+
return '__tests__';
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
return 'colocated';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Detect majority file extension
|
|
195
|
+
*/
|
|
196
|
+
function detectFileExtension(files) {
|
|
197
|
+
const extensions = files.map((f) => {
|
|
198
|
+
const ext = extname(f.path).slice(1); // remove leading dot
|
|
199
|
+
if (ext === 'ts' || ext === 'tsx') {
|
|
200
|
+
return 'ts'; // normalize to ts
|
|
201
|
+
}
|
|
202
|
+
return 'js'; // normalize to js
|
|
203
|
+
});
|
|
204
|
+
const tsCount = extensions.filter((e) => e === 'ts').length;
|
|
205
|
+
const jsCount = extensions.filter((e) => e === 'js').length;
|
|
206
|
+
if (tsCount === 0 && jsCount > 0) {
|
|
207
|
+
return 'js';
|
|
208
|
+
}
|
|
209
|
+
if (jsCount === 0 && tsCount > 0) {
|
|
210
|
+
return 'ts';
|
|
211
|
+
}
|
|
212
|
+
if (tsCount > 0 && jsCount > 0) {
|
|
213
|
+
return 'mixed';
|
|
214
|
+
}
|
|
215
|
+
return 'ts'; // default
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Read conventions from .taro/conventions.json
|
|
219
|
+
* @param projectRoot - Root directory of the project
|
|
220
|
+
* @returns ConventionsSchema or null if not found
|
|
221
|
+
*/
|
|
222
|
+
export async function readConventions(projectRoot) {
|
|
223
|
+
const conventionsPath = join(projectRoot, '.taro', 'conventions.json');
|
|
224
|
+
try {
|
|
225
|
+
await access(conventionsPath);
|
|
226
|
+
const content = await readFile(conventionsPath, 'utf-8');
|
|
227
|
+
return JSON.parse(content);
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// File doesn't exist or can't be read
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Scan project for test conventions
|
|
236
|
+
* @param projectRoot - Root directory of the project
|
|
237
|
+
* @returns ConventionsSchema with detected conventions
|
|
238
|
+
*/
|
|
239
|
+
export async function scanConventions(projectRoot) {
|
|
240
|
+
// Step 1: Find all test files
|
|
241
|
+
const files = await findTestFiles(projectRoot);
|
|
242
|
+
// Step 2: If no files found, return defaults
|
|
243
|
+
if (files.length === 0) {
|
|
244
|
+
const conventions = {
|
|
245
|
+
...DEFAULT_CONVENTIONS,
|
|
246
|
+
scannedAt: new Date().toISOString(),
|
|
247
|
+
projectRoot,
|
|
248
|
+
testFiles: [],
|
|
249
|
+
};
|
|
250
|
+
// Log warning
|
|
251
|
+
console.log(pc.yellow('[taro] CTX: No test files found — using defaults'));
|
|
252
|
+
// Persist defaults
|
|
253
|
+
await persistConventions(projectRoot, conventions);
|
|
254
|
+
return conventions;
|
|
255
|
+
}
|
|
256
|
+
// Step 3: Analyze all test files
|
|
257
|
+
const analyzed = await Promise.all(files.map(analyzeTestFile));
|
|
258
|
+
// Step 4: Derive conventions from analyzed files
|
|
259
|
+
const conventions = deriveConventions(analyzed, projectRoot);
|
|
260
|
+
// Step 5: Emit TEST-02 warnings for helpers with expect()
|
|
261
|
+
for (const file of analyzed) {
|
|
262
|
+
if (file.hasHelperWithExpect) {
|
|
263
|
+
console.log(pc.yellow(`[taro] TEST-02: Helper function with expect() found in ${relative(projectRoot, file.path)}`));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Step 6: Persist conventions
|
|
267
|
+
await persistConventions(projectRoot, conventions);
|
|
268
|
+
return conventions;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Persist conventions to .taro/conventions.json
|
|
272
|
+
*/
|
|
273
|
+
export async function persistConventions(projectRoot, conventions) {
|
|
274
|
+
const taroDir = join(projectRoot, '.taro');
|
|
275
|
+
// Ensure .taro directory exists
|
|
276
|
+
await mkdir(taroDir, { recursive: true });
|
|
277
|
+
// Write conventions.json
|
|
278
|
+
const conventionsPath = join(taroDir, 'conventions.json');
|
|
279
|
+
await writeFile(conventionsPath, JSON.stringify(conventions, null, 2), 'utf-8');
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Merge new file conventions into the persisted conventions store.
|
|
283
|
+
*/
|
|
284
|
+
export async function mergeConventions(projectRoot, newPatterns) {
|
|
285
|
+
const existing = await readConventions(projectRoot);
|
|
286
|
+
if (!existing) {
|
|
287
|
+
await scanConventions(projectRoot);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const normalizedPatterns = {
|
|
291
|
+
...newPatterns,
|
|
292
|
+
path: isAbsolute(newPatterns.path)
|
|
293
|
+
? newPatterns.path
|
|
294
|
+
: join(projectRoot, newPatterns.path),
|
|
295
|
+
};
|
|
296
|
+
const mergedFiles = existing.testFiles.filter((file) => file.path !== normalizedPatterns.path);
|
|
297
|
+
mergedFiles.push(normalizedPatterns);
|
|
298
|
+
const conventions = deriveConventions(mergedFiles, projectRoot);
|
|
299
|
+
await persistConventions(projectRoot, conventions);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Analyze a single test file without rescanning the whole project.
|
|
303
|
+
*/
|
|
304
|
+
export async function analyzeSingleTestFile(projectRoot, filePath) {
|
|
305
|
+
const normalizedPath = isAbsolute(filePath)
|
|
306
|
+
? filePath
|
|
307
|
+
: join(projectRoot, filePath);
|
|
308
|
+
return analyzeTestFile(normalizedPath);
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/core/scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { QueryResult } from '../types/recording.js';
|
|
2
|
+
import type { ScoreDimensions, ScoreResult } from '../types/score.js';
|
|
3
|
+
export declare function calculateQueryScore(queryResults: QueryResult[]): number;
|
|
4
|
+
export declare function calculateAssertionScore(code: string): number;
|
|
5
|
+
export declare function calculateStructureScore(code: string): number;
|
|
6
|
+
export declare function calculateAggregateScore(dimensions: ScoreDimensions): Pick<ScoreResult, 'total' | 'grade'>;
|
|
7
|
+
export declare function scoreGeneratedTest(code: string, queryResults?: QueryResult[]): ScoreResult;
|
|
8
|
+
//# sourceMappingURL=scorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../src/core/scorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAiBrE,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,CAUvE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmB5D;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,eAAe,GAC1B,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,CAwBtC;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,YAAY,GAAE,WAAW,EAAO,GAC/B,WAAW,CAWb"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const QUERY_WEIGHTS = {
|
|
2
|
+
getByRole: 1.0,
|
|
3
|
+
getByLabelText: 0.8,
|
|
4
|
+
getByText: 0.6,
|
|
5
|
+
getByPlaceholderText: 0.5,
|
|
6
|
+
getByTestId: 0.2,
|
|
7
|
+
};
|
|
8
|
+
const STRONG_ASSERTION_REGEX = /\.toHaveValue\(|\.toBeChecked\(|\.toHaveTextContent\(|\.toBeVisible\(/g;
|
|
9
|
+
const WEAK_ASSERTION_REGEX = /\.toBeInTheDocument\(/g;
|
|
10
|
+
function clampScore(score) {
|
|
11
|
+
return Math.min(100, Math.max(0, Math.round(score)));
|
|
12
|
+
}
|
|
13
|
+
export function calculateQueryScore(queryResults) {
|
|
14
|
+
if (queryResults.length === 0) {
|
|
15
|
+
return 100;
|
|
16
|
+
}
|
|
17
|
+
const totalWeight = queryResults.reduce((sum, queryResult) => {
|
|
18
|
+
return sum + (QUERY_WEIGHTS[queryResult.method] ?? 0.2);
|
|
19
|
+
}, 0);
|
|
20
|
+
return clampScore((totalWeight / queryResults.length) * 100);
|
|
21
|
+
}
|
|
22
|
+
export function calculateAssertionScore(code) {
|
|
23
|
+
const strongAssertions = code.match(STRONG_ASSERTION_REGEX)?.length ?? 0;
|
|
24
|
+
const weakAssertions = code.match(WEAK_ASSERTION_REGEX)?.length ?? 0;
|
|
25
|
+
const totalAssertions = strongAssertions + weakAssertions;
|
|
26
|
+
if (totalAssertions === 0) {
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
const weightedScore = strongAssertions + weakAssertions * 0.3;
|
|
30
|
+
return clampScore((weightedScore / totalAssertions) * 100);
|
|
31
|
+
}
|
|
32
|
+
export function calculateStructureScore(code) {
|
|
33
|
+
const describeCount = code.match(/\bdescribe\s*\(/g)?.length ?? 0;
|
|
34
|
+
const itCount = code.match(/\b(?:it|test)\s*\(/g)?.length ?? 0;
|
|
35
|
+
let score = 50;
|
|
36
|
+
if (describeCount > 0) {
|
|
37
|
+
score += 20;
|
|
38
|
+
}
|
|
39
|
+
if (itCount > 1) {
|
|
40
|
+
score += Math.min((itCount - 1) * 15, 30);
|
|
41
|
+
}
|
|
42
|
+
if (itCount === 1 && code.length > 2000) {
|
|
43
|
+
score -= 20;
|
|
44
|
+
}
|
|
45
|
+
return clampScore(score);
|
|
46
|
+
}
|
|
47
|
+
export function calculateAggregateScore(dimensions) {
|
|
48
|
+
const total = clampScore(dimensions.queryQuality * 0.4 +
|
|
49
|
+
dimensions.assertionSpecificity * 0.35 +
|
|
50
|
+
dimensions.testStructure * 0.25);
|
|
51
|
+
if (total >= 90) {
|
|
52
|
+
return { total, grade: 'A' };
|
|
53
|
+
}
|
|
54
|
+
if (total >= 80) {
|
|
55
|
+
return { total, grade: 'B' };
|
|
56
|
+
}
|
|
57
|
+
if (total >= 70) {
|
|
58
|
+
return { total, grade: 'C' };
|
|
59
|
+
}
|
|
60
|
+
if (total >= 60) {
|
|
61
|
+
return { total, grade: 'D' };
|
|
62
|
+
}
|
|
63
|
+
return { total, grade: 'F' };
|
|
64
|
+
}
|
|
65
|
+
export function scoreGeneratedTest(code, queryResults = []) {
|
|
66
|
+
const dimensions = {
|
|
67
|
+
queryQuality: calculateQueryScore(queryResults),
|
|
68
|
+
assertionSpecificity: calculateAssertionScore(code),
|
|
69
|
+
testStructure: calculateStructureScore(code),
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
...calculateAggregateScore(dimensions),
|
|
73
|
+
dimensions,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=scorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../src/core/scorer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input schema validation using Zod
|
|
3
|
+
* Validates Chrome Recorder export structure before processing,
|
|
4
|
+
* returning structured errors rather than throwing.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export declare const chromeRecorderSchema: z.ZodObject<{
|
|
8
|
+
title: z.ZodOptional<z.ZodString>;
|
|
9
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
10
|
+
type: z.ZodString;
|
|
11
|
+
target: z.ZodOptional<z.ZodString>;
|
|
12
|
+
selectors: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>;
|
|
13
|
+
value: z.ZodOptional<z.ZodString>;
|
|
14
|
+
key: z.ZodOptional<z.ZodString>;
|
|
15
|
+
url: z.ZodOptional<z.ZodString>;
|
|
16
|
+
assertedEvents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
17
|
+
type: z.ZodString;
|
|
18
|
+
url: z.ZodOptional<z.ZodString>;
|
|
19
|
+
title: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
type: string;
|
|
22
|
+
url?: string | undefined;
|
|
23
|
+
title?: string | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
type: string;
|
|
26
|
+
url?: string | undefined;
|
|
27
|
+
title?: string | undefined;
|
|
28
|
+
}>, "many">>;
|
|
29
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
30
|
+
type: z.ZodString;
|
|
31
|
+
target: z.ZodOptional<z.ZodString>;
|
|
32
|
+
selectors: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>;
|
|
33
|
+
value: z.ZodOptional<z.ZodString>;
|
|
34
|
+
key: z.ZodOptional<z.ZodString>;
|
|
35
|
+
url: z.ZodOptional<z.ZodString>;
|
|
36
|
+
assertedEvents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
37
|
+
type: z.ZodString;
|
|
38
|
+
url: z.ZodOptional<z.ZodString>;
|
|
39
|
+
title: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
type: string;
|
|
42
|
+
url?: string | undefined;
|
|
43
|
+
title?: string | undefined;
|
|
44
|
+
}, {
|
|
45
|
+
type: string;
|
|
46
|
+
url?: string | undefined;
|
|
47
|
+
title?: string | undefined;
|
|
48
|
+
}>, "many">>;
|
|
49
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
50
|
+
type: z.ZodString;
|
|
51
|
+
target: z.ZodOptional<z.ZodString>;
|
|
52
|
+
selectors: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>;
|
|
53
|
+
value: z.ZodOptional<z.ZodString>;
|
|
54
|
+
key: z.ZodOptional<z.ZodString>;
|
|
55
|
+
url: z.ZodOptional<z.ZodString>;
|
|
56
|
+
assertedEvents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
57
|
+
type: z.ZodString;
|
|
58
|
+
url: z.ZodOptional<z.ZodString>;
|
|
59
|
+
title: z.ZodOptional<z.ZodString>;
|
|
60
|
+
}, "strip", z.ZodTypeAny, {
|
|
61
|
+
type: string;
|
|
62
|
+
url?: string | undefined;
|
|
63
|
+
title?: string | undefined;
|
|
64
|
+
}, {
|
|
65
|
+
type: string;
|
|
66
|
+
url?: string | undefined;
|
|
67
|
+
title?: string | undefined;
|
|
68
|
+
}>, "many">>;
|
|
69
|
+
}, z.ZodTypeAny, "passthrough">>, "many">;
|
|
70
|
+
settings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
steps: z.objectOutputType<{
|
|
73
|
+
type: z.ZodString;
|
|
74
|
+
target: z.ZodOptional<z.ZodString>;
|
|
75
|
+
selectors: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>;
|
|
76
|
+
value: z.ZodOptional<z.ZodString>;
|
|
77
|
+
key: z.ZodOptional<z.ZodString>;
|
|
78
|
+
url: z.ZodOptional<z.ZodString>;
|
|
79
|
+
assertedEvents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
80
|
+
type: z.ZodString;
|
|
81
|
+
url: z.ZodOptional<z.ZodString>;
|
|
82
|
+
title: z.ZodOptional<z.ZodString>;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
type: string;
|
|
85
|
+
url?: string | undefined;
|
|
86
|
+
title?: string | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
type: string;
|
|
89
|
+
url?: string | undefined;
|
|
90
|
+
title?: string | undefined;
|
|
91
|
+
}>, "many">>;
|
|
92
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
93
|
+
title?: string | undefined;
|
|
94
|
+
settings?: Record<string, unknown> | undefined;
|
|
95
|
+
}, {
|
|
96
|
+
steps: z.objectInputType<{
|
|
97
|
+
type: z.ZodString;
|
|
98
|
+
target: z.ZodOptional<z.ZodString>;
|
|
99
|
+
selectors: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>;
|
|
100
|
+
value: z.ZodOptional<z.ZodString>;
|
|
101
|
+
key: z.ZodOptional<z.ZodString>;
|
|
102
|
+
url: z.ZodOptional<z.ZodString>;
|
|
103
|
+
assertedEvents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
104
|
+
type: z.ZodString;
|
|
105
|
+
url: z.ZodOptional<z.ZodString>;
|
|
106
|
+
title: z.ZodOptional<z.ZodString>;
|
|
107
|
+
}, "strip", z.ZodTypeAny, {
|
|
108
|
+
type: string;
|
|
109
|
+
url?: string | undefined;
|
|
110
|
+
title?: string | undefined;
|
|
111
|
+
}, {
|
|
112
|
+
type: string;
|
|
113
|
+
url?: string | undefined;
|
|
114
|
+
title?: string | undefined;
|
|
115
|
+
}>, "many">>;
|
|
116
|
+
}, z.ZodTypeAny, "passthrough">[];
|
|
117
|
+
title?: string | undefined;
|
|
118
|
+
settings?: Record<string, unknown> | undefined;
|
|
119
|
+
}>;
|
|
120
|
+
export type ValidatedRecording = z.infer<typeof chromeRecorderSchema>;
|
|
121
|
+
export interface ValidationError {
|
|
122
|
+
path: string;
|
|
123
|
+
message: string;
|
|
124
|
+
}
|
|
125
|
+
export type ValidationResult = {
|
|
126
|
+
valid: true;
|
|
127
|
+
data: ValidatedRecording;
|
|
128
|
+
} | {
|
|
129
|
+
valid: false;
|
|
130
|
+
errors: ValidationError[];
|
|
131
|
+
};
|
|
132
|
+
export declare function validateRecording(data: unknown): ValidationResult;
|
|
133
|
+
export declare function formatValidationErrors(errors: ValidationError[]): string;
|
|
134
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAoBvB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAI/B,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAErE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAA;AAS/C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAMjE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAExE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input schema validation using Zod
|
|
3
|
+
* Validates Chrome Recorder export structure before processing,
|
|
4
|
+
* returning structured errors rather than throwing.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
const assertedEventSchema = z.object({
|
|
8
|
+
type: z.string(),
|
|
9
|
+
url: z.string().optional(),
|
|
10
|
+
title: z.string().optional(),
|
|
11
|
+
});
|
|
12
|
+
const recordingStepSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
type: z.string(),
|
|
15
|
+
target: z.string().optional(),
|
|
16
|
+
selectors: z.array(z.array(z.string())).optional(),
|
|
17
|
+
value: z.string().optional(),
|
|
18
|
+
key: z.string().optional(),
|
|
19
|
+
url: z.string().optional(),
|
|
20
|
+
assertedEvents: z.array(assertedEventSchema).optional(),
|
|
21
|
+
})
|
|
22
|
+
.passthrough();
|
|
23
|
+
export const chromeRecorderSchema = z.object({
|
|
24
|
+
title: z.string().optional(),
|
|
25
|
+
steps: z.array(recordingStepSchema),
|
|
26
|
+
settings: z.record(z.unknown()).optional(),
|
|
27
|
+
});
|
|
28
|
+
function formatErrors(zodError) {
|
|
29
|
+
return zodError.errors.map((issue) => ({
|
|
30
|
+
path: issue.path.length > 0 ? issue.path.join('.') : '(root)',
|
|
31
|
+
message: issue.message,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
export function validateRecording(data) {
|
|
35
|
+
const result = chromeRecorderSchema.safeParse(data);
|
|
36
|
+
if (result.success) {
|
|
37
|
+
return { valid: true, data: result.data };
|
|
38
|
+
}
|
|
39
|
+
return { valid: false, errors: formatErrors(result.error) };
|
|
40
|
+
}
|
|
41
|
+
export function formatValidationErrors(errors) {
|
|
42
|
+
return errors.map((e) => ` • ${e.path}: ${e.message}`).join('\n');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAA;AAEF,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE;CACxD,CAAC;KACD,WAAW,EAAE,CAAA;AAEhB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAA;AAaF,SAAS,YAAY,CAAC,QAAoB;IACxC,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ;QAC7D,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC,CAAA;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAa;IAC7C,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IACnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;IAC3C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAyB;IAC9D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-write syntax verification using Babel parser.
|
|
3
|
+
* Ensures generated files parse successfully before reporting completion.
|
|
4
|
+
*/
|
|
5
|
+
export interface VerificationResult {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function verifySyntax(code: string, filePath: string): VerificationResult;
|
|
10
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/core/verifier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAcD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,kBAAkB,CAcpB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-write syntax verification using Babel parser.
|
|
3
|
+
* Ensures generated files parse successfully before reporting completion.
|
|
4
|
+
*/
|
|
5
|
+
import * as babelParser from '@babel/parser';
|
|
6
|
+
function getPlugins(filePath) {
|
|
7
|
+
if (filePath.endsWith('.tsx')) {
|
|
8
|
+
return ['typescript', 'jsx'];
|
|
9
|
+
}
|
|
10
|
+
if (filePath.endsWith('.ts')) {
|
|
11
|
+
return ['typescript'];
|
|
12
|
+
}
|
|
13
|
+
return ['jsx'];
|
|
14
|
+
}
|
|
15
|
+
export function verifySyntax(code, filePath) {
|
|
16
|
+
try {
|
|
17
|
+
babelParser.parse(code, {
|
|
18
|
+
sourceType: 'module',
|
|
19
|
+
plugins: getPlugins(filePath),
|
|
20
|
+
});
|
|
21
|
+
return { valid: true };
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return {
|
|
25
|
+
valid: false,
|
|
26
|
+
error: error instanceof Error ? error.message : 'Unknown parse error',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/core/verifier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,WAAW,MAAM,eAAe,CAAA;AAO5C,SAAS,UAAU,CAAC,QAAgB;IAClC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,YAAY,CAAC,CAAA;IACvB,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,QAAgB;IAEhB,IAAI,CAAC;QACH,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE;YACtB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC;SAC9B,CAAC,CAAA;QAEF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB;SACtE,CAAA;IACH,CAAC;AACH,CAAC"}
|