UNPKG

laravel-vue-i18n

Version:

allows to connect your `Laravel` Framework localization files with `Vue`.

182 lines 6.2 kB
import fs from 'fs'; import path from 'path'; import { Engine } from 'php-parser'; const toCamelCase = (str) => { if (str === str.toUpperCase()) { return str.toLowerCase(); } return str.replace(/^\w/, (c) => c.toLowerCase()); }; export const hasPhpTranslations = (folderPath) => { folderPath = folderPath.replace(/[\\/]$/, '') + path.sep; try { const folders = fs .readdirSync(folderPath) .filter((file) => fs.statSync(folderPath + path.sep + file).isDirectory()) .sort(); for (const folder of folders) { const lang = {}; const files = fs.readdirSync(folderPath + path.sep + folder).filter((file) => /\.php$/.test(file)); if (files.length > 0) { return true; } } } catch (e) { } return false; }; export const parseAll = (folderPath) => { folderPath = folderPath.replace(/[\\/]$/, '') + path.sep; if (!fs.existsSync(folderPath)) { return []; } const folders = fs .readdirSync(folderPath) .filter((file) => fs.statSync(folderPath + path.sep + file).isDirectory()) .sort(); const data = []; for (const folder of folders) { const langFolderPath = folderPath + path.sep + folder; const lang = readThroughDir(langFolderPath); data.push({ folder, translations: convertToDotsSyntax(lang) }); } // If data contains an object with folder name 'vendor' const vendorIndex = data.findIndex(({ folder }) => folder === 'vendor'); if (vendorIndex !== -1) { const vendorTranslations = data[vendorIndex].translations; data.splice(vendorIndex, 1); data.forEach((langFile) => (langFile.translations = mergeVendorTranslations(langFile.folder, langFile.translations, vendorTranslations))); } return data .filter(({ translations }) => { return Object.keys(translations).length > 0; }) .map(({ folder, translations }) => { return { name: `php_${folder}.json`, translations }; }); }; function mergeVendorTranslations(folder, translations, vendorTranslations) { // Filter the translations from the vendor file that match the current folder const langTranslationsFromVendor = Object.entries(vendorTranslations) .filter(([key]) => key.includes(`.${folder}.`)) .reduce((acc, [key, value]) => ({ ...acc, [key.replace(`.${folder}.`, '::')]: value }), {}); // Merge the vendor translations that matched the folder with the current translations return { ...translations, ...langTranslationsFromVendor }; } export const parse = (content) => { const arr = new Engine({}).parseCode(content, 'lang').children.filter((child) => child.kind === 'return')[0]; if (arr?.expr?.kind !== 'array') { return {}; } return convertToDotsSyntax(parseItem(arr.expr)); }; const parseItem = (expr) => { if (expr.kind === 'string') { return expr.value; } if (expr.kind === 'nullkeyword') { return null; } if (expr.kind === 'array') { let items = expr.items.map((item) => parseItem(item)); if (expr.items.every((item) => item.key !== null)) { items = items.reduce((acc, val) => Object.assign({}, acc, val), {}); } return items; } if (expr.kind === 'bin') { return parseItem(expr.left) + parseItem(expr.right); } if (expr.key) { let key = expr.key.value; if (expr.key.kind === 'staticlookup') { if (expr.key.offset.name === 'class') { key = toCamelCase(expr.key.what.name); } else { key = toCamelCase(expr.key.offset.name); } } else if (expr.key.kind === 'propertylookup') { key = toCamelCase(expr.key.what.offset.name); } return { [key]: parseItem(expr.value) }; } return parseItem(expr.value); }; const convertToDotsSyntax = (list) => { const flatten = (items, context = '') => { const data = {}; if (items === null) { return data; } Object.entries(items).forEach(([key, value]) => { if (typeof value === 'string') { data[context + key] = value; return; } Object.entries(flatten(value, context + key + '.')).forEach(([itemKey, itemValue]) => { data[itemKey] = itemValue; }); }); return data; }; return flatten(list); }; export const reset = (folderPath) => { const dir = fs.readdirSync(folderPath); dir .filter((file) => file.match(/^php_/)) .forEach((file) => { fs.unlinkSync(folderPath + file); }); }; export const readThroughDir = (dir) => { const data = {}; fs.readdirSync(dir).forEach((file) => { const absoluteFile = dir + path.sep + file; if (fs.statSync(absoluteFile).isDirectory()) { const subFolderFileKey = file.replace(/\.\w+$/, ''); data[subFolderFileKey] = readThroughDir(absoluteFile); } else { data[file.replace(/\.\w+$/, '')] = parse(fs.readFileSync(absoluteFile).toString()); } }); return data; }; export const prepareExtendedParsedLangFiles = (langPaths) => langPaths.flatMap((langPath) => parseAll(langPath)); export const generateFiles = (langPath, data) => { data = mergeData(data); if (!fs.existsSync(langPath)) { fs.mkdirSync(langPath); } data.forEach(({ name, translations }) => { fs.writeFileSync(langPath + name, JSON.stringify(translations)); }); return data; }; function mergeData(data) { const obj = {}; data.forEach(({ name, translations }) => { if (!obj[name]) { obj[name] = {}; } obj[name] = { ...obj[name], ...translations }; }); const arr = []; Object.entries(obj).forEach(([name, translations]) => { arr.push({ name, translations }); }); return arr; } //# sourceMappingURL=loader.mjs.map