|
| 1 | +import { lstatSync, openSync, fstatSync, closeSync, readdirSync, readFileSync, realpathSync } from 'node:fs'; |
| 2 | +import { createHash } from 'node:crypto'; |
| 3 | +import path from 'node:path'; |
| 4 | + |
| 5 | +// Read-only diagnosis for the fixed framework's lstat/fstat consistency guard. |
| 6 | +const root = realpathSync(process.argv[2]); const files = []; |
| 7 | +function visit(dir) { |
| 8 | + for (const entry of readdirSync(dir, { withFileTypes: true })) { |
| 9 | + if (entry.isSymbolicLink()) throw new Error('Unexpected source link'); |
| 10 | + const file = path.join(dir, entry.name); |
| 11 | + if (entry.isDirectory()) visit(file); else if (entry.isFile()) files.push(file); |
| 12 | + } |
| 13 | +} |
| 14 | +visit(path.join(root, 'src')); |
| 15 | +const fields = ['dev', 'ino', 'size', 'mtimeNs', 'ctimeNs']; const mismatches = []; |
| 16 | +for (const file of files.sort()) { |
| 17 | + const hash = () => createHash('sha256').update(readFileSync(file)).digest('hex'); |
| 18 | + const firstHash = hash(); const before = lstatSync(file, { bigint: true }); const fd = openSync(file, 'r'); |
| 19 | + try { |
| 20 | + const opened = fstatSync(fd, { bigint: true }); const after = lstatSync(file, { bigint: true }); |
| 21 | + const differentFields = fields.filter((field) => before[field] !== opened[field]); |
| 22 | + if (differentFields.length) mismatches.push({ file: path.relative(root, file), differentFields, |
| 23 | + before: Object.fromEntries(fields.map((field) => [field, String(before[field])])), |
| 24 | + opened: Object.fromEntries(fields.map((field) => [field, String(opened[field])])), |
| 25 | + pathStatStable: fields.every((field) => before[field] === after[field]), contentStable: firstHash === hash() }); |
| 26 | + } finally { closeSync(fd); } |
| 27 | + if (mismatches.length >= 3) break; |
| 28 | +} |
| 29 | +console.log(JSON.stringify({ node: process.version, platform: process.platform, inspectedFiles: files.length, mismatches, |
| 30 | + note: 'Diagnostic only. No source or guard was changed and no failed assertion is bypassed.' }, null, 2)); |
0 commit comments