|
| 1 | +# Changelog 2.0.0 — 27th of June 2025 |
| 2 | + |
| 3 | +!!! info inline end "[See release on GitHub]" |
| 4 | + [See release on GitHub]: https://github.com/CuyZ/Valinor/releases/tag/2.0.0 |
| 5 | + |
| 6 | +First release of the v2 series! 🎉 |
| 7 | + |
| 8 | +This release introduces some new features but also backward compatibility breaks |
| 9 | +that are detailed [in the upgrading chapter]: it is strongly recommended to read |
| 10 | +it carefully before upgrading. |
| 11 | + |
| 12 | +[in the upgrading chapter]: ../upgrading.md#upgrade-from-1x-to-2x |
| 13 | + |
| 14 | +## Notable new features |
| 15 | + |
| 16 | +**Mapper converters introduction** |
| 17 | + |
| 18 | +A mapper converter allows users to hook into the mapping process and apply |
| 19 | +custom logic to the input, by defining a callable signature that properly |
| 20 | +describes when it should be called: |
| 21 | + |
| 22 | +- A first argument with a type matching the expected input being mapped |
| 23 | +- A return type representing the targeted mapped type |
| 24 | + |
| 25 | +These two types are enough for the library to know when to call the converter |
| 26 | +and can contain advanced type annotations for more specific use cases. |
| 27 | + |
| 28 | +Below is a basic example of a converter that converts string inputs to |
| 29 | +uppercase: |
| 30 | + |
| 31 | +```php |
| 32 | +(new \CuyZ\Valinor\MapperBuilder()) |
| 33 | + ->registerConverter( |
| 34 | + fn (string $value): string => strtoupper($value) |
| 35 | + ) |
| 36 | + ->mapper() |
| 37 | + ->map('string', 'hello world'); // 'HELLO WORLD' |
| 38 | +``` |
| 39 | + |
| 40 | +Converters can be chained, allowing multiple transformations to be applied to a |
| 41 | +value. A second `callable` parameter can be declared, allowing the current |
| 42 | +converter to call the next one in the chain. |
| 43 | + |
| 44 | +A priority can be given to a converter to control the order in which converters |
| 45 | +are applied. The higher the priority, the earlier the converter will be |
| 46 | +executed. The default priority is 0. |
| 47 | + |
| 48 | +```php |
| 49 | +(new \CuyZ\Valinor\MapperBuilder()) |
| 50 | + ->registerConverter( |
| 51 | + function(string $value, callable $next): string { |
| 52 | + return $next(strtoupper($value)); |
| 53 | + } |
| 54 | + ) |
| 55 | + ->registerConverter( |
| 56 | + function(string $value, callable $next): string { |
| 57 | + return $next($value . '!'); |
| 58 | + }, |
| 59 | + priority: -10, |
| 60 | + ) |
| 61 | + ->registerConverter( |
| 62 | + function(string $value, callable $next): string { |
| 63 | + return $next($value . '?'); |
| 64 | + }, |
| 65 | + priority: 10, |
| 66 | + ) |
| 67 | + ->mapper() |
| 68 | + ->map('string', 'hello world'); // 'HELLO WORLD?!' |
| 69 | +``` |
| 70 | + |
| 71 | +More information can be found in the [mapper converter |
| 72 | +chapter](../../how-to/convert-input.md). |
| 73 | + |
| 74 | +**`NormalizerBuilder` introduction** |
| 75 | + |
| 76 | +The `NormalizerBuilder` class has been introduced and will now be the main entry |
| 77 | +to instantiate normalizers. Therefore, the methods in`MapperBuilder` that used |
| 78 | +to configure and return normalizers have been removed. |
| 79 | + |
| 80 | +This decision aims to make a clear distinction between the mapper and the |
| 81 | +normalizer configuration API, where confusion could arise when using both. |
| 82 | + |
| 83 | +The `NormalizerBuilder` can be used like this: |
| 84 | + |
| 85 | +```php |
| 86 | +$normalizer = (new \CuyZ\Valinor\NormalizerBuilder()) |
| 87 | + ->registerTransformer( |
| 88 | + fn (\DateTimeInterface $date) => $date->format('Y/m/d') |
| 89 | + ) |
| 90 | + ->normalizer(\CuyZ\Valinor\Normalizer\Format::array()) |
| 91 | + ->normalize($someData); |
| 92 | +``` |
| 93 | + |
| 94 | +**Changes to messages/errors handling** |
| 95 | + |
| 96 | +Some changes have been made to the way messages and errors are handled. |
| 97 | + |
| 98 | +It is now easier to fetch messages when error(s) occur during mapping: |
| 99 | + |
| 100 | +```php |
| 101 | +try { |
| 102 | + (new \CuyZ\Valinor\MapperBuilder())->mapper()->map(/* … */); |
| 103 | +} catch (\CuyZ\Valinor\Mapper\MappingError $error) { |
| 104 | + // Before (1.x): |
| 105 | + $messages = \CuyZ\Valinor\Mapper\Tree\Message\Messages::flattenFromNode( |
| 106 | + $error->node() |
| 107 | + ); |
| 108 | + |
| 109 | + // After (2.x): |
| 110 | + $messages = $error->messages(); |
| 111 | +} |
| 112 | +``` |
| 113 | + |
| 114 | +## Upgrading from 1.x to 2.x |
| 115 | + |
| 116 | +[See the upgrading chapter](../upgrading.md#upgrade-from-1x-to-2x). |
| 117 | + |
| 118 | +### ⚠ BREAKING CHANGES |
| 119 | + |
| 120 | +* Add purity markers in `MapperBuilder` and `NormalizerBuilder` ([123058](https://github.com/CuyZ/Valinor/commit/12305846c2444533abff2bb343dc046d249139a9)) |
| 121 | +* Add type and source accessors to `MappingError` ([378141](https://github.com/CuyZ/Valinor/commit/37814108beeda6d0200dab780fd787cb1b947899)) |
| 122 | +* Change exposed error messages codes ([15bb11](https://github.com/CuyZ/Valinor/commit/15bb115d6f96ccbfc0bcc2a05227a4535abf9b11)) |
| 123 | +* Introduce `NormalizerBuilder` as the main entry for normalizers ([f79ce2](https://github.com/CuyZ/Valinor/commit/f79ce2b8cfd78120fcd5adef7c7aee3a049f5d3f)) |
| 124 | +* Introduce internal cache interface and remove PSR-16 dependency ([dfdf40](https://github.com/CuyZ/Valinor/commit/dfdf403c0f12326558c7675b1464b77197c1869f)) |
| 125 | +* Mark some class constructors as `@internal` ([7fe5fe](https://github.com/CuyZ/Valinor/commit/7fe5fe5a6d86ec7b9280a11a4b77173b5f0af6ae)) |
| 126 | +* Remove `MapperBuilder::alter()` in favor of mapper converters ([bee098](https://github.com/CuyZ/Valinor/commit/bee098b476639ab200c8320b8690f754876c40f4)) |
| 127 | +* Remove `MapperBuilder::enableFlexibleCasting()` ([f8f16d](https://github.com/CuyZ/Valinor/commit/f8f16df28288459cd3f3e2bc8bb1e0fa2f5e882c)) |
| 128 | +* Remove unused class `PrioritizedList` ([0b8c89](https://github.com/CuyZ/Valinor/commit/0b8c89a3fe4f7f0eccfc8cd4054f6e9f0fc3d3c1)) |
| 129 | +* Remove unused interface `IdentifiableSource` ([aefb20](https://github.com/CuyZ/Valinor/commit/aefb203ddf14fa656e6f72da4daea6366898249c)) |
| 130 | +* Rename `MapperBuilder::warmup()` method to `warmupCacheFor()` ([963156](https://github.com/CuyZ/Valinor/commit/963156a2f23d15388b24316e841299fe10dd296f)) |
| 131 | +* Rework mapper node and messages handling ([14d5ca](https://github.com/CuyZ/Valinor/commit/14d5ca3f393cff26eea93559b0bcb8916e16f8d7)) |
| 132 | + |
| 133 | +### Features |
| 134 | + |
| 135 | +* Allow `MapperBuilder` and `NormalizerBuilder` to clear cache ([fe318c](https://github.com/CuyZ/Valinor/commit/fe318c6c30bab11d9dcdf0138ae6fc74d6cc8d3d)) |
| 136 | +* Introduce mapper converters to apply custom logic during mapping ([46c823](https://github.com/CuyZ/Valinor/commit/46c823e9fe85bc2771b587eaeecbab11c5994f5b)) |
| 137 | + |
| 138 | +### Bug Fixes |
| 139 | + |
| 140 | +* Update file system cache entries permissions ([6ffb0f](https://github.com/CuyZ/Valinor/commit/6ffb0f3266d09bebdaa40558210906de6d269d7a)) |
| 141 | + |
| 142 | +### Other |
| 143 | + |
| 144 | +* Remove `Throwable` inheritance from `ErrorMessage` ([dbd731](https://github.com/CuyZ/Valinor/commit/dbd7312050d29b30574acc3d4c132d48e378c219)) |
| 145 | +* Remove old class doc block ([4c2194](https://github.com/CuyZ/Valinor/commit/4c2194ebbbebf0b0e1f729a11a39828f263d7cb2)) |
| 146 | +* Remove unused property ([53841a](https://github.com/CuyZ/Valinor/commit/53841ac79f6ce0314ded278013f9a5d66defd91f)) |
0 commit comments