Skip to content

Instantly share code, notes, and snippets.

@olafwrieden
Created March 24, 2022 13:04
Show Gist options
  • Save olafwrieden/b028ce5f74ae933249aa33c149705059 to your computer and use it in GitHub Desktop.
Save olafwrieden/b028ce5f74ae933249aa33c149705059 to your computer and use it in GitHub Desktop.
Sync Translation Files
{
"name": "example",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"sync:i18n": "ts-node --project ../scripts/tsconfig.json ../scripts/syncTranslations.ts",
"build": "react-scripts build",
"test": "react-scripts test"
}
}
import fs from "fs";
import { join } from "path";
import prettier from "prettier";
import english from "../locales/common_en-US.json";
import { traverseTranslations } from "./traverseTranslations";
const paths = traverseTranslations();
const set = (string: string, obj: any, value: string) => {
const [current, ...rest] = string.split(".");
rest.length >= 1
? set(rest.join("."), (obj[current] = obj[current] || {}), value)
: (obj[current] = value);
return obj;
};
const get = (object: any, path: string, defval = undefined) => {
return path
.split(".")
.reduce((xs, x) => (xs && xs[x] ? xs[x] : defval), object);
};
export interface IHash {
[locale: string]: number;
}
let missingKeys: IHash = {};
fs.readdirSync(join(__dirname, "../locales")).forEach((locale) => {
if (locale === "common_en-US.json") {
return; // No need to analyse the master file
}
const filename = join(__dirname, "../locales", locale);
let data: any;
try {
data = JSON.parse(fs.readFileSync(filename, { encoding: "utf-8" }));
} catch (err: any) {
throw new Error(`${locale}: ${err.message}`);
}
paths.forEach((p) => {
if (get(data, p, undefined) === undefined) {
set(p, data, get(english, p, undefined));
missingKeys[locale] = missingKeys[locale] ? missingKeys[locale] + 1 : 1;
}
});
fs.writeFileSync(
filename,
prettier.format(JSON.stringify(data), {
parser: "json",
})
);
});
console.log("NEW TRANSLATIONS REQUIRED:");
console.log(missingKeys);
import translations from "../locales/common_en-US.json";
const keys: string[] = [];
type TranslationRecord = {
[P in string]: string | TranslationRecord;
};
const _traverseTranslations = (obj: TranslationRecord, path: string[]) => {
Object.keys(obj).forEach((key) => {
const objOrString = obj[key];
if (typeof objOrString === "string") {
keys.push([...path, key].join("."));
} else {
_traverseTranslations(objOrString, [...path, key]);
}
});
};
export const traverseTranslations = () => {
_traverseTranslations(translations, []);
return keys;
};
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": ["dom", "es6", "es2017", "esnext.asynciterable"],
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"removeComments": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"baseUrl": "."
},
"exclude": ["node_modules"],
"include": ["./*.ts"]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment