Skip to content

Commit

Permalink
Add default name mappers
Browse files Browse the repository at this point in the history
  • Loading branch information
przemyslaw-przylucki committed Aug 17, 2024
1 parent e34dabd commit eee600c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
10 changes: 10 additions & 0 deletions config/data.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Illuminate\Support\Enumerable;
use Spatie\LaravelData\Mappers\NameMapper;

return [
/**
Expand Down Expand Up @@ -128,6 +129,15 @@
*/
'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::OnlyRequests->value,

/**
* The default name mapping strategy for data objects' keys.
* This has to be a class implementing the `Spatie\LaravelData\Mappers\NameMapper` interface.
*/
'naming_strategy' => [
'input' => null,
'output' => null,
],

/**
* When using an invalid include, exclude, only or except partial, the package will
* throw an exception. You can disable this behaviour by setting this option to true.
Expand Down
20 changes: 18 additions & 2 deletions src/Resolvers/NameMappersResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ protected function resolveInputNameMapper(
): ?NameMapper {
/** @var \Spatie\LaravelData\Attributes\MapInputName|\Spatie\LaravelData\Attributes\MapName|null $mapper */
$mapper = $attributes->first(fn (object $attribute) => $attribute instanceof MapInputName)
?? $attributes->first(fn (object $attribute) => $attribute instanceof MapName);
?? $attributes->first(fn (object $attribute) => $attribute instanceof MapName)
?? $this->resolveDefaultNameMapper(input: true);

if ($mapper) {
return $this->resolveMapper($mapper->input);
Expand All @@ -48,7 +49,8 @@ protected function resolveOutputNameMapper(
): ?NameMapper {
/** @var \Spatie\LaravelData\Attributes\MapOutputName|\Spatie\LaravelData\Attributes\MapName|null $mapper */
$mapper = $attributes->first(fn (object $attribute) => $attribute instanceof MapOutputName)
?? $attributes->first(fn (object $attribute) => $attribute instanceof MapName);
?? $attributes->first(fn (object $attribute) => $attribute instanceof MapName)
?? $this->resolveDefaultNameMapper(input: false);

if ($mapper) {
return $this->resolveMapper($mapper->output);
Expand Down Expand Up @@ -86,4 +88,18 @@ protected function resolveMapperClass(int|string|NameMapper $value): NameMapper

return new ProvidedNameMapper($value);
}

private function resolveDefaultNameMapper(bool $input): null|MapInputName|MapOutputName
{
$nameMapper = config('data.naming_strategy.'.($input ? 'input' : 'output'));

if ($nameMapper === null) {
return null;
}

return match ($input) {
true => new MapInputName($nameMapper),
false => new MapOutputName($nameMapper),
};
}
}
15 changes: 15 additions & 0 deletions tests/Resolvers/NameMappersResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Spatie\LaravelData\Attributes\MapName;
use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Mappers\CamelCaseMapper;
use Spatie\LaravelData\Mappers\StudlyCaseMapper;
use Spatie\LaravelData\Mappers\ProvidedNameMapper;
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
use Spatie\LaravelData\Resolvers\NameMappersResolver;
Expand Down Expand Up @@ -102,6 +103,20 @@ function getAttributes(object $class): Collection
]);
});

it('can have default mappers', function () {
config()->set('data.naming_strategy.input', CamelCaseMapper::class);
config()->set('data.naming_strategy.output', SnakeCaseMapper::class);

$attributes = getAttributes(new class () {
public $property;
});

expect($this->resolver->execute($attributes))->toMatchArray([
'inputNameMapper' => new CamelCaseMapper(),
'outputNameMapper' => new SnakeCaseMapper(),
]);
});

it('can ignore certain mapper types', function () {
$attributes = getAttributes(new class () {
#[MapInputName('input'), MapOutputName(CamelCaseMapper::class)]
Expand Down

0 comments on commit eee600c

Please sign in to comment.