102 lines
3.6 KiB
TypeScript
102 lines
3.6 KiB
TypeScript
import * as xliffConverter from 'xliff';
|
|
import { ParsedXliff, Translation } from './types';
|
|
import { languages, UPDATED_XLIFF_PATH } from './constants';
|
|
import fs from 'fs';
|
|
|
|
export async function updateLocalFiles(downloadedXliff: ParsedXliff): Promise<Translation[]> {
|
|
const translations: Translation[] = languages.map(lang => ({
|
|
content: flattenJson(JSON.parse(fs.readFileSync(`./apps/red-ui/src/assets/i18n/${lang.code}.json`, 'utf8'))),
|
|
lang,
|
|
}));
|
|
const source = translations[0]; // flat English
|
|
const xliffKeys = Object.keys(downloadedXliff);
|
|
|
|
// Update json files with potential new translations
|
|
for (const key of xliffKeys) {
|
|
if (source.content[key] !== undefined) {
|
|
for (const translation of translations) {
|
|
const newValue = downloadedXliff[key][translation.lang.key];
|
|
const oldValue = translation.content[key];
|
|
if (newValue && newValue !== translation.content[key]) {
|
|
translation.content[key] = newValue;
|
|
console.log(`Updated ${translation.lang.name} translation for [${key}].`);
|
|
console.log(`Old value: ${oldValue}, new value: ${newValue}`);
|
|
}
|
|
}
|
|
} else {
|
|
console.log(`Key [${key}] doesn't exist in en.json - probably was removed.`);
|
|
}
|
|
}
|
|
|
|
const unflattenedTranslations = translations.map(translation => ({
|
|
content: unflattenJson(translation.content),
|
|
lang: translation.lang,
|
|
}));
|
|
|
|
console.log('Updating translation files...');
|
|
unflattenedTranslations.forEach(translation => {
|
|
fs.writeFileSync(
|
|
`./apps/red-ui/src/assets/i18n/${translation.lang.code}.json`,
|
|
JSON.stringify(translation.content, null, 2) + '\n',
|
|
);
|
|
});
|
|
console.log('Updated translation files!');
|
|
|
|
return translations;
|
|
}
|
|
|
|
export async function xliffToJson(xliff: string): Promise<ParsedXliff> {
|
|
const data = await xliffConverter.xliff12ToJs(xliff);
|
|
return data.resources.redaction;
|
|
}
|
|
|
|
export async function generateXliff(translations: Translation[]): Promise<void> {
|
|
console.log('Generating new XLIFF...');
|
|
|
|
const xliff = await xliffConverter.createxliff12('en-US', 'de-DE', translations[0].content, translations[1].content, 'redaction');
|
|
fs.writeFileSync(UPDATED_XLIFF_PATH, xliff);
|
|
|
|
console.log(`Writing new XLIFF to ${UPDATED_XLIFF_PATH} succeeded!`);
|
|
}
|
|
|
|
export function flattenJson(data: any) {
|
|
const result: any = {};
|
|
|
|
function recurse(cur: any, prop: any) {
|
|
if (Object(cur) !== cur) {
|
|
result[prop] = cur;
|
|
} else if (Array.isArray(cur)) {
|
|
let l = 0;
|
|
for (let i = 0, l = cur.length; i < l; i++) recurse(cur[i], prop + '[' + i + ']');
|
|
if (l === 0) result[prop] = [];
|
|
} else {
|
|
let isEmpty = true;
|
|
for (const p in cur) {
|
|
isEmpty = false;
|
|
recurse(cur[p], prop ? prop + '.' + p : p);
|
|
}
|
|
if (isEmpty && prop) result[prop] = {};
|
|
}
|
|
}
|
|
|
|
recurse(data, '');
|
|
return result;
|
|
}
|
|
|
|
export function unflattenJson(data: any) {
|
|
if (Object(data) !== data || Array.isArray(data)) return data;
|
|
const regex = /\.?([^.\[\]]+)|\[(\d+)\]/g,
|
|
resultholder: any = {};
|
|
for (const p in data) {
|
|
let cur: any = resultholder,
|
|
prop = '',
|
|
m: any;
|
|
while ((m = regex.exec(p))) {
|
|
cur = cur[prop] || (cur[prop] = m[2] ? [] : {});
|
|
prop = m[2] || m[1];
|
|
}
|
|
cur[prop] = data[p];
|
|
}
|
|
return resultholder[''] || resultholder;
|
|
}
|