// ===================================================================== // Detecta mojibake (UTF-8 leído como Latin-1) en los archivos del proyecto. // node scripts/revisar-codificacion.mjs // Se corre después de cualquier edición masiva: reemplazar con expresiones // regulares desde PowerShell rompe los acentos y el daño es difícil de ver. // ===================================================================== import { readFile, readdir } from 'node:fs/promises'; import path from 'node:path'; const RAIZ = path.resolve(import.meta.dirname, '..'); const EXTENSIONES = new Set(['.mjs', '.js', '.css', '.html', '.sql', '.md', '.json', '.yml', '.ps1']); const IGNORAR = new Set(['node_modules', 'tests', '.git', 'capturas', 'test-results', 'reporte']); // Secuencias típicas del doble encodeo: à seguida de otra letra acentuada, etc. const SOSPECHAS = [/Ã[€-¿­]/, /Â[ -¿]/, /â€/, /Â/]; async function archivos(dir) { const salida = []; for (const e of await readdir(dir, { withFileTypes: true })) { if (IGNORAR.has(e.name)) continue; const p = path.join(dir, e.name); if (e.isDirectory()) salida.push(...await archivos(p)); else if (EXTENSIONES.has(path.extname(e.name))) salida.push(p); } return salida; } const sospechosos = []; for (const p of await archivos(RAIZ)) { if (p === import.meta.filename) continue; // este archivo contiene los patrones a propósito const texto = await readFile(p, 'utf8'); const lineas = texto.split('\n'); const malas = []; lineas.forEach((l, i) => { if (SOSPECHAS.some((re) => re.test(l))) malas.push({ n: i + 1, l: l.trim().slice(0, 90) }); }); if (malas.length) sospechosos.push({ archivo: path.relative(RAIZ, p), malas }); } if (!sospechosos.length) { console.log('\n ✔ Sin mojibake: los acentos están bien en todos los archivos.\n'); process.exit(0); } console.log('\n ✖ Se encontró texto mal codificado:\n'); for (const s of sospechosos) { console.log(` ${s.archivo}`); for (const m of s.malas.slice(0, 6)) console.log(` línea ${m.n}: ${m.l}`); if (s.malas.length > 6) console.log(` …y ${s.malas.length - 6} líneas más`); } console.log(''); process.exit(1);