import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // 语言文件列表 const languageFiles = [ 'en.js', 'CN.js', 'zh-CN.js', 'Korean.js', 'Japanese.js', 'de.js', 'fr.js', 'es.js', 'pt.js', 'Italy.js', 'gr.js', 'vi.js', 'th.js', 'ga.js', 'nl.js', 'sv.js', 'da.js', 'no.js', 'fi.js', 'lb.js', 'ro.js', 'tur.js' ]; const modulesPath = path.join(__dirname, 'src', 'i18n', 'modules'); // 提取键的函数 function extractKeys(filePath) { try { const content = fs.readFileSync(filePath, 'utf-8'); const keys = new Set(); // 匹配 'key': 或 "key": 的模式 const keyPattern = /['"]([^'"]+)['"]\s*:/g; let match; while ((match = keyPattern.exec(content)) !== null) { keys.add(match[1]); } return keys; } catch (error) { console.error(`Error reading ${filePath}:`, error.message); return new Set(); } } // 主检查函数 function checkI18nKeys() { console.log('开始检查多语言文件键的一致性...\n'); // 读取英文文件作为基准 const enPath = path.join(modulesPath, 'en.js'); const enKeys = extractKeys(enPath); console.log(`英文文件 (en.js) 包含 ${enKeys.size} 个键\n`); const results = {}; // 检查每个语言文件 for (const langFile of languageFiles) { if (langFile === 'en.js') continue; // 跳过英文文件本身 const langPath = path.join(modulesPath, langFile); const langKeys = extractKeys(langPath); // 找出缺失的键(在en.js中但不在当前文件中) const missingKeys = [...enKeys].filter(key => !langKeys.has(key)); // 找出多余的键(在当前文件中但不在en.js中) const extraKeys = [...langKeys].filter(key => !enKeys.has(key)); results[langFile] = { totalKeys: langKeys.size, missingKeys, extraKeys, missingCount: missingKeys.length, extraCount: extraKeys.length }; } // 生成报告 console.log('='.repeat(80)); console.log('检查结果报告'); console.log('='.repeat(80)); console.log(`基准文件 (en.js): ${enKeys.size} 个键\n`); let hasIssues = false; for (const [langFile, result] of Object.entries(results)) { const status = result.missingCount === 0 && result.extraCount === 0 ? '✓' : '✗'; console.log(`${status} ${langFile}`); console.log(` 总键数: ${result.totalKeys}`); if (result.missingCount > 0) { hasIssues = true; console.log(` ❌ 缺失 ${result.missingCount} 个键:`); result.missingKeys.slice(0, 10).forEach(key => { console.log(` - ${key}`); }); if (result.missingKeys.length > 10) { console.log(` ... 还有 ${result.missingKeys.length - 10} 个键`); } } if (result.extraCount > 0) { hasIssues = true; console.log(` ⚠️ 多余 ${result.extraCount} 个键:`); result.extraKeys.slice(0, 10).forEach(key => { console.log(` - ${key}`); }); if (result.extraKeys.length > 10) { console.log(` ... 还有 ${result.extraKeys.length - 10} 个键`); } } if (result.missingCount === 0 && result.extraCount === 0) { console.log(` ✓ 所有键都匹配`); } console.log(''); } // 生成详细报告文件 const reportPath = path.join(__dirname, 'i18n-keys-report.txt'); let reportContent = '多语言文件键一致性检查报告\n'; reportContent += '='.repeat(80) + '\n'; reportContent += `检查时间: ${new Date().toLocaleString('zh-CN')}\n`; reportContent += `基准文件 (en.js): ${enKeys.size} 个键\n\n`; for (const [langFile, result] of Object.entries(results)) { reportContent += `\n${'='.repeat(80)}\n`; reportContent += `${langFile}\n`; reportContent += `${'='.repeat(80)}\n`; reportContent += `总键数: ${result.totalKeys}\n`; reportContent += `缺失键数: ${result.missingCount}\n`; reportContent += `多余键数: ${result.extraCount}\n\n`; if (result.missingCount > 0) { reportContent += `缺失的键 (${result.missingCount} 个):\n`; result.missingKeys.forEach(key => { reportContent += ` - ${key}\n`; }); reportContent += '\n'; } if (result.extraCount > 0) { reportContent += `多余的键 (${result.extraCount} 个):\n`; result.extraKeys.forEach(key => { reportContent += ` - ${key}\n`; }); reportContent += '\n'; } } fs.writeFileSync(reportPath, reportContent, 'utf-8'); console.log(`详细报告已保存到: ${reportPath}\n`); if (hasIssues) { console.log('⚠️ 发现不一致的键,请查看上方报告或详细报告文件'); process.exit(1); } else { console.log('✓ 所有语言文件的键都与英文文件一致!'); process.exit(0); } } // 运行检查 checkI18nKeys();