UNPKG

@mailbutler/i18n-utils

Version:

Manage i18n localization with static analysis

118 lines (117 loc) 5.27 kB
"use strict"; 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); }