Skip to content

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Jun 27, 2025

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
cuyz/valinor ^1.4 -> ^2.0 age adoption passing confidence

Release Notes

CuyZ/Valinor (cuyz/valinor)

v2.0.0

Compare Source

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)

v1.17.0

Compare Source

Notable changes

Flexible casting setting split

The mapper setting enableFlexibleCasting is (softly) deprecated in favor of three distinct modes, which guarantee the same functionalities as before.

Allowing scalar value casting:

With this setting enabled, scalar types will accept castable values:

  • Integer types will accept any valid numeric value, for instance the string value "42".

  • Float types will accept any valid numeric value, for instance the string value "1337.42".

  • String types will accept any integer, float or object implementing the Stringable interface.

  • Boolean types will accept any truthy or falsy value:

    • (string) "true", (string) "1" and (int) 1 will be cast to true
    • (string) "false", (string) "0" and (int) 0 will be cast to false
(new \CuyZ\Valinor\MapperBuilder())
    ->allowScalarValueCasting()
    ->mapper()
    ->map('array{id: string, price: float, active: bool}', [
        'id' => 549465210, // Will be cast to string
        'price' => '42.39', // Will be cast to float
        'active' => 1, // Will be cast to bool
    ]);

Allowing non-sequential lists:

By default, list types will only accept sequential keys starting from 0.

This setting allows the mapper to convert associative arrays to a list with sequential keys.

(new \CuyZ\Valinor\MapperBuilder())
    ->allowNonSequentialList()
    ->mapper()
    ->map('list<int>', [
        'foo' => 42,
        'bar' => 1337,
    ]);

// => [0 => 42, 1 => 1337]

Allowing undefined values:

Allows the mapper to accept undefined values (missing from the input), by converting them to null (if the current type is nullable) or an empty array (if the current type is an object or an iterable).

(new \CuyZ\Valinor\MapperBuilder())
    ->allowUndefinedValues()
    ->mapper()
    ->map('array{name: string, age: int|null}', [
        'name' => 'John Doe',
        // 'age' is not defined
    ]);

// => ['name' => 'John Doe', 'age' => null]
Features
  • Split flexible casting setting in three distinct modes (02ef8e)
Other
  • Simplify ValueNode implementation (7e6ccf)

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot added the dependencies Updates project dependencies label Jun 27, 2025
@renovate renovate bot requested a review from eliashaeussler as a code owner June 27, 2025 10:48
Copy link
Contributor Author

renovate bot commented Jun 27, 2025

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: composer.lock
Command failed: composer update cuyz/valinor:2.0.0 --with-dependencies --no-ansi --no-interaction --no-scripts --no-autoloader --no-plugins --minimal-changes
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires cuyz/valinor ^2.0, found cuyz/valinor[2.0.0] but these were not loaded, likely because it conflicts with another require.
  Problem 2
    - eliashaeussler/version-bumper is locked to version 2.4.0 and an update of this package was not requested.
    - eliashaeussler/version-bumper 2.4.0 requires cuyz/valinor ^1.12 -> found cuyz/valinor[1.12.0, ..., 1.17.0] but it conflicts with your root composer.json require (^2.0).

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

@renovate renovate bot force-pushed the renovate/cuyz-valinor-2.x branch 5 times, most recently from 3f405a7 to bcf74a1 Compare July 14, 2025 18:12
| datasource | package      | from   | to    |
| ---------- | ------------ | ------ | ----- |
| packagist  | cuyz/valinor | 1.17.0 | 2.0.0 |
@renovate renovate bot force-pushed the renovate/cuyz-valinor-2.x branch from bcf74a1 to 9368579 Compare July 14, 2025 18:15
Copy link
Contributor Author

renovate bot commented Jul 14, 2025

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@eliashaeussler eliashaeussler enabled auto-merge July 14, 2025 18:30
@eliashaeussler eliashaeussler merged commit 57c27bb into main Jul 14, 2025
14 checks passed
@eliashaeussler eliashaeussler deleted the renovate/cuyz-valinor-2.x branch July 14, 2025 18:31
@coveralls
Copy link
Collaborator

Pull Request Test Coverage Report for Build 16274828940

Details

  • 5 of 5 (100.0%) changed or added relevant lines in 4 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.02%) to 90.061%

Totals Coverage Status
Change from base Build 16274529837: -0.02%
Covered Lines: 1785
Relevant Lines: 1982

💛 - Coveralls

@eliashaeussler eliashaeussler changed the title [TASK] Update cuyz/valinor to v2 [FEATURE] Update cuyz/valinor to v2 Jul 14, 2025
@eliashaeussler eliashaeussler added enhancement New feature or request and removed dependencies Updates project dependencies labels Jul 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants