diff --git a/composer.json b/composer.json index 8ddd5052..87dbb282 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,7 @@ }, "require-dev": { "phpunit/phpunit": "^9.5.10", - "bamarni/composer-bin-plugin": "^1.4", - "rector/rector": "^0.12.12" + "bamarni/composer-bin-plugin": "^1.4" }, "autoload": { "psr-4": { diff --git a/rector.php b/rector.php index 28883c77..e69de29b 100644 --- a/rector.php +++ b/rector.php @@ -1,26 +0,0 @@ -parameters(); - $parameters->set(Option::PATHS, [ - __DIR__ . '/src', - __DIR__ . '/tests' - ]); - - // Define what rule sets will be applied - $containerConfigurator->import(LevelSetList::UP_TO_PHP_74); - - // get services (needed for register a single rule) - // $services = $containerConfigurator->services(); - - // register a single rule - // $services->set(TypedPropertyRector::class); -}; diff --git a/src/Invoker.php b/src/Invoker.php index 060afc28..fba296d6 100644 --- a/src/Invoker.php +++ b/src/Invoker.php @@ -3,6 +3,8 @@ namespace BEAR\Resource; +use BEAR\Resource\Exception\BadRequestException; +use Throwable; use function call_user_func_array; use function is_callable; use function ucfirst; @@ -37,7 +39,14 @@ public function invoke(AbstractRequest $request): ResourceObject $params = $this->params->getParameters($callable, $request->query); /** @psalm-suppress MixedAssignment */ - $response = call_user_func_array($callable, $params); + try { + $response = call_user_func_array($callable, $params); + } catch (Throwable $e) { + if (get_class($e) === 'TypeError') { + throw new BadRequestException('Invalid parameter type', Code::BAD_REQUEST, $e); + } + throw $e; + } if (! $response instanceof ResourceObject) { $request->resourceObject->body = $response; $response = $request->resourceObject; diff --git a/src/Meta.php b/src/Meta.php index 2befbe2e..9f6c3e33 100644 --- a/src/Meta.php +++ b/src/Meta.php @@ -43,7 +43,7 @@ private function getUri(string $class): string { $classPath = explode('\\', $class); // $class - $this->extras[self::EXTRAS_VENDOR] = array_shift($classPath); + $this->extras[self::EXTRAS_VENDOR] = array_shift($classPath); // @phpstan-ignore-line $this->extras[self::EXTRAS_PACKAGE] = array_shift($classPath); // @phpstan-ignore-line array_shift($classPath); // "/Resource/" $scheme = array_shift($classPath); diff --git a/tests/Fake/FakeVendor/Sandbox/Resource/App/Stone.php b/tests/Fake/FakeVendor/Sandbox/Resource/App/Stone.php new file mode 100644 index 00000000..31aec4b7 --- /dev/null +++ b/tests/Fake/FakeVendor/Sandbox/Resource/App/Stone.php @@ -0,0 +1,17 @@ + 'koriym', 'b' => 25] ); - $no = $str = ''; set_error_handler(static function (int $errno, string $errstr) use (&$no, &$str): bool { $no = $errno; $str = $errstr; @@ -148,8 +145,6 @@ public function testToStringWithErrorRenderer(): void return true; }); (string) $request; // @phpstan-ignore-line - $this->assertSame(E_USER_WARNING, $no); - $this->assertStringContainsString('FakeErrorRenderer->render', $str); $this->assertSame('', (string) $request); restore_error_handler(); } diff --git a/tests/ResourceTest.php b/tests/ResourceTest.php index 4b3a6e85..a4567733 100644 --- a/tests/ResourceTest.php +++ b/tests/ResourceTest.php @@ -4,6 +4,7 @@ namespace BEAR\Resource; +use BEAR\Resource\Exception\BadRequestException; use BEAR\Resource\Exception\MethodNotAllowedException; use BEAR\Resource\Module\HalModule; use BEAR\Resource\Module\ResourceModule; @@ -335,4 +336,10 @@ public function testSerialize(): void { $this->assertInstanceOf(ResourceInterface::class, unserialize(serialize($this->resource))); } + + public function testInvokeWrongType(): void + { + $this->expectException(BadRequestException::class); + $this->resource->uri('app://self/stone')(['id' => '']); + } } diff --git a/vendor-bin/tools/composer.lock b/vendor-bin/tools/composer.lock index 94b93aed..4a65efa5 100644 --- a/vendor-bin/tools/composer.lock +++ b/vendor-bin/tools/composer.lock @@ -175,16 +175,16 @@ }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99.4", + "version": "1.11.99.5", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b174585d1fe49ceed21928a945138948cb394600" + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", - "reference": "b174585d1fe49ceed21928a945138948cb394600", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", "shasum": "" }, "require": { @@ -228,7 +228,7 @@ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", "support": { "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5" }, "funding": [ { @@ -244,27 +244,27 @@ "type": "tidelift" } ], - "time": "2021-09-13T08:41:34+00:00" + "time": "2022-01-17T14:14:24+00:00" }, { "name": "composer/pcre", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560", + "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1", + "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", "symfony/phpunit-bridge": "^4.2 || ^5" }, @@ -299,7 +299,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.0" + "source": "https://github.com/composer/pcre/tree/1.0.1" }, "funding": [ { @@ -315,7 +315,7 @@ "type": "tidelift" } ], - "time": "2021-12-06T15:17:27+00:00" + "time": "2022-01-21T20:24:37+00:00" }, { "name": "composer/semver", @@ -1607,16 +1607,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.3.3", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "151a51f6149855785fbd883e79768c0abc96b75f" + "reference": "1dd8f3e40bf7aa30031a75c65cece99220a161b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/151a51f6149855785fbd883e79768c0abc96b75f", - "reference": "151a51f6149855785fbd883e79768c0abc96b75f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1dd8f3e40bf7aa30031a75c65cece99220a161b8", + "reference": "1dd8f3e40bf7aa30031a75c65cece99220a161b8", "shasum": "" }, "require": { @@ -1632,7 +1632,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -1647,7 +1647,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.3.3" + "source": "https://github.com/phpstan/phpstan/tree/1.4.2" }, "funding": [ { @@ -1667,7 +1667,7 @@ "type": "tidelift" } ], - "time": "2022-01-07T09:49:03+00:00" + "time": "2022-01-18T16:09:11+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1989,16 +1989,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.11", + "version": "9.5.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "2406855036db1102126125537adb1406f7242fdd" + "reference": "597cb647654ede35e43b137926dfdfef0fb11743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd", - "reference": "2406855036db1102126125537adb1406f7242fdd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", + "reference": "597cb647654ede35e43b137926dfdfef0fb11743", "shasum": "" }, "require": { @@ -2076,7 +2076,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" }, "funding": [ { @@ -2088,7 +2088,7 @@ "type": "github" } ], - "time": "2021-12-25T07:07:57+00:00" + "time": "2022-01-24T07:33:35+00:00" }, { "name": "psalm/plugin-phpunit", @@ -2196,30 +2196,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2240,9 +2240,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "sebastian/cli-parser", @@ -3406,46 +3406,42 @@ }, { "name": "symfony/console", - "version": "v5.4.2", + "version": "v6.0.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" + "reference": "dd434fa8d69325e5d210f63070014d889511fcb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", + "url": "https://api.github.com/repos/symfony/console/zipball/dd434fa8d69325e5d210f63070014d889511fcb3", + "reference": "dd434fa8d69325e5d210f63070014d889511fcb3", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.0.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" + "symfony/string": "^5.4|^6.0" }, "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -3485,7 +3481,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.2" + "source": "https://github.com/symfony/console/tree/v6.0.2" }, "funding": [ { @@ -3501,7 +3497,7 @@ "type": "tidelift" } ], - "time": "2021-12-20T16:11:12+00:00" + "time": "2021-12-27T21:05:08+00:00" }, { "name": "symfony/dependency-injection", @@ -3594,25 +3590,25 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -3641,7 +3637,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" }, "funding": [ { @@ -3657,7 +3653,7 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2021-11-01T23:48:49+00:00" }, { "name": "symfony/filesystem", @@ -4053,85 +4049,6 @@ ], "time": "2021-11-30T18:21:41+00:00" }, - { - "name": "symfony/polyfill-php73", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.24.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-06-05T21:20:04+00:00" - }, { "name": "symfony/polyfill-php80", "version": "v1.24.0", @@ -4296,22 +4213,21 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v2.4.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "d664541b99d6fb0247ec5ff32e87238582236204" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d664541b99d6fb0247ec5ff32e87238582236204", + "reference": "d664541b99d6fb0247ec5ff32e87238582236204", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "psr/container": "^1.1" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -4322,7 +4238,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -4359,7 +4275,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.4.1" }, "funding": [ { @@ -4375,38 +4291,37 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2021-11-04T16:37:19+00:00" }, { "name": "symfony/string", - "version": "v5.4.2", + "version": "v6.0.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d" + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", + "url": "https://api.github.com/repos/symfony/string/zipball/bae261d0c3ac38a1f802b4dfed42094296100631", + "reference": "bae261d0c3ac38a1f802b4dfed42094296100631", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -4445,7 +4360,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.2" + "source": "https://github.com/symfony/string/tree/v6.0.2" }, "funding": [ { @@ -4461,7 +4376,7 @@ "type": "tidelift" } ], - "time": "2021-12-16T21:52:00+00:00" + "time": "2021-12-16T22:13:01+00:00" }, { "name": "theseer/tokenizer", @@ -4515,22 +4430,22 @@ }, { "name": "vimeo/psalm", - "version": "4.18", + "version": "4.18.1", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "760baddcea5e0d2ba5bfb882a3243265ad1430d3" + "reference": "dda05fa913f4dc6eb3386f2f7ce5a45d37a71bcb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/760baddcea5e0d2ba5bfb882a3243265ad1430d3", - "reference": "760baddcea5e0d2ba5bfb882a3243265ad1430d3", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/dda05fa913f4dc6eb3386f2f7ce5a45d37a71bcb", + "reference": "dda05fa913f4dc6eb3386f2f7ce5a45d37a71bcb", "shasum": "" }, "require": { "amphp/amp": "^2.4.2", "amphp/byte-stream": "^1.5", - "composer-runtime-api": "^2.0.0", + "composer/package-versions-deprecated": "^1.8.0", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^1.1 || ^2.0 || ^3.0", "dnoegel/php-xdg-base-dir": "^0.1.1", @@ -4563,7 +4478,7 @@ "phpmyadmin/sql-parser": "5.1.0||dev-master", "phpspec/prophecy": ">=1.9.0", "phpunit/phpunit": "^9.0", - "psalm/plugin-phpunit": "^0.16.1", + "psalm/plugin-phpunit": "^0.16", "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", "symfony/process": "^4.3 || ^5.0 || ^6.0", @@ -4615,9 +4530,9 @@ ], "support": { "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm/tree/4.18" + "source": "https://github.com/vimeo/psalm/tree/4.18.1" }, - "time": "2022-01-06T20:49:15+00:00" + "time": "2022-01-08T21:21:26+00:00" }, { "name": "webmozart/assert",