rucken
Version:
Console tools and scripts for nx and not only that I (EndyKaufman) use to automate the workflow and speed up the development process
256 lines (255 loc) • 12.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GettextService = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const fast_deep_equal_1 = tslib_1.__importDefault(require("fast-deep-equal"));
const fs_1 = require("fs");
const gettext_extractor_1 = require("gettext-extractor");
const log4js_1 = require("log4js");
const path_1 = require("path");
const utils_service_1 = require("../utils/utils.service");
const i18next_conv_1 = require("./i18next-conv");
const po2json_1 = require("./po2json");
let GettextService = class GettextService {
constructor(utilsService) {
this.utilsService = utilsService;
}
setLogger(command) {
this.logger = (0, log4js_1.getLogger)(command);
this.logger.level = utils_service_1.UtilsService.logLevel();
}
extractTranslatesFromSourcesForLibraries({ po2jsonOptions, pattern, locales, defaultLocale, markers, }) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
locales = [defaultLocale, ...locales.filter((l) => l !== defaultLocale)];
this.logger.info('Start create translate files...');
this.logger.debug(`Config: ${JSON.stringify({
po2jsonOptions,
pattern,
locales,
defaultLocale,
markers,
})}`);
try {
const projects = this.utilsService.getWorkspaceProjects();
const projectNames = Object.keys(projects);
for (let pIdx = 0; pIdx < projectNames.length; pIdx++) {
const projectName = projectNames[pIdx];
this.logger.debug(projectName, projects[projectName].sourceRoot);
const assetsPath = projects[projectName].projectType === 'application' ||
((_a = projects[projectName].sourceRoot) === null || _a === void 0 ? void 0 : _a.substring(0, 5)) === 'apps/'
? 'assets'
: '';
for (let lIdx = 0; lIdx < locales.length; lIdx++) {
const locale = locales[lIdx];
if (projects[projectName].sourceRoot) {
yield this.processLibrary({
po2jsonOptions,
pattern,
sourceRoot: projects[projectName].sourceRoot,
defaultLocale,
marker: '',
locale,
assetsPath,
});
for (let mIdx = 0; mIdx < markers.length; mIdx++) {
const marker = markers[mIdx];
yield this.processLibrary({
po2jsonOptions,
pattern,
sourceRoot: projects[projectName].sourceRoot,
defaultLocale,
marker,
locale,
assetsPath,
});
}
}
}
}
this.logger.info('End of create translate files...');
}
catch (error) {
this.logger.error(error);
process.exit(1);
}
});
}
processLibrary({ po2jsonOptions, pattern, sourceRoot, defaultLocale, marker, locale, assetsPath, }) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
// default pot
const defaultPotFileName = 'template.pot';
const defaultPotFile = (0, path_1.resolve)(sourceRoot, assetsPath || '', 'i18n', marker ? marker : '', defaultPotFileName);
let defaultJsonPotData = {};
// default json
const defaultJsonFileName = `${defaultLocale}.json`;
const defaultJsonFile = (0, path_1.resolve)(sourceRoot, assetsPath || '', 'i18n', marker ? marker : '', defaultJsonFileName);
let defaultJsonData = {};
// locale json
const localeJsonFileName = `${locale}.json`;
const localeJsonFile = (0, path_1.resolve)(sourceRoot, assetsPath || '', 'i18n', marker ? marker : '', localeJsonFileName);
let localeJsonData = {};
// locale po
const localePoFileName = `${locale}.po`;
const localePoFile = (0, path_1.resolve)(sourceRoot, assetsPath || '', 'i18n', marker ? marker : '', localePoFileName);
let localeJsonPoData = {};
if ((0, fs_1.existsSync)(defaultJsonFile)) {
try {
defaultJsonData = JSON.parse((0, fs_1.readFileSync)(defaultJsonFile).toString());
if (Object.keys(defaultJsonData).length === 0) {
(0, fs_1.unlinkSync)(defaultJsonFile);
}
}
catch (error) {
defaultJsonData = {};
}
}
if ((0, fs_1.existsSync)(localeJsonFile)) {
try {
localeJsonData = JSON.parse((0, fs_1.readFileSync)(localeJsonFile).toString());
if (Object.keys(localeJsonData).length === 0) {
(0, fs_1.unlinkSync)(localeJsonFile);
}
}
catch (error) {
localeJsonData = {};
}
}
// считываем пот файл
if ((0, fs_1.existsSync)(defaultPotFile)) {
defaultJsonPotData = (0, po2json_1.parseFileSync)(defaultPotFile, po2jsonOptions);
}
const newDefaultJsonData = Object.assign(Object.assign({}, defaultJsonData), defaultJsonPotData);
// чистим значения помеченные как отсутствующие
// для дефолтного языка ставим ключ в качестве значения
Object.keys(newDefaultJsonData).forEach((key) => {
if (newDefaultJsonData[key] === `Missing value for '${key}'`) {
if (locale === defaultLocale) {
newDefaultJsonData[key] =
defaultJsonData[key] === `Missing value for '${key}'`
? key
: defaultJsonData[key];
}
else {
newDefaultJsonData[key] = '';
}
}
});
// считываем по файл локали
if ((0, fs_1.existsSync)(localePoFile)) {
localeJsonPoData = (0, po2json_1.parseFileSync)(localePoFile, po2jsonOptions);
}
const newLocaleJsonData = Object.assign(Object.assign({}, localeJsonData), localeJsonPoData);
Object.keys(newLocaleJsonData).forEach((key) => {
if (newLocaleJsonData[key] === `Missing value for '${key}'`) {
if (locale === defaultLocale) {
newLocaleJsonData[key] =
localeJsonData[key] === `Missing value for '${key}'`
? key
: localeJsonData[key];
}
else {
newLocaleJsonData[key] = '';
}
}
});
// формируем общий json
const newJsonData = Object.assign(Object.assign({}, newDefaultJsonData), newLocaleJsonData);
this.extractWithMarkers(marker, sourceRoot, pattern, newJsonData);
// если язык не дефолт и у него перевод равен ключу, то сносим перевод
Object.keys(newJsonData).forEach((key) => {
// if (newJsonData[key] && String(newJsonData[key]).includes('\\{')) {
// newJsonData[key] = String(newJsonData[key]).split('\\{').join('{');
// }
// if (newJsonData[key] && String(newJsonData[key]).includes('\\}')) {
// newJsonData[key] = String(newJsonData[key]).split('\\}').join('}');
// }
if (newJsonData[key] === key && locale !== defaultLocale) {
newJsonData[key] = '';
}
});
// если есть данные для сохранения то создаем по файл
if (Object.keys(newJsonData).length > 0) {
if (locale === defaultLocale) {
const poContent = yield (0, i18next_conv_1.i18nextToPot)(locale, JSON.stringify(newJsonData, null, 4));
const newPoContent = poContent
.toString()
.split('\n')
.filter((line) => !(line.includes('POT-Creation-Date') ||
line.includes('PO-Revision-Date')))
.join('\n');
if (!(0, fs_1.existsSync)((0, path_1.dirname)(defaultPotFile))) {
(0, fs_1.mkdirSync)((0, path_1.dirname)(defaultPotFile), { recursive: true });
}
if (!(0, fast_deep_equal_1.default)(newJsonData, defaultJsonPotData) ||
!(0, fs_1.existsSync)(defaultPotFile) ||
newPoContent !== poContent) {
(0, fs_1.writeFileSync)(defaultPotFile, newPoContent.toString());
}
}
const poContent = yield (0, i18next_conv_1.i18nextToPo)(locale, JSON.stringify(newJsonData, null, 4));
const newPoContent = poContent
.toString()
.split('\n')
.filter((line) => !(line.includes('POT-Creation-Date') ||
line.includes('PO-Revision-Date')))
.join('\n');
if (!(0, fs_1.existsSync)((0, path_1.dirname)(localePoFile))) {
(0, fs_1.mkdirSync)((0, path_1.dirname)(localePoFile), { recursive: true });
}
if (!(0, fast_deep_equal_1.default)(newJsonData, localeJsonPoData) ||
!(0, fs_1.existsSync)(localePoFile) ||
newPoContent !== poContent) {
(0, fs_1.writeFileSync)(localePoFile, newPoContent.toString());
}
if (!(0, fs_1.existsSync)((0, path_1.dirname)(localeJsonFile))) {
(0, fs_1.mkdirSync)((0, path_1.dirname)(localeJsonFile), { recursive: true });
}
if (!(0, fast_deep_equal_1.default)(newJsonData, localeJsonData) || !(0, fs_1.existsSync)(localeJsonFile)) {
(0, fs_1.writeFileSync)(localeJsonFile, JSON.stringify(newJsonData, null, 4));
}
}
else {
if ((0, fs_1.existsSync)(localeJsonFile)) {
(0, fs_1.unlinkSync)(localeJsonFile);
}
if ((0, fs_1.existsSync)(localePoFile)) {
(0, fs_1.unlinkSync)(localePoFile);
}
}
});
}
extractWithMarkers(marker, sourceRoot, pattern, newJsonData) {
let extractor = null;
if (marker) {
extractor = new gettext_extractor_1.GettextExtractor();
extractor
.createJsParser([
gettext_extractor_1.JsExtractors.callExpression(marker, {
arguments: {
text: 0,
context: 1,
},
}),
])
.parseFilesGlob(`./${sourceRoot}/${pattern}`);
}
extractor
? extractor.getMessages().reduce((all, cur) => {
// сканируем исходники и ищим по маркеру слова, если есть новые, то добавляем их в общий json
if (cur.text && !newJsonData[cur.text]) {
all[cur.text] = cur.text;
newJsonData[cur.text] = cur.text;
}
return all;
}, {})
: {};
}
};
GettextService.title = 'gettext';
GettextService = tslib_1.__decorate([
(0, common_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [utils_service_1.UtilsService])
], GettextService);
exports.GettextService = GettextService;