Files

79 lines
2.1 KiB
JavaScript
Raw Permalink Normal View History

/**
* Harvest EN→locale phrase map from already-translated message keys,
* then merge into phrase-map.json (does not overwrite non-empty existing locales).
*
* Run: node apps/web/scripts/harvest-phrase-map.mjs
*/
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const messagesDir = path.resolve(__dirname, "../src/lib/i18n/messages");
const mapPath = path.join(__dirname, "phrase-map.json");
const LOCALES = ["es", "fr", "de", "it", "pt", "nl", "pl", "ja"];
function parseMessageDict(source) {
const dict = {};
const re = /"([^"\\]+)"\s*:\s*((?:"(?:\\.|[^"\\])*")|(?:`(?:\\.|[^`\\])*`))/gs;
let m;
while ((m = re.exec(source))) {
const key = m[1];
const raw = m[2];
dict[key] = raw.startsWith("`")
? raw.slice(1, -1).replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\n/g, "\n")
: JSON.parse(raw);
}
return dict;
}
function load(code) {
return parseMessageDict(fs.readFileSync(path.join(messagesDir, `${code}.ts`), "utf8"));
}
const en = load("en");
const packs = Object.fromEntries(LOCALES.map((c) => [c, load(c)]));
const map = fs.existsSync(mapPath) ? JSON.parse(fs.readFileSync(mapPath, "utf8")) : {};
let harvestedPhrases = 0;
let filledSlots = 0;
let newPhrases = 0;
for (const [key, enVal] of Object.entries(en)) {
if (!enVal || typeof enVal !== "string") continue;
const byLoc = {};
let good = 0;
for (const code of LOCALES) {
const v = packs[code][key];
if (typeof v === "string" && v.trim() && v !== enVal) {
byLoc[code] = v;
good += 1;
}
}
if (good < 4) continue;
const existing = map[enVal] ?? {};
let changed = false;
const next = { ...existing };
for (const code of LOCALES) {
if ((!next[code] || !String(next[code]).trim()) && byLoc[code]) {
next[code] = byLoc[code];
filledSlots += 1;
changed = true;
}
}
if (changed) {
if (!map[enVal]) newPhrases += 1;
map[enVal] = next;
harvestedPhrases += 1;
}
}
fs.writeFileSync(mapPath, JSON.stringify(map, null, "\t") + "\n", "utf8");
console.log({
phraseCount: Object.keys(map).length,
harvestedPhrases,
newPhrases,
filledSlots,
});