From 8e03336c2011b38596338272eab873807df8a703 Mon Sep 17 00:00:00 2001 From: 3m1n3nc3 Date: Sat, 21 Sep 2024 13:39:28 +0100 Subject: [PATCH] Add ability to convert resource keys to camel case. --- .DS_Store | Bin 6148 -> 8196 bytes .github/.DS_Store | Bin 0 -> 6148 bytes README.md | 6 ++-- config/config.php | 11 +++++++ src/Commands/stubs/resource.stub | 2 +- src/Services/Json/JsonResource.php | 38 ++++++++++++++++++++++ tests/Feature/ResourceMakeCommandTest.php | 31 +++++++++++++++++- tests/Feature/ResourceTest.php | 21 ++++++++++++ tests/app/Http/Resources/UserResource.php | 3 +- 9 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 .github/.DS_Store create mode 100644 src/Services/Json/JsonResource.php create mode 100644 tests/Feature/ResourceTest.php diff --git a/.DS_Store b/.DS_Store index 73ed4c2c7f26a7eb371bb08870215cf5c85a7b5f..5595c6c8006a30aaf0d3c037e04dd8f76ad59098 100644 GIT binary patch delta 418 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8FDWo2aMAD7`UYH}hr%jz7$c**Q2S7O*f% zPv&9is!u8}E=bDBPXemlkyMbASzKaZaE+0PnT3@NsE&i1BQ`iAzdX1kv81%vDX}OT z#0$yK&q;!@6O+O+Q_JH8M4a>UN)j{kQj5SEGE-84N@Bt@^HTE5o$^cbQi{QPgCPYm)fGTD%wL60GwA(NqmA%mfmA*n35C@&{JFCC;2h*=qufTEcUISeT&#mPBI zKrd_-W}U{!9DeWV$ AF8}}l delta 167 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5sJ6q~50$SAQfU^g?P#AF_UuE{xqjhmH( zCNZkoaz+8wurZV|q%!0&q%h<&6y@f-xFqG|CxOfmTfQw)UuyDAVL3J^^RKWxlj4Jk uiC-48b8rYU0~G;*05_0u1=+PR@jLTmei=`Y%?wNsSAZPGusNP*4l@9KpCU^D diff --git a/.github/.DS_Store b/.github/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9a4df371c0baf24d54b848253f275ee37b92dfe2 GIT binary patch literal 6148 zcmeHKJxc>Y5PhR5A^}Nhxql)5U=6uKP!OWEL4!>W4iY5ob^dMNd;|@rkjg@5j@h?6 zJ8zeJ#mx->nZK=Pz!boku84OXhNk=K13Qa|qSzS?p74MMceo#9e;-ipC2p|f^GN0= z{}$JJ)_V8SK6hQK^b73KVT%o3(Q>xO?y$}K(^7#{AQeajQh`+91O=jIjwdJNW=blM z3j8kx^!rfgiZ!rzv`+^IYXOKOhRry)UV>OOK&*kiBO^3%D$%JDErvLq@e+A8uy=Gi z#BSy}akE5+B6d6D#nK_wF~?LO6*yMl+?P|W{|)_z{{NVit5hHr_)`kVXt7+(`ASh+ z2QR0!w$NAfgE80AIanzsS}Ep2OYzm0yrOgN*TCM<=!_ekm_GulOIj-M8wz{?Jk1-K literal 0 HcmV?d00001 diff --git a/README.md b/README.md index cc3db80..a0a4ed1 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ -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 @@ -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 @@ -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 diff --git a/config/config.php b/config/config.php index 745b426..4b0f1e9 100644 --- a/config/config.php +++ b/config/config.php @@ -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 ]; diff --git a/src/Commands/stubs/resource.stub b/src/Commands/stubs/resource.stub index ce8ece4..ab107a2 100644 --- a/src/Commands/stubs/resource.stub +++ b/src/Commands/stubs/resource.stub @@ -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 { diff --git a/src/Services/Json/JsonResource.php b/src/Services/Json/JsonResource.php new file mode 100644 index 0000000..3ee918e --- /dev/null +++ b/src/Services/Json/JsonResource.php @@ -0,0 +1,38 @@ +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); + } +} diff --git a/tests/Feature/ResourceMakeCommandTest.php b/tests/Feature/ResourceMakeCommandTest.php index ada0c5e..2b772e2 100644 --- a/tests/Feature/ResourceMakeCommandTest.php +++ b/tests/Feature/ResourceMakeCommandTest.php @@ -1,8 +1,10 @@ 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); } @@ -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(); +}); diff --git a/tests/Feature/ResourceTest.php b/tests/Feature/ResourceTest.php new file mode 100644 index 0000000..ef4cd25 --- /dev/null +++ b/tests/Feature/ResourceTest.php @@ -0,0 +1,21 @@ +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(); +}); diff --git a/tests/app/Http/Resources/UserResource.php b/tests/app/Http/Resources/UserResource.php index e98e826..f0d8ac2 100644 --- a/tests/app/Http/Resources/UserResource.php +++ b/tests/app/Http/Resources/UserResource.php @@ -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 { @@ -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, ]; } }