Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add Enum and class-name support #191

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading