Skip to content

Commit

Permalink
fix: Add Enum and class-name support (#191)
Browse files Browse the repository at this point in the history
* fix: Add Enum support

* fix: Add support for classes.
  • Loading branch information
xiCO2k authored Oct 28, 2024
1 parent 4b851ea commit d54d08b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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) => {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/lang/en/classnames.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class SomeClass
{
const NAME = 'name';
}

return [
SomeClass::class => 'Some Class',
SomeClass::NAME => 'Name',
];
16 changes: 16 additions & 0 deletions test/fixtures/lang/en/enums.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

enum Status
{
case New = 'new';
case InProgress = 'in_progress';
case Finished = 'finished';
}

return [
Status::class => [
Status::New->value => 'New',
Status::InProgress->value => 'In Progress',
Status::Finished->value => 'Finished',
],
];
15 changes: 15 additions & 0 deletions test/loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down

0 comments on commit d54d08b

Please sign in to comment.