vue-i18n-extract
Version:
Manage vue-i18n localization with static analysis
65 lines (53 loc) • 2.11 kB
text/typescript
import fs from 'fs';
import { I18NItem, I18NItemWithBounding, I18NLanguage, I18NReport } from '../types';
function stripBounding (item: I18NItemWithBounding): I18NItem {
return {
path: item.path,
file: item.file,
line: item.line,
}
}
function mightBeDynamic (item: I18NItemWithBounding): boolean {
return item.path.includes('${') && !!item.previousCharacter.match(/`/g) && !!item.nextCharacter.match(/`/g);
}
// Looping through the arays multiple times might not be the most effecient, but it's the easiest to read and debug. Which at this scale is an accepted trade-off.
export function extractI18NReport (vueItems: I18NItemWithBounding[], languageFiles: I18NLanguage): I18NReport {
const missingKeys: I18NItem[] = [];
const unusedKeys: I18NItem[] = [];
const maybeDynamicKeys: I18NItem[] = vueItems
.filter(vueItem => mightBeDynamic(vueItem))
.map(vueItem => stripBounding(vueItem));
Object.keys(languageFiles).forEach(language => {
const languageItems = languageFiles[language];
const missingKeysInLanguage = vueItems
.filter(vueItem => !mightBeDynamic(vueItem))
.filter(vueItem => !languageItems.some(languageItem => vueItem.path === languageItem.path))
.map(vueItem => ({ ...stripBounding(vueItem), language }));
const unusedKeysInLanguage = languageItems
.filter(languageItem => !vueItems.some(vueItem => languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.')))
.map(languageItem => ({ ...languageItem, language }));
missingKeys.push(...missingKeysInLanguage);
unusedKeys.push(...unusedKeysInLanguage);
});
return {
missingKeys,
unusedKeys,
maybeDynamicKeys,
};
}
export async function writeReportToFile (report: I18NReport, writePath: string): Promise<NodeJS.ErrnoException | void> {
const reportString = JSON.stringify(report);
return new Promise((resolve, reject) => {
fs.writeFile(
writePath,
reportString,
(err) => {
if (err) {
reject(err);
return;
}
resolve();
},
);
});
}