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 { 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 { const data = await xliffConverter.xliff12ToJs(xliff); return data.resources.redaction; } export async function generateXliff(translations: Translation[]): Promise { 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; }