github CuyZ/Valinor 2.0.0

latest releases: 2.1.2, 2.1.1, 2.1.0...
2 months ago

First release of the v2 series! 🎉

This release introduces some new features but also backward compatibility breaks that are detailed in the upgrading chapter: it is strongly recommended to read it carefully before upgrading.

Notable new features

Mapper converters introduction

A mapper converter allows users to hook into the mapping process and apply custom logic to the input, by defining a callable signature that properly describes when it should be called:

  • A first argument with a type matching the expected input being mapped
  • A return type representing the targeted mapped type

These two types are enough for the library to know when to call the converter and can contain advanced type annotations for more specific use cases.

Below is a basic example of a converter that converts string inputs to uppercase:

(new \CuyZ\Valinor\MapperBuilder())
    ->registerConverter(
        fn (string $value): string => strtoupper($value)
    )
    ->mapper()
    ->map('string', 'hello world'); // 'HELLO WORLD'

Converters can be chained, allowing multiple transformations to be applied to a value. A second callable parameter can be declared, allowing the current converter to call the next one in the chain.

A priority can be given to a converter to control the order in which converters are applied. The higher the priority, the earlier the converter will be executed. The default priority is 0.

(new \CuyZ\Valinor\MapperBuilder())
    ->registerConverter(
        function(string $value, callable $next): string {
            return $next(strtoupper($value));
        }
    )
    ->registerConverter(
        function(string $value, callable $next): string {
            return $next($value . '!');
        },
        priority: -10,
    )
    ->registerConverter(
        function(string $value, callable $next): string {
            return $next($value . '?');
        },
        priority: 10,
    )
    ->mapper()
    ->map('string', 'hello world'); // 'HELLO WORLD?!'

More information can be found in the mapper converter chapter.

NormalizerBuilder introduction

The NormalizerBuilder class has been introduced and will now be the main entry to instantiate normalizers. Therefore, the methods inMapperBuilder that used to configure and return normalizers have been removed.

This decision aims to make a clear distinction between the mapper and the normalizer configuration API, where confusion could arise when using both.

The NormalizerBuilder can be used like this:

$normalizer = (new \CuyZ\Valinor\NormalizerBuilder())
    ->registerTransformer(
        fn (\DateTimeInterface $date) => $date->format('Y/m/d')
    )
    ->normalizer(\CuyZ\Valinor\Normalizer\Format::array())
    ->normalize($someData);

Changes to messages/errors handling

Some changes have been made to the way messages and errors are handled.

It is now easier to fetch messages when error(s) occur during mapping:

try {
    (new \CuyZ\Valinor\MapperBuilder())->mapper()->map(/* … */);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
    // Before (1.x):
    $messages = \CuyZ\Valinor\Mapper\Tree\Message\Messages::flattenFromNode(
        $error->node()
    );
    
    // After (2.x):
    $messages = $error->messages();
}

Upgrading from 1.x to 2.x

See the upgrading chapter.

⚠ BREAKING CHANGES

  • Add purity markers in MapperBuilder and NormalizerBuilder (123058)
  • Add type and source accessors to MappingError (378141)
  • Change exposed error messages codes (15bb11)
  • Introduce NormalizerBuilder as the main entry for normalizers (f79ce2)
  • Introduce internal cache interface and remove PSR-16 dependency (dfdf40)
  • Mark some class constructors as @internal (7fe5fe)
  • Remove MapperBuilder::alter() in favor of mapper converters (bee098)
  • Remove MapperBuilder::enableFlexibleCasting() (f8f16d)
  • Remove unused class PrioritizedList (0b8c89)
  • Remove unused interface IdentifiableSource (aefb20)
  • Rename MapperBuilder::warmup() method to warmupCacheFor() (963156)
  • Rework mapper node and messages handling (14d5ca)

Features

  • Allow MapperBuilder and NormalizerBuilder to clear cache (fe318c)
  • Introduce mapper converters to apply custom logic during mapping (46c823)

Bug Fixes

  • Update file system cache entries permissions (6ffb0f)

Other

  • Remove Throwable inheritance from ErrorMessage (dbd731)
  • Remove old class doc block (4c2194)
  • Remove unused property (53841a)

Don't miss a new Valinor release

NewReleases is sending notifications on new releases.