gen-jhipster
Version:
VHipster - Spring Boot + Angular/React/Vue in one handy generator
94 lines (93 loc) • 4 kB
JavaScript
/**
* Copyright 2013-2026 the original author or authors from the JHipster project.
*
* This file is part of the JHipster project, see https://www.jhipster.tech/
* for more information.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { inspect } from 'node:util';
import { transform } from '@yeoman/transform';
import { defaultsDeep, get, merge, template } from 'lodash-es';
import { Minimatch } from 'minimatch';
export const createTranslationsFilter = ({ clientI18nDir, nativeLanguage, fallbackLanguage, }) => {
const pattern = !fallbackLanguage || nativeLanguage === fallbackLanguage
? `**/${clientI18nDir}${nativeLanguage}/*.json`
: `**/${clientI18nDir}{${nativeLanguage},${fallbackLanguage}}/*.json`;
const minimatch = new Minimatch(pattern);
return (filePath) => minimatch.match(filePath);
};
export const createTranslationsFileFilter = (opts) => {
const filter = createTranslationsFilter(opts);
return (file) => filter(file.path);
};
export default class TranslationData {
translations;
generator;
constructor({ generator, translations }) {
if (!generator) {
throw new Error('Generator is required');
}
this.generator = generator;
this.translations = translations;
}
loadFromStreamTransform({ enableTranslation, clientI18nDir, nativeLanguage, fallbackLanguage = 'en', }) {
const filter = createTranslationsFileFilter({ clientI18nDir, nativeLanguage, fallbackLanguage });
const minimatchNative = new Minimatch(`**/${clientI18nDir}${nativeLanguage}/*.json`);
return transform(file => {
if (filter(file) && file.contents) {
const contents = JSON.parse(file.contents.toString());
this.mergeTranslation(contents, !minimatchNative.match(file.path));
if (!enableTranslation) {
return undefined;
}
}
return file;
});
}
mergeTranslation(translation, fallback) {
if (fallback) {
defaultsDeep(this.translations, translation);
}
else {
merge(this.translations, translation);
}
}
/**
* Get translation value for a key.
*/
getClientTranslation(translationKey, data) {
let translatedValue = get(this.translations, translationKey);
if (translatedValue === undefined) {
const [last, second, third, ...others] = translationKey.split('.').reverse();
translatedValue =
get(this.translations, `${[...others.reverse(), third].join('.')}['${second}.${last}']`) ??
get(this.translations, `${others.reverse().join('.')}['${third}.${second}.${last}']`);
}
if (translatedValue === undefined) {
const errorMessage = `Translation missing for ${translationKey}`;
this.generator.log.warn(errorMessage);
this.generator.log.debug(`${errorMessage} at ${inspect(this.translations, { depth: null })}`);
return errorMessage;
}
if (!data) {
return translatedValue;
}
/* workaround custom translation for UserManagement */
if (translatedValue.includes('{{ login }}') && !data.login) {
data.login = data.id;
}
const compiledTemplate = template(translatedValue, { interpolate: /{{([\s\S]+?)}}/g });
return compiledTemplate(data);
}
}