deflake 1.2.33 → 1.2.35
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/cli.js +37 -26
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -238,6 +238,18 @@ async function applyFix(res, loc) {
|
|
|
238
238
|
continue;
|
|
239
239
|
}
|
|
240
240
|
if (p.action === 'INSERT_AFTER') {
|
|
241
|
+
// SAFETY: Detect if we'd insert at class scope (outside any method)
|
|
242
|
+
// Pattern: line is '}' (end of constructor/method) and next non-blank line starts a new method
|
|
243
|
+
const targetLine = lines[idx].trim();
|
|
244
|
+
const nextMeaningful = lines.slice(p.line).find(l => l.trim() !== '');
|
|
245
|
+
const isClassScope = targetLine === '}' && nextMeaningful &&
|
|
246
|
+
/^\s*(async\s+)?\w+\s*\(|^\s*(private|public|protected|static|readonly|get |set )|^\s*}/.test(nextMeaningful);
|
|
247
|
+
|
|
248
|
+
if (isClassScope && /await |return |const |let |var /.test(p.new_line)) {
|
|
249
|
+
console.log(` ${C.YELLOW}⏭️ Blocked: would insert executable code at class scope (after ${targetLine})${C.RESET}`);
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
241
253
|
lines.splice(p.line, 0, cleanLine);
|
|
242
254
|
console.log(` ${C.GREEN}+ Line ${p.line + 1}: ${cleanLine.trim()}${C.RESET}`);
|
|
243
255
|
} else {
|
|
@@ -294,36 +306,35 @@ function extractLoc(text) {
|
|
|
294
306
|
if (!text) return null;
|
|
295
307
|
|
|
296
308
|
// === MULTI-FRAMEWORK LOCATION EXTRACTION ===
|
|
297
|
-
//
|
|
298
|
-
|
|
299
|
-
// Strategy 1: Absolute path inside parentheses (most precise)
|
|
300
|
-
// Format: at FunctionName (/absolute/path/file.ts:75:35)
|
|
301
|
-
let m = text.match(/\(([^()]*?[\\/][^()]+\.(?:ts|js|tsx|jsx|mjs|cjs)):(\d+)(?::(\d+))?\)/);
|
|
302
|
-
if (m) return { path: path.resolve(m[1]), line: parseInt(m[2]) };
|
|
309
|
+
// Returns the LAST match (closest to the Error Context anchor)
|
|
310
|
+
// to avoid picking up stack traces from previous error blocks.
|
|
303
311
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (m) return { path: path.resolve(m[1]), line: parseInt(m[2]) };
|
|
312
|
+
const patterns = [
|
|
313
|
+
// Strategy 1: Absolute path in parens — at Func (/path/file.ts:75:35)
|
|
314
|
+
/\(([^()]*?[\\/][^()]+\.(?:ts|js|tsx|jsx|mjs|cjs)):(\d+)(?::(\d+))?\)/g,
|
|
315
|
+
// Strategy 2: Absolute path — at /path/file.ts:75:35
|
|
316
|
+
/at\s+(\/[^\s]+\.(?:ts|js|tsx|jsx)):(\d+)(?::(\d+))?/g,
|
|
317
|
+
// Strategy 3: Relative path — at ../pages/file.ts:75
|
|
318
|
+
/at\s+(\.\.?\/[^\s]+\.(?:ts|js|tsx|jsx)):(\d+)(?::(\d+))?/g,
|
|
319
|
+
];
|
|
313
320
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
+
let lastMatch = null;
|
|
322
|
+
for (const pattern of patterns) {
|
|
323
|
+
let m;
|
|
324
|
+
while ((m = pattern.exec(text)) !== null) {
|
|
325
|
+
lastMatch = { path: path.resolve(m[1]), line: parseInt(m[2]) };
|
|
326
|
+
}
|
|
327
|
+
if (lastMatch) return lastMatch;
|
|
328
|
+
}
|
|
321
329
|
|
|
322
|
-
// Strategy
|
|
323
|
-
|
|
324
|
-
|
|
330
|
+
// Strategy 4: Generic — any path-like /dir/file.ts:line
|
|
331
|
+
const generic = /((?:[\w@.-]+\/)+[\w.-]+\.(?:ts|js|tsx|jsx)):(\d+)/g;
|
|
332
|
+
let m;
|
|
333
|
+
while ((m = generic.exec(text)) !== null) {
|
|
334
|
+
lastMatch = { path: path.resolve(m[1]), line: parseInt(m[2]) };
|
|
335
|
+
}
|
|
325
336
|
|
|
326
|
-
return
|
|
337
|
+
return lastMatch;
|
|
327
338
|
}
|
|
328
339
|
|
|
329
340
|
async function runDoctor() {
|