#!/usr/bin/env node /* * Lightweight backend lint gate: syntax-check all backend JS files. */ const fs = require('fs'); const path = require('path'); const { spawnSync } = require('child_process'); const ROOT = path.resolve(__dirname, '..'); const BACKEND_DIR = path.join(ROOT, 'backend'); const IGNORED_DIRS = new Set([ 'node_modules', 'coverage', 'frontend', 'build', 'test-results', 'uploads', '.pm2', '__pycache__' ]); function walk(dir, out = []) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { if (IGNORED_DIRS.has(entry.name)) continue; walk(fullPath, out); continue; } if (entry.isFile() && entry.name.endsWith('.js')) { out.push(fullPath); } } return out; } function checkFile(filePath) { const result = spawnSync(process.execPath, ['--check', filePath], { encoding: 'utf8' }); return { filePath, ok: result.status === 0, stdout: result.stdout, stderr: result.stderr, status: result.status }; } function main() { const files = walk(BACKEND_DIR).sort(); if (files.length === 0) { console.error('No backend JS files found to lint.'); process.exit(2); } const failures = files .map(checkFile) .filter((result) => !result.ok); console.log(`Checked ${files.length} backend JS files.`); if (failures.length > 0) { console.error(`Syntax lint failed for ${failures.length} file(s):`); failures.forEach((failure) => { console.error(`\n--- ${path.relative(ROOT, failure.filePath)} ---`); const output = (failure.stderr || failure.stdout || '').trim(); if (output) { console.error(output); } }); process.exit(1); } console.log('Backend syntax lint passed.'); } main();