| New file |
| | |
| | | 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(); |
| | | |