75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const ts = require('typescript');
|
|
|
|
function transpile(file) {
|
|
const code = fs.readFileSync(file, 'utf8');
|
|
const out = ts.transpileModule(code, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2019 },
|
|
});
|
|
return out.outputText;
|
|
}
|
|
|
|
function load(file) {
|
|
const out = transpile(file);
|
|
const module = { exports: {} };
|
|
const fn = new Function('module', 'exports', out);
|
|
fn(module, module.exports);
|
|
return module.exports.default || module.exports;
|
|
}
|
|
|
|
function flatten(obj, prefix = '') {
|
|
const keys = new Set();
|
|
for (const k of Object.keys(obj)) {
|
|
const v = obj[k];
|
|
const p = prefix ? prefix + '.' + k : k;
|
|
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
for (const sk of flatten(v, p)) keys.add(sk);
|
|
} else {
|
|
keys.add(p);
|
|
}
|
|
}
|
|
return keys;
|
|
}
|
|
|
|
const zhKeys = flatten(load('src/locales/zh/index.ts'));
|
|
const enKeys = flatten(load('src/locales/en/index.ts'));
|
|
console.log('zh keys:', zhKeys.size, 'en keys:', enKeys.size);
|
|
|
|
const dir = 'src';
|
|
const exts = ['.tsx', '.ts', '.jsx', '.js'];
|
|
function walk(d) {
|
|
let r = [];
|
|
for (const f of fs.readdirSync(d)) {
|
|
const p = path.join(d, f);
|
|
if (fs.statSync(p).isDirectory()) {
|
|
r = r.concat(walk(p));
|
|
} else if (exts.some((e) => f.endsWith(e)) && !p.includes('locales')) {
|
|
r.push(p);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
const used = new Set();
|
|
const fileKey = {};
|
|
for (const f of walk(dir)) {
|
|
const code = fs.readFileSync(f, 'utf8');
|
|
const re = /(?:[^.\w]|^)(?:t|i18n\.t)\(\s*['"]([a-zA-Z0-9_.-]+)['"]/g;
|
|
let m;
|
|
while ((m = re.exec(code)) !== null) {
|
|
const k = m[1];
|
|
used.add(k);
|
|
(fileKey[k] = fileKey[k] || new Set()).add(f);
|
|
}
|
|
}
|
|
console.log('Total distinct keys used in source:', used.size);
|
|
|
|
const missing = [...used].filter((k) => !zhKeys.has(k) || !enKeys.has(k));
|
|
console.log('Keys used but missing in locale files:', missing.length);
|
|
for (const k of missing.sort()) {
|
|
console.log(' ' + k + ' <- ' + [...(fileKey[k] || [])].join(', '));
|
|
}
|
|
|
|
// Also detect literal raw t('...') keys that might be dynamic (skip)
|