@formatjs/cli-lib
Version:
Lib for CLI for formatjs.
76 lines (75 loc) • 2.65 kB
JavaScript
import { isStructurallySame, parse, } from '@formatjs/icu-messageformat-parser';
import { debug, writeStderr } from '../console_utils';
import { error } from 'console';
/**
* Flatten nested obj into list of keys, delimited by `.`
* @param obj
* @param parentKey
* @returns
*/
function flatten(obj, parentKey = '') {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
return {};
}
return Object.keys(obj).reduce((all, k) => {
const value = obj[k];
const key = parentKey ? `${parentKey}.${k}` : k;
if (typeof value === 'object') {
Object.assign(all, flatten(value, key));
}
else {
all[key] = value;
}
return all;
}, {});
}
export async function checkStructuralEquality(translationFilesContents, sourceLocale) {
debug('Checking translation files:');
const enUSContent = translationFilesContents[sourceLocale];
if (!enUSContent) {
throw new Error(`Missing source ${sourceLocale}.json file`);
}
const enUSMessages = Object.entries(flatten(enUSContent)).reduce((all, [key, value]) => {
try {
all[key] = parse(value);
}
catch (e) {
error('Error parsing message', key, value, e);
}
return all;
}, {});
return Object.entries(translationFilesContents)
.filter(([locale]) => locale !== sourceLocale)
.reduce((result, [locale, content]) => {
const localeMessages = flatten(content);
const problematicKeys = Object.keys(enUSMessages)
.map(k => {
if (!localeMessages[k]) {
return { key: k, success: true };
}
const enUSMessage = enUSMessages[k];
try {
const localeMessage = parse(localeMessages[k]);
return {
key: k,
...isStructurallySame(enUSMessage, localeMessage),
};
}
catch (e) {
return {
key: k,
success: false,
error: e instanceof Error ? e : new Error(String(e)),
};
}
})
.filter(s => !s.success);
if (!problematicKeys.length) {
return result;
}
writeStderr('---------------------------------\n');
writeStderr(`These translation keys for locale ${locale} are structurally different from ${sourceLocale}:\n`);
problematicKeys.forEach(({ key, error }) => writeStderr(`${key}: ${error?.message}\n`));
return false;
}, true);
}