Skip to content

Commit

Permalink
Add ability to convert resource keys to camel case.
Browse files Browse the repository at this point in the history
  • Loading branch information
3m1n3nc3 committed Sep 21, 2024
1 parent 1ef7ffa commit 8e03336
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 6 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file added .github/.DS_Store
Binary file not shown.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<!-- ![GitHub Actions](https://github.com/toneflix/laravel-resource-modifier/actions/workflows/run-tests.yml/badge.svg) -->

A simple Laravel package that intercepts and help you customize, remove or modify the meta data on your Eloquent API Resource response.
A simple Laravel package that intercepts and help you customize, remove or modify the meta data on your Eloquent API Resource response, as well as automatically convert resource keys to camel case.

## Installation

Expand Down Expand Up @@ -45,7 +45,7 @@ Run `php artisan vendor:publish --tag="resource-modifier"`

## Generating Resources

To generate a resource class, you may use the `mod:resource` Artisan command. By default, resources will be placed in the `app/Http/Resources` directory of your application. Resources extend the `Illuminate\Http\Resources\Json\JsonResource` class:
To generate a resource class, you may use the `mod:resource` Artisan command. By default, resources will be placed in the `app/Http/Resources` directory of your application. Resources extend the `ToneflixCode\ResourceModifier\Services\Json\JsonResource` class:

```bash
artisan mod:resource UserResource
Expand Down Expand Up @@ -80,7 +80,7 @@ class ResourceMakeCommand extends ToneflixCodeResourceMakeCommand
}
```

This will overide the default `ResourceMakeCommand` as Laravel will prefer user defined commands over built in ones, so the next time you call `php artisan make:resource UserCollection`, your collection will be created with the Laravel Resource Modifier signature.
This will overide the default `ResourceMakeCommand` as Laravel will prefer user defined commands over built in ones, so the next time you call `php artisan make:resource UserCollection`, your collection will be created with the Laravel Resource Modifier signature.

## Testing

Expand Down
11 changes: 11 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,15 @@
'prev' => 'prev',
'next' => 'next',
],

/*
|---------------------------------------------------------------------------------
| Camel Casing
|---------------------------------------------------------------------------------
|
| When enable, it will try to enforce camel casing for all resource keys
|
*/

'prefer_camel_casing' => true
];
2 changes: 1 addition & 1 deletion src/Commands/stubs/resource.stub
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace {{ namespace }};

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use ToneflixCode\ResourceModifier\Services\Json\JsonResource;

class {{ class }} extends JsonResource
{
Expand Down
38 changes: 38 additions & 0 deletions src/Services/Json/JsonResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace ToneflixCode\ResourceModifier\Services\Json;

use Illuminate\Container\Container;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Resources\Json\JsonResource as IlluminateJsonResource;
use JsonSerializable;

class JsonResource extends IlluminateJsonResource
{
/**
* Resolve the resource to an array.
*
* @param \Illuminate\Http\Request|null $request
* @return array
*/
public function resolve($request = null)
{
$data = $this->toArray(
$request ?: Container::getInstance()->make('request')
);

if ($data instanceof Arrayable) {
$data = $data->toArray();
} elseif ($data instanceof JsonSerializable) {
$data = $data->jsonSerialize();
}

if (config('resource-modifier.prefer_camel_casing', false) === true) {
return collect($this->filter((array) $data))
->mapWithKeys(fn($value, $key) => [str($key)->camel()->toString() => $value])
->toArray();
}

return $this->filter((array) $data);
}
}
31 changes: 30 additions & 1 deletion tests/Feature/ResourceMakeCommandTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<?php

use App\Http\Resources\XyzCollection;
use App\Http\Resources\XyzResource;
use Illuminate\Support\Facades\File;
use ToneflixCode\ResourceModifier\Services\Json\ResourceCollection;
use ToneflixCode\ResourceModifier\Services\Json\JsonResource;
use ToneflixCode\ResourceModifier\Tests\Models\User;

test('can create modified resource collection', function () {
Expand All @@ -12,9 +14,16 @@
expect(XyzCollection::class)->toBe('App\Http\Resources\XyzCollection');
});

test('can create modified resource', function () {

$this->artisan('mod:resource XyzResource')->assertExitCode(0);

expect(XyzResource::class)->toBe('App\Http\Resources\XyzResource');
});

test('can assure that modified resource collection is valid', function () {

$outputPath = realpath(__DIR__.'/../../vendor/orchestra/testbench-core/laravel/app/Http/Resources/XyzCollection.php');
$outputPath = realpath(__DIR__ . '/../../vendor/orchestra/testbench-core/laravel/app/Http/Resources/XyzCollection.php');
if ($outputPath) {
unlink($outputPath);
}
Expand All @@ -30,3 +39,23 @@

expect(stripos($content, ResourceCollection::class) >= 0)->toBeTrue();
});


test('can assure that modified resource is valid', function () {

$outputPath = realpath(__DIR__ . '/../../vendor/orchestra/testbench-core/laravel/app/Http/Resources/XyzResource.php');
if ($outputPath) {
unlink($outputPath);
}
$this->artisan('mod:resource XyzResource')->assertExitCode(0);

User::factory(10)->create();

$content = '';

if ($outputPath) {
$content = File::get($outputPath);
}

expect(stripos($content, JsonResource::class) >= 0)->toBeTrue();
});
21 changes: 21 additions & 0 deletions tests/Feature/ResourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use Illuminate\Support\Facades\Route;
use ToneflixCode\ResourceModifier\Tests\App\Http\Resources\UserResource;
use ToneflixCode\ResourceModifier\Tests\Models\User;

test('can convert resource to camel case', function () {

$user = User::factory()->create();

Route::get('test/users', function () use ($user) {
return present(fn() => new UserResource($user));
});

$response = $this->get('/test/users');

! json_validate($response->content()) && $response->dump();

$response->assertCreated();
expect($response->collect('data')->keys()[3])->toBeCamelCase();
});
3 changes: 2 additions & 1 deletion tests/app/Http/Resources/UserResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace ToneflixCode\ResourceModifier\Tests\App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use ToneflixCode\ResourceModifier\Services\Json\JsonResource;

class UserResource extends JsonResource
{
Expand All @@ -18,6 +18,7 @@ public function toArray(Request $request): array
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'name_email' => $this->name . ' ' . $this->email,
];
}
}

0 comments on commit 8e03336

Please sign in to comment.