From d54d08b83a3323d6c04deba464a5aa488f0d7951 Mon Sep 17 00:00:00 2001 From: Francisco Madeira Date: Mon, 28 Oct 2024 16:22:36 +0000 Subject: [PATCH] fix: Add `Enum` and `class-name` support (#191) * fix: Add Enum support * fix: Add support for classes. --- src/loader.ts | 52 ++++++++++++++++++++-------- test/fixtures/lang/en/classnames.php | 11 ++++++ test/fixtures/lang/en/enums.php | 16 +++++++++ test/loader.test.ts | 15 ++++++++ 4 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 test/fixtures/lang/en/classnames.php create mode 100644 test/fixtures/lang/en/enums.php diff --git a/src/loader.ts b/src/loader.ts index b0bb14a..4e4bd06 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -3,6 +3,14 @@ import path from 'path' import { Engine } from 'php-parser' import { ParsedLangFileInterface } from './interfaces/parsed-lang-file' +const toCamelCase = (str: string): string => { + if (str === str.toUpperCase()) { + return str.toLowerCase() + } + + return str.replace(/^\w/, (c) => c.toLowerCase()) +} + export const hasPhpTranslations = (folderPath: string): boolean => { folderPath = folderPath.replace(/[\\/]$/, '') + path.sep @@ -51,14 +59,16 @@ export const parseAll = (folderPath: string): ParsedLangFileInterface[] => { } // If data contains an object with folder name 'vendor' - const vendorIndex = data.findIndex(({ folder }) => folder === 'vendor'); + const vendorIndex = data.findIndex(({ folder }) => folder === 'vendor') if (vendorIndex !== -1) { - const vendorTranslations = data[vendorIndex].translations; - data.splice(vendorIndex, 1); + const vendorTranslations = data[vendorIndex].translations + data.splice(vendorIndex, 1) - data.forEach(langFile => - langFile.translations = mergeVendorTranslations(langFile.folder, langFile.translations, vendorTranslations)); + data.forEach( + (langFile) => + (langFile.translations = mergeVendorTranslations(langFile.folder, langFile.translations, vendorTranslations)) + ) } return data @@ -75,16 +85,18 @@ export const parseAll = (folderPath: string): ParsedLangFileInterface[] => { function mergeVendorTranslations(folder: string, translations: any, vendorTranslations: any) { // Filter the translations from the vendor file that match the current folder - const langTranslationsFromVendor = Object - .entries(vendorTranslations) + const langTranslationsFromVendor = Object.entries(vendorTranslations) .filter(([key]) => key.includes(`.${folder}.`)) - .reduce((acc, [key, value]) => ({ - ...acc, - [key.replace(`.${folder}.`, '::')]: value, - }), {}); + .reduce( + (acc, [key, value]) => ({ + ...acc, + [key.replace(`.${folder}.`, '::')]: value + }), + {} + ) // Merge the vendor translations that matched the folder with the current translations - return { ...translations, ...langTranslationsFromVendor }; + return { ...translations, ...langTranslationsFromVendor } } export const parse = (content: string) => { @@ -121,7 +133,19 @@ const parseItem = (expr) => { } if (expr.key) { - return { [expr.key.value]: parseItem(expr.value) } + 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) @@ -181,7 +205,7 @@ export const readThroughDir = (dir) => { } export const prepareExtendedParsedLangFiles = (langPaths: string[]): ParsedLangFileInterface[] => - langPaths.flatMap(langPath => parseAll(langPath)); + langPaths.flatMap((langPath) => parseAll(langPath)) export const generateFiles = (langPath: string, data: ParsedLangFileInterface[]): ParsedLangFileInterface[] => { data = mergeData(data) diff --git a/test/fixtures/lang/en/classnames.php b/test/fixtures/lang/en/classnames.php new file mode 100644 index 0000000..fdb373d --- /dev/null +++ b/test/fixtures/lang/en/classnames.php @@ -0,0 +1,11 @@ + 'Some Class', + SomeClass::NAME => 'Name', +]; diff --git a/test/fixtures/lang/en/enums.php b/test/fixtures/lang/en/enums.php new file mode 100644 index 0000000..3dc22ed --- /dev/null +++ b/test/fixtures/lang/en/enums.php @@ -0,0 +1,16 @@ + [ + Status::New->value => 'New', + Status::InProgress->value => 'In Progress', + Status::Finished->value => 'Finished', + ], +]; diff --git a/test/loader.test.ts b/test/loader.test.ts index f8fddbf..38cf1fe 100644 --- a/test/loader.test.ts +++ b/test/loader.test.ts @@ -126,6 +126,21 @@ it('transforms simple index array to .json', () => { expect(lang['arr.1']).toBe('bar'); }); +it('transforms enum values to .json', () => { + const lang = parse(fs.readFileSync(isolatedFixtures + '/lang/en/enums.php').toString()); + + expect(lang['status.new']).toBe('New'); + expect(lang['status.inProgress']).toBe('In Progress'); + expect(lang['status.finished']).toBe('Finished'); +}); + +it('transforms class names and consts to .json', () => { + const lang = parse(fs.readFileSync(isolatedFixtures + '/lang/en/classnames.php').toString()); + + expect(lang['someClass']).toBe('Some Class'); + expect(lang['name']).toBe('Name'); +}); + it('ignores empty `array` or `null` translations', () => { const lang = parse(fs.readFileSync(isolatedFixtures + '/lang/en/ignore.php').toString());