Update dependency cuyz/valinor to v2 - #485
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
7 times, most recently
from
November 30, 2025 13:09
cfd5457 to
23ffe46
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
6 times, most recently
from
December 12, 2025 00:04
049200b to
e53d51a
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
3 times, most recently
from
December 20, 2025 08:43
8e42656 to
2c5cf92
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
from
December 31, 2025 15:58
2c5cf92 to
9b7c208
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
3 times, most recently
from
January 19, 2026 21:16
f95a62e to
6ecd49e
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
7 times, most recently
from
January 27, 2026 09:00
2f9c09f to
ac5dea8
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
2 times, most recently
from
January 30, 2026 22:07
798d51d to
453ef0c
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
2 times, most recently
from
March 3, 2026 00:39
12f4be5 to
67957b8
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
2 times, most recently
from
March 6, 2026 18:19
d4a4c2e to
01135c8
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
5 times, most recently
from
March 23, 2026 17:44
e4d9fc4 to
95c7fed
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
6 times, most recently
from
March 30, 2026 14:33
f05538e to
498eea7
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
3 times, most recently
from
April 8, 2026 00:55
3b91f98 to
d870dc3
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
7 times, most recently
from
April 16, 2026 22:39
45a1703 to
107b0d8
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
2 times, most recently
from
April 21, 2026 23:35
7c04400 to
9f35972
Compare
renovate
Bot
force-pushed
the
renovate/cuyz-valinor-2.x
branch
2 times, most recently
from
April 26, 2026 16:43
1c29c9a to
c319c22
Compare
| datasource | package | from | to | | ---------- | ------------ | ------ | ----- | | packagist | cuyz/valinor | 1.17.0 | 2.6.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
1.17.0→2.6.0Release Notes
CuyZ/Valinor (cuyz/valinor)
v2.6.0Compare Source
Notable changes
This release brings a set of new features to the library:
Enjoy! 🎉
Provided mapper configurators
A set of configurators is now available out-of-the-box for the mapper, mirroring the normalizer configurators introduced in the previous release. Each one can be used either globally through the
configureWith()method or locally as an attribute targeting a specific property.The
MapToDateTimeFromFormatconfigurator parses the input string using the given date format, which must follow the syntax supported byDateTimeImmutable::createFromFormat():The
MapExplodedStringToListconfigurator explodes a string into a list using the given separator, which is useful when the input carries a list as a single delimited string, for instance a value coming from a CSV file or a query parameter:The
MapArrayToListconfigurator discards the keys of an array and maps its values to a list, for cases where the input is an associative array, or a sparse list with missing or out-of-order indices, that should be handled as a sequential list:Finally, the
MapFromJsonconfigurator decodes a JSON string and hands the result over to the mapper, so that the usual validation and error reporting still apply to the decoded value:Scalar value casting
Four configurators convert a scalar value to a specific type before mapping:
MapAsBool,MapAsInt,MapAsFloatandMapAsString. They are useful when the input data carries values in a different representation than the targeted type, for instance numbers or booleans encoded as strings in a form submission, a CSV file or a JSON payload.Used as an attribute, a single property is cast, leaving the strictness rules untouched for every other value:
Casting can also be enabled for every value of a given type with the new
allowCastingToBoolean(),allowCastingToInteger(),allowCastingToFloat()andallowCastingToString()methods of the mapper builder. They offer a finer control thanallowScalarValueCasting(), which relaxes strictness for all scalar types at once:Mapping a property from a specific key
The new
MapFromKeyattribute feeds a class property, or a constructor/method argument, from a specific source key instead of matching it against the property name:This attribute is built on a lightweight protocol that is open to userland: any attribute class declaring a
mapKey(string $key): stringmethod and carrying the#[AsConverter]attribute can remap the key of the element it is placed on. This is handy to factor out a recurring transformation, such as a prefix shared by several properties:New normalizer configurators
Three configurators join the ones introduced in the previous release.
The
NormalizeKeyToattribute renames the key of a property during normalization, when the name used in the data format differs from the one used in the PHP codebase:The
NormalizeToSingleValueclass flattens an object holding a single property, so that instead of['someProperty' => 'value']the normalized result is simply'value'. It can be used either as a configurator, applying to every object with a single property, or as an attribute targeting a specific class or property:The
IgnoreOnNormalizationattribute excludes a property from the normalized output, for instance to hide sensitive data such as a password. For the attribute to take effect, an instance of this class must also be registered on the builder viaconfigureWith():Generics of PHP internal classes
Generics used to be limited to userland classes, because classes internal to PHP or provided by an extension cannot declare
@templateannotations in their own source code. The library now ships generic signatures for a wide range of them, includingArrayObject,ArrayIterator, the SPL data structures and theDscollection classes, so they can be parameterized like any other class:Every one of these templates declares a default type, so bare references like
ArrayObjectkeep resolving as before.Default types for templates
A
@templateannotation can now declare a default type with=. A template that declares a default type may be omitted when the class is referenced, in which case the default type is used:A default type is what makes it possible to add a template to a class that is already referenced elsewhere: the existing references, which do not fill the new template in, keep resolving to its default type and can be made more precise later on.
Overriding an unparseable type
When a property, parameter or return type uses a PHPStan or Psalm syntax that the library cannot parse yet, for instance a conditional type like
($a is 1 ? int : null), the dedicated@valinor-var,@valinor-paramand@valinor-returnannotations can be used to give the library a type it understands. They take precedence over every other annotation, so the static analysis tools keep using their own type while the library uses the override:Features
@valinor-*annotations to override an unparseable type (11938c)@templateannotations (0d6efe)MapArrayToList(1f81fa)MapAsBool(65dfed)MapAsFloat(84eea9)MapAsInt(ea28a7)MapAsString(6b0528)MapExplodedStringToList(beb4db)MapFromJson(469863)MapToDateTimeFromFormat(d6e53b)IgnoreOnNormalization(9769f2)NormalizeKeyTo(947127)NormalizeToSingleValue(7c5f13)Bug Fixes
Internal
canCast()andcast()from scalar types (eae3f0)v2.5.1Compare Source
Bug Fixes
Internal
v2.5.0Compare Source
Notable changes
This release brings a set of new features to the library:
key-oftype supportEnjoy! 🎉
Normalizer configurators support
A set of configurators is now available for the normalizer, mirroring the mapper configurators introduced in the previous release. Each one can be used either globally through the
configureWith()method or locally as an attribute targeting a specific class or property.Keys case normalization
Four configurators normalize the keys of a normalized object to a given case. This is useful to expose data following a naming convention that differs from the one used in the PHP codebase.
new NormalizeKeysToCamelCase()first_name→firstNamenew NormalizeKeysToPascalCase()first_name→FirstNamenew NormalizeKeysToSnakeCase()firstName→first_namenew NormalizeKeysToKebabCase()firstName→first-nameUsed globally, the keys of every normalized object are converted:
Used as an attribute, only the keys of the targeted class are converted:
Date and time normalization
The
NormalizeDateTimeFormatconfigurator normalizes anyDateTimeInterfaceinstance to a string using the given format.Used globally, every date and time encountered during normalization is formatted:
Used as an attribute, only the targeted property is formatted:
Shaped list type support
The shaped list type
list{…}is now supported. It works like a shaped array but enforces sequential integer keys starting at0, making it the right type to describe a tuple-like list of values.key-oftype supportThe
key-of<T>type is now supported. It extracts the key types from enums, arrays, lists, and shaped arrays, including array constants. It is compatible with the same syntax as accepted by PHPStan and Psalm.Features
ConvertDateTime(bf688b)NormalizeKeysToCamelCase(b0d38f)NormalizeKeysToKebabCase(9826ca)NormalizeKeysToPascalCase(53bff2)NormalizeKeysToSnakeCase(c831e0)key-oftype mapping (ff16b2)Bug Fixes
Internal
Shell(f84e78)Other
ConvertDateTimeconfigurator toNormalizeDateTimeFormat(b7683a)ConvertKeysTo*Caseconfigurators toMapKeysTo*Case(e38e06)v2.4.0Compare Source
Notable changes
This release brings a whole set of new features to the library:
Enjoy! 🎉
HTTP request mapping support
This library now provides a way to map an HTTP request to controller action parameters or object properties. Parameters can be mapped from route, query and body values.
Three attributes are available to explicitly bind a parameter to a single source, ensuring the value is never resolved from the wrong source:
#[FromRoute]— for parameters extracted from the URL path by router#[FromQuery]— for query string parameters#[FromBody]— for request body valuesThose attributes can be omitted entirely if the parameter is not bound to a specific source, in which case a collision error is raised if the same key is found in more than one source.
This gives controllers a clean, type-safe signature without coupling to a framework's request object, while benefiting from the library's validation and error handling.
Normal mapping rules apply there: parameters are required unless they have a default value.
Route and query parameter values coming from an HTTP request are typically strings. The mapper automatically handles scalar value casting for these parameters: a string
"42"will be properly mapped to anintparameter.Mapping a request using attributes
Consider an API that lists articles for a given author. The author identifier comes from the URL path, while filtering and pagination come from the query string.
Mapping a request without using attributes
When it is unnecessary to distinguish which source a parameter comes from, the attribute can be omitted entirely — the mapper will resolve each parameter from whichever source contains the matching key.
Mapping all parameters at once
Instead of mapping individual query parameters or body values to separate parameters, the
asRootoption can be used to map all of them at once to a single parameter. This is useful when working with complex data structures or when the number of parameters is large.The same approach works with
#[FromBody(asRoot: true)]for body values.Mapping to an object
Instead of mapping to a callable's arguments, an
HttpRequestcan be mapped directly to an object. The attributes work the same way on constructor parameters or promoted properties.Using PSR-7 requests
An
HttpRequestinstance can be built directly from a PSR-7ServerRequestInterface. This is the recommended approach when integrating with frameworks that use PSR-7.The factory method extracts query parameters from
getQueryParams()and body values fromgetParsedBody(). It also passes the original PSR-7 request object through, so it can be injected into controller parameters if needed (see below).Accessing the original request object
When building an
HttpRequest, an original request object can be provided. If a controller parameter's type matches this object, it will be injected automatically; no attribute is needed.Error handling
When the mapping fails — for instance because a required query parameter is missing or a body value has the wrong type — a
MappingErroris thrown, just like with regular mapping.Read the validation and error handling chapter for more information.
Mapper/Normalizer configurators support
Introduce
MapperBuilderConfiguratorandNormalizerBuilderConfiguratorinterfaces along with aconfigureWith()method on both builders.A configurator is a reusable piece of configuration logic that can be applied to a
MapperBuilderor aNormalizerBuilderinstance. This is useful when the same configuration needs to be applied in multiple places across an application, or when configuration logic needs to be distributed as a package.In the example below, we apply two configuration settings to a
MapperBuilderinside a single class, but this could contain any number of customizations, depending on the needs of the application.This configurator can be registered within the
MapperBuilderinstance:Composing multiple configurators
Multiple configurators can be combined to compose the final configuration. Each configurator is applied in order, allowing layered and modular configuration.
This approach keeps each configurator focused on a single concern, making them easier to test and reuse independently.
Using
NormalizerBuilderConfiguratorThe same configurator logic can be applied on
NormalizerBuilder:CamelCase/snake_case keys conversion support
Two configurators are available to convert the keys of input data before mapping them to object properties or shaped array keys. This allows accepting data with a different naming convention than the one used in the PHP codebase.
ConvertKeysToCamelCasefirst_name→firstNameFirstName→firstNamefirst-name→firstNameConvertKeysToSnakeCasefirstName→first_nameFirstName→first_namefirst-name→first_nameThis configurator can be combined with a key restriction configurator to both validate and convert keys in a single step. The restriction configurator must be registered before the conversion so that the validation runs on the original input keys.
Keys case restriction support
Four configurators restrict which key case is accepted when mapping input data to objects or shaped arrays. If a key does not match the expected case, a mapping error will be raised.
This is useful, for instance, to enforce a consistent naming convention across an API's input to ensure that a JSON payload only contains
camelCase,snake_case,PascalCaseorkebab-casekeys.Available configurators:
new RestrictKeysToCamelCase()firstNamenew RestrictKeysToPascalCase()FirstNamenew RestrictKeysToSnakeCase()first_namenew RestrictKeysToKebabCase()first-nameFeatures
Bug Fixes
FileWatchingCache(d445e4)Internal
Deps
v2.3.2Compare Source
Notable changes
End of PHP 8.1 support
PHP 8.1 security support has ended on the 31st of December 2025.
See: https://www.php.net/supported-versions.php
Removal of
composer-runtime-apipackage dependencyUsing the
composer-runtime-apilibrary leads to unnecessary IO everytime the library is used; therefore, we prefer to use a basic constant that contains the package version.This change slightly increases performance and makes the package completely dependency free. 🎉
Bug Fixes
Cache
Internal
composer-runtime-apirequirement by PHP constant usage (8152be)Other
v2.3.1Compare Source
Bug Fixes
v2.3.0Compare Source
Notable new features
PHP 8.5 support 🐘
Enjoy the upcoming PHP 8.5 version before it is even officially released!
Performance improvements
The awesome @staabm has identified some performance bottlenecks in the codebase, leading to changes that improved the execution time of the mapper by ~50% in his case (and probably some of yours)!
Incoming HTTP request mapping
There is an ongoing discussion to add support for HTTP request mapping, if that's something you're interested in, please join the discussion!
Features
Other
Internal
ShapedArrayType::toString()(4fcfb6)v2.2.2Compare Source
Bug Fixes
v2.2.1Compare Source
This release contains a lot of internal refactorings that were needed to fix an important bug regarding converters. Although we made our best to provide a stable release, bugs can have slipped through the cracks. If that's the case, please open an issue describing the issue and we will try to fix it as soon as possible.
The commit [d9e3cf0] is the result of a long journey whose goal was to fix a very upsetting bug that would make mapper converters being called when they shouldn't be. This could result in unexpected behaviors and could even lead to invalid data being mapped.
Take the following example below:
We register a converter that will return null if the string length is lower than 5. For this converter to be called, the target type should match the
string|nulltype, because that is what the converter can return.In this example, we want to map a value to
string, which is not matched by the converter return type because it does not containnull. This means that the converter should never be called, because it could return an invalid value (nullwill never be a validstring).Before this commit, the converter would be called and return
null, which would raise an unexpected error:This error was caused by the following line:
It should have been:
Easy fix, isn't it?
Well… actually no. Because changing this completely modifies the behavior of the converters, and the library is now missing a lot of information to properly infer the return type of the converter.
In some cases this change was enough, but in some more complex cases we now would need more information.
For instance, let's take the
CamelCaseKeysexample as it was written in the documentation before this commit:There is a big issue in the types signature of this converter: the
objectreturn type means that the converter can return anything, as long as this is an object. This breaks the type matching contract and the converter should never be called. But it was.This is the new way of writing this converter:
Now, the type matching contract is respected because of the
@templateannotation, and the converter is called when mapping to any object.To be able to properly infer the return type of the converter, we needed to:
@templateannotations inside functionsThis was a huge amount of work, which required several small changes during the last month, as well as [b7f3e5f] and [d9e3cf0]. A lot of work for an error in a single line of code, right? T_T
The good news is: the library is now more powerful than ever, as it is now able to statically infer generic types, which could bring new possibilities in the future.
Now the bad news is: this commit can break backwards compatibility promise in some cases. But as this is still a (huge) bug fix, we will not release a new major version, although it can break some existing code. Instead, converters should be adapted to use proper type signatures.
To help with that, here are the list of the diff that should be applied to converter examples that were written in the documentation:
CamelCaseKeys
RenameKeys
Explode
ArrayToList
JsonDecode
Bug Fixes
Internal
INFconstant to detect default converter value (72079b)Other
Configuration
📅 Schedule: (in timezone UTC)
🚦 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.
This PR was generated by Mend Renovate. View the repository job log.