81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const root = 'src';
|
|
const exts = ['.tsx', '.ts', '.jsx', '.js'];
|
|
const excludeDirs = ['locales', 'node_modules'];
|
|
const cjk = /[\u4e00-\u9fff]/;
|
|
|
|
function walk(dir) {
|
|
const out = [];
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
if (excludeDirs.includes(entry.name)) continue;
|
|
out.push(...walk(full));
|
|
} else if (exts.includes(path.extname(entry.name))) {
|
|
out.push(full);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
// Load locale keys (flattened)
|
|
function load(localePath) {
|
|
let src = fs.readFileSync(localePath, 'utf8');
|
|
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');
|
|
return new Function(src + '\nreturn obj;')();
|
|
}
|
|
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 zhF = flatten(load('src/locales/zh/index.ts'));
|
|
const enF = flatten(load('src/locales/en/index.ts'));
|
|
|
|
// 1) Find all t('...') / i18n.t('...') referenced keys
|
|
const files = walk(root);
|
|
const refKeys = new Set();
|
|
const refRegex = /(?:i18n\.t|[^a-zA-Z]t)\(\s*['"`]([a-zA-Z][a-zA-Z0-9_.]*?)['"`]/g;
|
|
for (const f of files) {
|
|
const content = fs.readFileSync(f, 'utf8');
|
|
let m;
|
|
while ((m = refRegex.exec(content))) {
|
|
refKeys.add(m[1]);
|
|
}
|
|
}
|
|
const refArr = [...refKeys].sort();
|
|
const missingInZh = refArr.filter(k => !(k in zhF));
|
|
const missingInEn = refArr.filter(k => !(k in enF));
|
|
console.log('=== t() referenced keys missing in ZH (' + missingInZh.length + ') ===');
|
|
console.log(missingInZh.join('\n'));
|
|
console.log('\n=== t() referenced keys missing in EN (' + missingInEn.length + ') ===');
|
|
console.log(missingInEn.join('\n'));
|
|
console.log('\nTotal referenced keys:', refArr.length);
|
|
|
|
// 2) Find user-facing hardcoded Chinese strings.
|
|
// Exclude lines that are only comments or console.* (developer-facing).
|
|
const userHits = [];
|
|
for (const f of files) {
|
|
const lines = fs.readFileSync(f, 'utf8').split('\n');
|
|
lines.forEach((line, i) => {
|
|
const t = line.trim();
|
|
if (!cjk.test(line)) return;
|
|
if (t.startsWith('//') || t.startsWith('*') || t.startsWith('/*')) return;
|
|
if (/^\{\/\*/.test(t)) return; // {/* ... */}
|
|
// exclude console.* (browser console only)
|
|
if (/\bconsole\.(log|error|warn|info|debug)\s*\(/.test(line)) return;
|
|
userHits.push({ file: f, line: i + 1, text: t.slice(0, 220) });
|
|
});
|
|
}
|
|
console.log('\n=== USER-FACING hardcoded CJK lines (' + userHits.length + ') ===');
|
|
for (const h of userHits) {
|
|
console.log(h.file + ':' + h.line + ' | ' + h.text);
|
|
}
|