lr-i18n
Version:
Allows to connect your `Laravel` Framework localization files with `React`.
138 lines (112 loc) • 4.16 kB
text/typescript
import fs from 'fs';
import { createLogger } from 'vite';
import { convertToKeyType, saveKeyTypeToFile } from './plugin/key-type';
import parser from './plugin/parser';
import locale from './plugin/locale';
interface ConfigInterface {
langDirname?: string;
typeDestinationPath?: string;
typeTranslationKeys?: boolean;
}
/**
*
*/
export default function i18n(config?: ConfigInterface) {
const langDirname = config?.langDirname ? config.langDirname : 'lang';
const logger = createLogger('info', { prefix: '[laravel-react-i18n]' });
let isPhpLocale = false;
let files: { path: string; basename: string }[] = [];
let exitHandlersBound = false;
let jsonLocales: string[] = [];
let phpLocales: string[] = [];
function clean() {
files.forEach((file) => fs.existsSync(file.path) && fs.unlinkSync(file.path));
files = [];
}
function pushKeys(keys: string[], locales: string[]) {
if (
typeof process.env.VITE_LARAVEL_REACT_I18N_LOCALE !== 'undefined' &&
locales.includes(process.env.VITE_LARAVEL_REACT_I18N_LOCALE)
) {
const fileName = isPhpLocale
? `php_${process.env.VITE_LARAVEL_REACT_I18N_LOCALE}`
: process.env.VITE_LARAVEL_REACT_I18N_LOCALE;
keys.push(convertToKeyType(langDirname, fileName));
}
if (
typeof process.env.VITE_LARAVEL_REACT_I18N_FALLBACK_LOCALE !== 'undefined' &&
locales.includes(process.env.VITE_LARAVEL_REACT_I18N_FALLBACK_LOCALE) &&
process.env.VITE_LARAVEL_REACT_I18N_LOCALE !== process.env.VITE_LARAVEL_REACT_I18N_FALLBACK_LOCALE
) {
const fileName = isPhpLocale
? `php_${process.env.VITE_LARAVEL_REACT_I18N_FALLBACK_LOCALE}`
: process.env.VITE_LARAVEL_REACT_I18N_FALLBACK_LOCALE;
keys.push(convertToKeyType(langDirname, fileName));
}
}
return {
name: 'i18n',
enforce: 'post',
config() {
const keys: string[] = [];
// Check language directory is exists.
if (!fs.existsSync(langDirname)) {
const msg = [
'Language directory is not exist, maybe you did not publish the language files with `php artisan lang:publish`.',
'For more information please visit: https://laravel.com/docs/10.x/localization#publishing-the-language-files'
];
msg.map((str) => logger.error(str, { timestamp: true }));
return;
}
// JSON-file locales.
jsonLocales = locale.getJsonLocale(langDirname);
if (config?.typeTranslationKeys) {
pushKeys(keys, jsonLocales);
}
// PHP-file locales.
phpLocales = locale.getPhpLocale(langDirname);
if (phpLocales.length > 0) {
files = parser(langDirname);
isPhpLocale = true;
if (config?.typeTranslationKeys) {
pushKeys(keys, phpLocales);
}
} else {
const msg = [
'Language directory not contain php translations files.',
'For more information please visit: https://laravel.com/docs/10.x/localization#introduction'
];
msg.map((str) => logger.info(str, { timestamp: true }));
}
if (config?.typeTranslationKeys) {
saveKeyTypeToFile(keys.join('|'), config?.typeDestinationPath);
}
},
buildEnd: clean,
handleHotUpdate(ctx: any) {
const keys: string[] = [];
if (config?.typeTranslationKeys) {
pushKeys(keys, jsonLocales);
}
if (isPhpLocale) {
if (/lang\/.*\.php$/.test(ctx.file)) {
files = parser(langDirname);
}
if (config?.typeTranslationKeys) {
pushKeys(keys, phpLocales);
}
}
if (config?.typeTranslationKeys) {
saveKeyTypeToFile(keys.join('|'), config?.typeDestinationPath);
}
},
configureServer() {
if (exitHandlersBound) return;
process.on('exit', clean);
process.on('SIGINT', process.exit);
process.on('SIGTERM', process.exit);
process.on('SIGHUP', process.exit);
exitHandlersBound = true;
}
};
}