All checks were successful
Deploy to production / deploy (push) Successful in 1m56s
- Added new localized strings for minigames in Cebuano, including loading hints, objectives, and play focus descriptions to improve user experience. - Updated existing translations for clarity and consistency across various game elements. - Enhanced the Match3Game component to utilize localized strings, ensuring dynamic text rendering based on user language preferences. - Included a new entry in .gitignore for the locale audit report to maintain a clean repository.
141 lines
3.8 KiB
JavaScript
141 lines
3.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Vergleicht en- mit ceb-Locale-Chunks (wie in src/i18n/index.js).
|
|
* - identical: Blattstrings, die nach Merge noch gleich en sind (typisch: fehlende Bisaya-Übersetzung).
|
|
* - germanHints: Blattstrings in ceb mit deutschen Anzeichen (Umlaute / typische Wörter).
|
|
*
|
|
* Usage: node frontend/scripts/audit-ceb-locale.mjs
|
|
*/
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const localesRoot = path.join(__dirname, '../src/i18n/locales');
|
|
|
|
const EN_CHUNKS = [
|
|
'general.json',
|
|
'header.json',
|
|
'navigation.json',
|
|
'home.json',
|
|
'chat.json',
|
|
'register.json',
|
|
'passwordReset.json',
|
|
'error.json',
|
|
'activate.json',
|
|
'settings.json',
|
|
'admin.json',
|
|
'socialnetwork.json',
|
|
'friends.json',
|
|
'falukant.json',
|
|
'blog.json',
|
|
'minigames.json',
|
|
'message.json',
|
|
'personal.json',
|
|
'seo.json',
|
|
];
|
|
|
|
function isPlainObject(value) {
|
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
}
|
|
|
|
function deepMerge(target, source) {
|
|
if (!isPlainObject(source)) return target;
|
|
const base = isPlainObject(target) ? { ...target } : {};
|
|
for (const key of Object.keys(source)) {
|
|
const sv = source[key];
|
|
const tv = base[key];
|
|
if (isPlainObject(sv) && isPlainObject(tv)) {
|
|
base[key] = deepMerge(tv, sv);
|
|
} else if (isPlainObject(sv)) {
|
|
base[key] = deepMerge({}, sv);
|
|
} else {
|
|
base[key] = sv;
|
|
}
|
|
}
|
|
return base;
|
|
}
|
|
|
|
function loadJson(rel) {
|
|
const p = path.join(localesRoot, rel);
|
|
const raw = fs.readFileSync(p, 'utf8');
|
|
return JSON.parse(raw);
|
|
}
|
|
|
|
function flatten(obj, prefix = '', out = {}) {
|
|
if (!isPlainObject(obj)) return out;
|
|
for (const k of Object.keys(obj)) {
|
|
const v = obj[k];
|
|
const key = prefix ? `${prefix}.${k}` : k;
|
|
if (isPlainObject(v)) {
|
|
flatten(v, key, out);
|
|
} else if (typeof v === 'string') {
|
|
out[key] = v;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
const germanWordHints =
|
|
/\b(der|die|das|und|nicht|wird|werden|schon|keine|kein|Ziel|Ziele|Zug|Züge|Spiel|Level|Bitte|Hier|wurde|können|müssen)\b/i;
|
|
const germanChars = /[äöüÄÖÜß]/;
|
|
|
|
function audit() {
|
|
let enMerged = {};
|
|
let cebMerged = {};
|
|
|
|
for (const f of EN_CHUNKS) {
|
|
const enPath = path.join('en', f);
|
|
const cebPath = path.join('ceb', f);
|
|
if (!fs.existsSync(path.join(localesRoot, cebPath))) {
|
|
console.warn(`Warnung: fehlt ${cebPath} (übersprungen)`);
|
|
continue;
|
|
}
|
|
enMerged = deepMerge(enMerged, loadJson(enPath));
|
|
cebMerged = deepMerge(cebMerged, loadJson(enPath));
|
|
cebMerged = deepMerge(cebMerged, loadJson(cebPath));
|
|
}
|
|
|
|
const enFlat = flatten(enMerged);
|
|
const cebFlat = flatten(cebMerged);
|
|
|
|
const identical = [];
|
|
const germanHints = [];
|
|
|
|
for (const key of Object.keys(cebFlat)) {
|
|
const ev = enFlat[key];
|
|
const cv = cebFlat[key];
|
|
if (typeof cv !== 'string') continue;
|
|
if (ev === cv && typeof ev === 'string') {
|
|
identical.push(key);
|
|
}
|
|
if (germanChars.test(cv) || germanWordHints.test(cv)) {
|
|
germanHints.push({ key, sample: cv.slice(0, 120) });
|
|
}
|
|
}
|
|
|
|
identical.sort();
|
|
germanHints.sort((a, b) => a.key.localeCompare(b.key));
|
|
|
|
const report = {
|
|
generated: new Date().toISOString(),
|
|
summary: {
|
|
totalLeafStringsCeb: Object.keys(cebFlat).length,
|
|
identicalToEnCount: identical.length,
|
|
germanHintCount: germanHints.length,
|
|
},
|
|
identicalToEn: identical,
|
|
germanHintsInCeb: germanHints,
|
|
};
|
|
|
|
const outFile = path.join(__dirname, '../ceb-locale-audit-report.json');
|
|
fs.writeFileSync(outFile, JSON.stringify(report, null, 2), 'utf8');
|
|
console.log(`Bericht geschrieben: ${outFile}`);
|
|
console.log(
|
|
`Zusammenfassung: ${report.summary.identicalToEnCount} Blätter noch identisch mit EN, ` +
|
|
`${report.summary.germanHintCount} Strings mit DE-Hinweis (heuristisch).`
|
|
);
|
|
}
|
|
|
|
audit();
|