Files

63 lines
2.0 KiB
JavaScript

'use strict';
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const vm = require('vm');
const root = path.resolve(__dirname, '..');
const skipDirs = new Set(['.git', 'node_modules', 'dist', 'output', '.playwright-cli', 'coverage']);
const files = [];
function walk(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.isDirectory()) {
if (!skipDirs.has(entry.name)) walk(path.join(dir, entry.name));
} else if (entry.isFile() && entry.name.endsWith('.js')) {
files.push(path.join(dir, entry.name));
}
}
}
walk(root);
let failures = 0;
for (const file of files.sort()) {
const code = fs.readFileSync(file, 'utf8');
const rel = path.relative(root, file).replace(/\\/g, '/');
const isModule = /^\s*(?:import|export)\s/m.test(code);
const result = isModule
? spawnSync(process.execPath, ['--input-type=module', '--check'], { input: code, encoding: 'utf8' })
: spawnSync(process.execPath, ['--check', file], { encoding: 'utf8' });
let parseError = null;
if (result.error?.code === 'EPERM') {
try {
if (isModule) {
if (typeof vm.SourceTextModule !== 'function') {
throw new Error('Node vm.SourceTextModule is unavailable; rerun with NODE_OPTIONS=--experimental-vm-modules');
}
new vm.SourceTextModule(code, { identifier: file });
} else {
new vm.Script(code, { filename: file });
}
} catch (error) {
parseError = error;
}
}
if ((result.error?.code === 'EPERM' && parseError) || (result.error?.code !== 'EPERM' && result.status !== 0)) {
failures += 1;
const output = parseError?.stack || `${result.stdout || ''}${result.stderr || ''}`.trim() || result.error?.stack || '';
console.error(`Syntax check failed: ${rel}`);
if (output) console.error(output);
}
}
if (failures) {
console.error(`JavaScript syntax check failed for ${failures}/${files.length} files.`);
process.exit(1);
}
console.log(`JavaScript syntax check passed (${files.length} files).`);