@mailbutler/i18n-utils
Version:
Manage i18n localization with static analysis
118 lines (117 loc) • 5.27 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.readLanguageFiles = readLanguageFiles;
exports.extractI18NLanguageFromLanguageFiles = extractI18NLanguageFromLanguageFiles;
exports.writeMissingToLanguageFiles = writeMissingToLanguageFiles;
exports.removeUnusedFromLanguageFiles = removeUnusedFromLanguageFiles;
exports.parselanguageFiles = parselanguageFiles;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const glob_1 = require("glob");
const dot_object_1 = __importDefault(require("dot-object"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const is_valid_glob_1 = __importDefault(require("is-valid-glob"));
const utils_1 = require("./utils");
function readLanguageFiles(src) {
if (!(0, is_valid_glob_1.default)(src)) {
throw new Error(`languageFiles isn't a valid glob pattern.`);
}
if (!Array.isArray(src)) {
src = [src];
}
const targetFiles = src
.flatMap((targetFile) => (0, glob_1.globSync)(targetFile))
.sort((fileA, fileB) => fileA.localeCompare(fileB));
if (targetFiles.length === 0) {
throw new Error('languageFiles glob has no files.');
}
return targetFiles.map((f) => {
const langPath = path_1.default.resolve(process.cwd(), f);
const extension = langPath.substring(langPath.lastIndexOf('.')).toLowerCase();
const isJSON = extension === '.json';
const isYAML = extension === '.yaml' || extension === '.yml';
let langObj;
if (isJSON) {
langObj = JSON.parse(fs_1.default.readFileSync(langPath, 'utf8'));
}
else if (isYAML) {
langObj = js_yaml_1.default.load(fs_1.default.readFileSync(langPath, 'utf8'));
}
else {
langObj = eval(fs_1.default.readFileSync(langPath, 'utf8'));
}
const fileName = f.replace(process.cwd(), '.');
return { path: f, fileName, content: JSON.stringify(langObj) };
});
}
function extractI18NLanguageFromLanguageFiles(languageFiles, dot = dot_object_1.default) {
return languageFiles.reduce((accumulator, file) => {
const language = file.fileName.substring(file.fileName.lastIndexOf('/') + 1, file.fileName.lastIndexOf('.'));
if (!accumulator[language]) {
accumulator[language] = [];
}
const flattenedObject = dot.dot(JSON.parse(file.content));
Object.keys(flattenedObject).forEach((key, index) => {
accumulator[language].push({
path: key,
file: file.fileName,
line: index
});
});
return accumulator;
}, {});
}
function writeMissingToLanguageFiles(parsedLanguageFiles, missingKeys, dot = dot_object_1.default, normalize = false) {
parsedLanguageFiles.forEach((languageFile) => {
let languageFileContent = JSON.parse(languageFile.content);
missingKeys.forEach((item) => {
if ((item.language && languageFile.fileName.includes(item.language)) || !item.language) {
dot.str(item.path, '', languageFileContent);
}
});
if (normalize) {
languageFileContent = (0, utils_1.sortObject)(languageFileContent);
}
writeLanguageFile(languageFile, languageFileContent);
});
}
function removeUnusedFromLanguageFiles(parsedLanguageFiles, unusedKeys, dot = dot_object_1.default, normalize = false) {
parsedLanguageFiles.forEach((languageFile) => {
let languageFileContent = JSON.parse(languageFile.content);
unusedKeys.forEach((item) => {
if (item.language && languageFile.fileName.includes(item.language)) {
dot.delete(item.path, languageFileContent);
}
});
if (normalize) {
languageFileContent = (0, utils_1.sortObject)(languageFileContent);
}
writeLanguageFile(languageFile, languageFileContent);
});
}
function writeLanguageFile(languageFile, newLanguageFileContent) {
const fileExtension = languageFile.fileName.substring(languageFile.fileName.lastIndexOf('.') + 1);
const filePath = languageFile.path;
const stringifiedContent = JSON.stringify(newLanguageFileContent, null, 2);
if (fileExtension === 'json') {
fs_1.default.writeFileSync(filePath, stringifiedContent);
}
else if (fileExtension === 'js') {
const jsFile = `module.exports = ${stringifiedContent}; \n`;
fs_1.default.writeFileSync(filePath, jsFile);
}
else if (fileExtension === 'yaml' || fileExtension === 'yml') {
const yamlFile = js_yaml_1.default.dump(newLanguageFileContent);
fs_1.default.writeFileSync(filePath, yamlFile);
}
else {
throw new Error(`Language filetype of ${fileExtension} not supported.`);
}
}
// This is a convenience function for users implementing in their own projects, and isn't used internally
function parselanguageFiles(languageFiles, dot = dot_object_1.default) {
return extractI18NLanguageFromLanguageFiles(readLanguageFiles(languageFiles), dot);
}