const fs = require('fs'); const path = require('path'); function load(localePath) { let src = fs.readFileSync(localePath, 'utf8'); // strip TS type annotations and the const/export lines to a plain object // replace "const zh = {" -> "var obj = {", remove "export default zh;" src = src.replace(/const\s+\w+\s*=\s*\{/, 'var obj = {'); src = src.replace(/export\s+default\s+\w+;?/, ''); src = src.replace(/\bconst\b/g, 'var'); const moduleWrap = new Function(src + '\nreturn obj;'); return moduleWrap(); } function flatten(obj, prefix = '', res = {}) { for (const k of Object.keys(obj)) { const key = prefix ? prefix + '.' + k : k; if (obj[k] && typeof obj[k] === 'object' && !Array.isArray(obj[k])) { flatten(obj[k], key, res); } else { res[key] = obj[k]; } } return res; } const zhRaw = load('src/locales/zh/index.ts'); const enRaw = load('src/locales/en/index.ts'); const zhF = flatten(zhRaw); const enF = flatten(enRaw); const zhKeys = Object.keys(zhF).sort(); const enKeys = Object.keys(enF).sort(); const onlyZh = zhKeys.filter(k => !(k in enF)); const onlyEn = enKeys.filter(k => !(k in zhF)); console.log('=== Keys in ZH but MISSING in EN (' + onlyZh.length + ') ==='); console.log(onlyZh.join('\n')); console.log(''); console.log('=== Keys in EN but MISSING in ZH (' + onlyEn.length + ') ==='); console.log(onlyEn.join('\n')); console.log(''); console.log('ZH total keys:', zhKeys.length, ' EN total keys:', enKeys.length);