From 19914c62428894b3d6408b21fa4e87768abc2704 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 01:47:27 +0200 Subject: [PATCH 01/30] Fix API action names to match HostFact API v2 docs, remove psalm API action name fixes (verified against hostfact.nl/developer/api): - CanResendApproverEmail: resendapproveremail -> resendapprovermail - CanPaymentProcessPause: payment_process_pause -> paymentprocesspause - CanPaymentProcessReactivate: payment_process_reactivate -> paymentprocessreactivate - CanAddAttachment/CanDeleteAttachment/CanDownloadAttachment: use controller=attachment with action=add/delete/download - CanAddLine/CanDeleteLine: use controller={name}line with action=add/delete - Hosting: new CanEmailAccountInfo trait sending sendaccountinfobyemail (was incorrectly sharing VPS trait sending sendaccountdatabyemail) - Api.php: store exception message string instead of non-serializable exception object in error array - LICENSE: fix copyright year typo (2105 -> 2015) - Remove psalm (no modern PHP support): config, dependency, and script references --- .gitignore | 1 + LICENSE | 2 +- composer.json | 4 - composer.lock | 3103 +++++------------ psalm.xml | 15 - src/Api/Api.php | 2 +- src/Api/Capabilities/CanAddAttachment.php | 4 +- src/Api/Capabilities/CanAddLine.php | 4 +- src/Api/Capabilities/CanDeleteAttachment.php | 4 +- src/Api/Capabilities/CanDeleteLine.php | 4 +- .../Capabilities/CanDownloadAttachment.php | 4 +- src/Api/Capabilities/CanEmailAccountInfo.php | 20 + .../Capabilities/CanPaymentProcessPause.php | 2 +- .../CanPaymentProcessReactivate.php | 2 +- .../Capabilities/CanResendApproverEmail.php | 2 +- src/Api/Controllers/Hosting.php | 4 +- 16 files changed, 867 insertions(+), 2310 deletions(-) delete mode 100644 psalm.xml create mode 100644 src/Api/Capabilities/CanEmailAccountInfo.php diff --git a/.gitignore b/.gitignore index 6bcc606f7..2d8657406 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.idea/ clover.xml .phpunit.result.cache +CLAUDE.md diff --git a/LICENSE b/LICENSE index 8458fc23d..4db6b03e6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2105 Gerben Geijteman +Copyright (c) 2015 Gerben Geijteman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index cf51919fe..5e84a4adb 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,6 @@ "require-dev": { "phpunit/phpunit": "^9.5", "phpmd/phpmd": "^2.13", - "vimeo/psalm": "^5.1", "orchestra/testbench": "^7.15 || ^8.0", "phpstan/phpstan": "^1.9", "squizlabs/php_codesniffer": "^3.7 || ^4.0", @@ -55,8 +54,6 @@ "test": [ "@phpmd --version", "@phpmd --strict src text cyclomatic.xml", - "@psalm --version", - "@psalm", "@phpstan --version", "@phpstan analyse", "@phpcbf --version", @@ -75,7 +72,6 @@ ], "phpunit": "vendor/phpunit/phpunit/phpunit", "phpmd": "vendor/bin/phpmd", - "psalm": "vendor/bin/psalm", "phpstan": "vendor/bin/phpstan", "phpcs": "vendor/bin/phpcs", "phpcbf": "vendor/bin/phpcbf", diff --git a/composer.lock b/composer.lock index 151e02c40..9aab1e5dd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7cec93e35d1f3af43f8ab0c73cd1eab9", + "content-hash": "df3a354a6f6eef895b7ea067ecaae8c4", "packages": [ { "name": "guzzlehttp/guzzle", @@ -217,16 +217,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", "shasum": "" }, "require": { @@ -242,6 +242,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", + "jshttp/mime-db": "1.54.0.1", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { @@ -313,7 +314,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.8.0" + "source": "https://github.com/guzzle/psr7/tree/2.9.0" }, "funding": [ { @@ -329,7 +330,7 @@ "type": "tidelift" } ], - "time": "2025-08-23T21:21:41+00:00" + "time": "2026-03-10T16:41:02+00:00" }, { "name": "hyperized/value-objects", @@ -789,166 +790,6 @@ } ], "packages-dev": [ - { - "name": "amphp/amp", - "version": "v2.6.4", - "source": { - "type": "git", - "url": "https://github.com/amphp/amp.git", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1", - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^7 | ^8 | ^9", - "react/promise": "^2", - "vimeo/psalm": "^3.12" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "files": [ - "lib/functions.php", - "lib/Internal/functions.php" - ], - "psr-4": { - "Amp\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], - "support": { - "irc": "irc://irc.freenode.org/amphp", - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v2.6.4" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-03-21T18:52:26+00:00" - }, - { - "name": "amphp/byte-stream", - "version": "v1.8.2", - "source": { - "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", - "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", - "shasum": "" - }, - "require": { - "amphp/amp": "^2", - "php": ">=7.1" - }, - "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "amphp/phpunit-util": "^1.4", - "friendsofphp/php-cs-fixer": "^2.3", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^6 || ^7 || ^8", - "psalm/phar": "^3.11.4" - }, - "type": "library", - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Amp\\ByteStream\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "https://amphp.org/byte-stream", - "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" - ], - "support": { - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" - }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-04-13T18:00:56+00:00" - }, { "name": "brick/math", "version": "0.12.3", @@ -1171,16 +1012,16 @@ }, { "name": "composer/pcre", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { @@ -1190,19 +1031,19 @@ "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "phpstan/phpstan": "^1.11.10", - "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - }, "phpstan": { "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-main": "3.x-dev" } }, "autoload": { @@ -1230,7 +1071,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.1" + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { @@ -1246,28 +1087,28 @@ "type": "tidelift" } ], - "time": "2024-08-27T18:44:43+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { "name": "composer/semver", - "version": "3.4.2", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", - "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -1311,7 +1152,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.2" + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { @@ -1321,13 +1162,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-07-12T11:35:52+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { "name": "composer/xdebug-handler", @@ -1470,117 +1307,34 @@ }, "time": "2024-07-08T12:26:09+00:00" }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "v0.1.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" - }, - "type": "library", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "support": { - "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", - "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" - }, - "time": "2019-12-04T15:06:13+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "1.4.10 || 2.0.3", - "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/log": "^1 || ^2 || ^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.4" - }, - "time": "2024-12-07T21:18:45+00:00" - }, { "name": "doctrine/inflector", - "version": "2.0.10", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^11.0", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25 || ^5.4" + "doctrine/coding-standard": "^12.0 || ^13.0", + "phpstan/phpstan": "^1.12 || ^2.0", + "phpstan/phpstan-phpunit": "^1.4 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", + "phpunit/phpunit": "^8.5 || ^12.2" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + "Doctrine\\Inflector\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1625,7 +1379,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.10" + "source": "https://github.com/doctrine/inflector/tree/2.1.0" }, "funding": [ { @@ -1641,34 +1395,33 @@ "type": "tidelift" } ], - "time": "2024-02-18T20:23:39+00:00" + "time": "2025-08-10T19:31:58+00:00" }, { "name": "doctrine/instantiator", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.4" }, "require-dev": { - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^14", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" }, "type": "library", "autoload": { @@ -1695,7 +1448,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + "source": "https://github.com/doctrine/instantiator/tree/2.1.0" }, "funding": [ { @@ -1711,7 +1464,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" + "time": "2026-01-05T06:47:08+00:00" }, { "name": "doctrine/lexer", @@ -1792,29 +1545,28 @@ }, { "name": "dragonmantank/cron-expression", - "version": "v3.4.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "8c784d071debd117328803d86b2097615b457500" + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", - "reference": "8c784d071debd117328803d86b2097615b457500", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", "shasum": "" }, "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" + "php": "^8.2|^8.3|^8.4|^8.5" }, "replace": { "mtdowling/cron-expression": "^1.0" }, "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.32|^2.1.31", + "phpunit/phpunit": "^8.5.48|^9.0" }, "type": "library", "extra": { @@ -1845,7 +1597,7 @@ ], "support": { "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0" }, "funding": [ { @@ -1853,20 +1605,20 @@ "type": "github" } ], - "time": "2024-10-09T13:47:03+00:00" + "time": "2025-10-31T18:51:33+00:00" }, { "name": "egulias/email-validator", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "b115554301161fa21467629f1e1391c1936de517" + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", - "reference": "b115554301161fa21467629f1e1391c1936de517", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", "shasum": "" }, "require": { @@ -1912,7 +1664,7 @@ ], "support": { "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" }, "funding": [ { @@ -1920,20 +1672,20 @@ "type": "github" } ], - "time": "2024-12-27T00:36:43+00:00" + "time": "2025-03-06T22:45:56+00:00" }, { "name": "fakerphp/faker", - "version": "v1.23.1", + "version": "v1.24.1", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", "shasum": "" }, "require": { @@ -1981,123 +1733,22 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" - }, - "time": "2024-01-02T13:46:09+00:00" - }, - { - "name": "felixfbecker/advanced-json-rpc", - "version": "v3.2.1", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", - "shasum": "" - }, - "require": { - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "php": "^7.1 || ^8.0", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "AdvancedJsonRpc\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "A more advanced JSONRPC implementation", - "support": { - "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", - "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" - }, - "time": "2021-06-11T22:34:44+00:00" - }, - { - "name": "felixfbecker/language-server-protocol", - "version": "v1.5.2", - "source": { - "type": "git", - "url": "https://github.com/felixfbecker/php-language-server-protocol.git", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842", - "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "^3.1", - "vimeo/psalm": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "LanguageServerProtocol\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Felix Becker", - "email": "felix.b@outlook.com" - } - ], - "description": "PHP classes for the Language Server Protocol", - "keywords": [ - "language", - "microsoft", - "php", - "server" - ], - "support": { - "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", - "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2" + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" }, - "time": "2022-03-02T22:36:06+00:00" + "time": "2024-11-21T13:46:39+00:00" }, { "name": "fidry/cpu-core-counter", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "8520451a140d3f46ac33042715115e290cf5785f" + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", - "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { @@ -2107,10 +1758,10 @@ "fidry/makefile": "^0.2.0", "fidry/php-cs-fixer-config": "^1.1.2", "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", "phpunit/phpunit": "^8.5.31 || ^9.5.26", "webmozarts/strict-phpunit": "^7.5" }, @@ -2137,7 +1788,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" }, "funding": [ { @@ -2145,30 +1796,30 @@ "type": "github" } ], - "time": "2024-08-06T10:04:20+00:00" + "time": "2025-08-14T07:29:31+00:00" }, { "name": "filp/whoops", - "version": "2.15.4", + "version": "2.18.4", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", + "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", + "php": "^7.1 || ^8.0", "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" }, "suggest": { "symfony/var-dumper": "Pretty print complex values better with var-dumper available", @@ -2208,7 +1859,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.15.4" + "source": "https://github.com/filp/whoops/tree/2.18.4" }, "funding": [ { @@ -2216,35 +1867,35 @@ "type": "github" } ], - "time": "2023-11-03T12:00:00+00:00" + "time": "2025-08-08T12:00:00+00:00" }, { "name": "fruitcake/php-cors", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/fruitcake/php-cors.git", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", "shasum": "" }, "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6|^7" + "php": "^8.1", + "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" }, "require-dev": { - "phpstan/phpstan": "^1.4", + "phpstan/phpstan": "^2", "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" + "squizlabs/php_codesniffer": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -2275,7 +1926,7 @@ ], "support": { "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" }, "funding": [ { @@ -2287,28 +1938,28 @@ "type": "github" } ], - "time": "2023-10-12T05:21:21+00:00" + "time": "2025-12-03T09:33:47+00:00" }, { "name": "graham-campbell/result-type", - "version": "v1.1.3", + "version": "v1.1.4", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3" + "phpoption/phpoption": "^1.9.5" }, "require-dev": { - "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" }, "type": "library", "autoload": { @@ -2337,7 +1988,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" }, "funding": [ { @@ -2349,20 +2000,20 @@ "type": "tidelift" } ], - "time": "2024-07-20T21:45:45+00:00" + "time": "2025-12-27T19:43:20+00:00" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.4", + "version": "v1.0.5", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "30e286560c137526eccd4ce21b2de477ab0676d2" + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/30e286560c137526eccd4ce21b2de477ab0676d2", - "reference": "30e286560c137526eccd4ce21b2de477ab0676d2", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", "shasum": "" }, "require": { @@ -2371,7 +2022,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.44 || ^9.6.25", "uri-template/tests": "1.0.0" }, "type": "library", @@ -2419,7 +2070,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.4" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" }, "funding": [ { @@ -2435,24 +2086,24 @@ "type": "tidelift" } ], - "time": "2025-02-03T10:55:03+00:00" + "time": "2025-08-22T14:27:06+00:00" }, { "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", "shasum": "" }, "require": { - "php": "^5.3|^7.0|^8.0" + "php": "^7.4|^8.0" }, "replace": { "cordoval/hamcrest-php": "*", @@ -2460,8 +2111,8 @@ "kodova/hamcrest-php": "*" }, "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" }, "type": "library", "extra": { @@ -2484,9 +2135,9 @@ ], "support": { "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" }, - "time": "2020-07-09T08:09:16+00:00" + "time": "2025-04-30T06:54:44+00:00" }, { "name": "infection/abstract-testframework-adapter", @@ -2798,20 +2449,20 @@ }, { "name": "justinrainbow/json-schema", - "version": "v5.2.13", + "version": "5.3.3", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/a0b7c13588b102d7d6536823e96d1c88d3dba85e", + "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", @@ -2822,11 +2473,6 @@ "bin/validate-json" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -2861,23 +2507,23 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.3" }, - "time": "2023-09-26T02:20:38+00:00" + "time": "2026-03-24T18:47:53+00:00" }, { "name": "laravel/framework", - "version": "v10.48.29", + "version": "10.50.2", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "8f7f9247cb8aad1a769d6b9815a6623d89b46b47" + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/8f7f9247cb8aad1a769d6b9815a6623d89b46b47", - "reference": "8f7f9247cb8aad1a769d6b9815a6623d89b46b47", + "url": "https://api.github.com/repos/laravel/framework/zipball/3ff39b7a9b83e633383ec9b019827ed54b6d38bc", + "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc", "shasum": "" }, "require": { @@ -3036,6 +2682,7 @@ }, "autoload": { "files": [ + "src/Illuminate/Collections/functions.php", "src/Illuminate/Collections/helpers.php", "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php", @@ -3071,7 +2718,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-03-12T14:42:01+00:00" + "time": "2026-02-15T14:12:07+00:00" }, { "name": "laravel/prompts", @@ -3194,33 +2841,33 @@ }, { "name": "laravel/tinker", - "version": "v2.9.0", + "version": "v2.11.1", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", - "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "url": "https://api.github.com/repos/laravel/tinker/zipball/c9f80cc835649b5c1842898fb043f8cc098dd741", + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", "php": "^7.2.5|^8.0", "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0|^8.0" }, "require-dev": { "mockery/mockery": "~1.3.3|^1.4.2", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.8|^9.3.3" + "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." }, "type": "library", "extra": { @@ -3254,9 +2901,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.9.0" + "source": "https://github.com/laravel/tinker/tree/v2.11.1" }, - "time": "2024-01-04T16:10:04+00:00" + "time": "2026-02-06T14:12:35+00:00" }, { "name": "league/commonmark", @@ -3449,16 +3096,16 @@ }, { "name": "league/flysystem", - "version": "3.29.1", + "version": "3.33.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" + "reference": "570b8871e0ce693764434b29154c54b434905350" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/570b8871e0ce693764434b29154c54b434905350", + "reference": "570b8871e0ce693764434b29154c54b434905350", "shasum": "" }, "require": { @@ -3482,13 +3129,13 @@ "composer/semver": "^3.0", "ext-fileinfo": "*", "ext-ftp": "*", - "ext-mongodb": "^1.3", + "ext-mongodb": "^1.3|^2", "ext-zip": "*", "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "guzzlehttp/psr7": "^2.6", "microsoft/azure-storage-blob": "^1.1", - "mongodb/mongodb": "^1.2", + "mongodb/mongodb": "^1.2|^2", "phpseclib/phpseclib": "^3.0.36", "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.5.11|^10.0", @@ -3526,22 +3173,22 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" + "source": "https://github.com/thephpleague/flysystem/tree/3.33.0" }, - "time": "2024-10-08T08:58:34+00:00" + "time": "2026-03-25T07:59:30+00:00" }, { "name": "league/flysystem-local", - "version": "3.29.0", + "version": "3.31.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", "shasum": "" }, "require": { @@ -3575,9 +3222,9 @@ "local" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" }, - "time": "2024-08-09T21:24:39+00:00" + "time": "2026-01-23T15:30:45+00:00" }, { "name": "league/mime-type-detection", @@ -3720,16 +3367,16 @@ }, { "name": "monolog/monolog", - "version": "3.8.1", + "version": "3.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", "shasum": "" }, "require": { @@ -3747,7 +3394,7 @@ "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", + "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.8", "phpstan/phpstan": "^2", @@ -3807,7 +3454,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.8.1" + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" }, "funding": [ { @@ -3819,7 +3466,7 @@ "type": "tidelift" } ], - "time": "2024-12-05T17:15:07+00:00" + "time": "2026-01-02T08:56:05+00:00" }, { "name": "myclabs/deep-copy", @@ -3989,73 +3636,22 @@ "time": "2025-01-08T20:10:23+00:00" }, { - "name": "netresearch/jsonmapper", - "version": "v4.5.0", + "name": "nette/schema", + "version": "v1.3.5", "source": { "type": "git", - "url": "https://github.com/cweiske/jsonmapper.git", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5" + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8e76efb98ee8b6afc54687045e1b8dba55ac76e5", - "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", "shasum": "" }, "require": { - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", - "squizlabs/php_codesniffer": "~3.5" - }, - "type": "library", - "autoload": { - "psr-0": { - "JsonMapper": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "OSL-3.0" - ], - "authors": [ - { - "name": "Christian Weiske", - "email": "cweiske@cweiske.de", - "homepage": "http://github.com/cweiske/jsonmapper/", - "role": "Developer" - } - ], - "description": "Map nested JSON structures onto PHP classes", - "support": { - "email": "cweiske@cweiske.de", - "issues": "https://github.com/cweiske/jsonmapper/issues", - "source": "https://github.com/cweiske/jsonmapper/tree/v4.5.0" - }, - "time": "2024-09-08T10:13:13+00:00" - }, - { - "name": "nette/schema", - "version": "v1.3.5", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.5" + "nette/utils": "^4.0", + "php": "8.1 - 8.5" }, "require-dev": { "nette/phpstan-rules": "^1.0", @@ -4108,20 +3704,20 @@ }, { "name": "nette/utils", - "version": "v4.0.10", + "version": "v4.1.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "2778deb6aab136c8db4ed1f4d6e9f465ca2dbee3" + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/2778deb6aab136c8db4ed1f4d6e9f465ca2dbee3", - "reference": "2778deb6aab136c8db4ed1f4d6e9f465ca2dbee3", + "url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe", + "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe", "shasum": "" }, "require": { - "php": "8.0 - 8.5" + "php": "8.2 - 8.5" }, "conflict": { "nette/finder": "<3", @@ -4129,8 +3725,10 @@ }, "require-dev": { "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", "nette/tester": "^2.5", - "phpstan/phpstan-nette": "^2.0@stable", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", "tracy/tracy": "^2.9" }, "suggest": { @@ -4144,7 +3742,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -4191,9 +3789,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.10" + "source": "https://github.com/nette/utils/tree/v4.1.3" }, - "time": "2025-12-01T17:30:42+00:00" + "time": "2026-02-13T03:05:33+00:00" }, { "name": "nikic/php-parser", @@ -4248,40 +3846,40 @@ }, { "name": "nunomaduro/collision", - "version": "v7.10.0", + "version": "v7.12.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "49ec67fa7b002712da8526678abd651c09f375b2" + "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/49ec67fa7b002712da8526678abd651c09f375b2", - "reference": "49ec67fa7b002712da8526678abd651c09f375b2", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/995245421d3d7593a6960822063bdba4f5d7cf1a", + "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a", "shasum": "" }, "require": { - "filp/whoops": "^2.15.3", - "nunomaduro/termwind": "^1.15.1", + "filp/whoops": "^2.17.0", + "nunomaduro/termwind": "^1.17.0", "php": "^8.1.0", - "symfony/console": "^6.3.4" + "symfony/console": "^6.4.17" }, "conflict": { "laravel/framework": ">=11.0.0" }, "require-dev": { - "brianium/paratest": "^7.3.0", - "laravel/framework": "^10.28.0", - "laravel/pint": "^1.13.3", - "laravel/sail": "^1.25.0", - "laravel/sanctum": "^3.3.1", - "laravel/tinker": "^2.8.2", - "nunomaduro/larastan": "^2.6.4", - "orchestra/testbench-core": "^8.13.0", - "pestphp/pest": "^2.23.2", - "phpunit/phpunit": "^10.4.1", - "sebastian/environment": "^6.0.1", - "spatie/laravel-ignition": "^2.3.1" + "brianium/paratest": "^7.4.8", + "laravel/framework": "^10.48.29", + "laravel/pint": "^1.21.2", + "laravel/sail": "^1.41.0", + "laravel/sanctum": "^3.3.3", + "laravel/tinker": "^2.10.1", + "nunomaduro/larastan": "^2.10.0", + "orchestra/testbench-core": "^8.35.0", + "pestphp/pest": "^2.36.0", + "phpunit/phpunit": "^10.5.36", + "sebastian/environment": "^6.1.0", + "spatie/laravel-ignition": "^2.9.1" }, "type": "library", "extra": { @@ -4340,7 +3938,7 @@ "type": "patreon" } ], - "time": "2023-10-11T15:45:01+00:00" + "time": "2025-03-14T22:35:49+00:00" }, { "name": "nunomaduro/termwind", @@ -4507,36 +4105,36 @@ }, { "name": "orchestra/canvas", - "version": "v8.11.8", + "version": "v8.12.0", "source": { "type": "git", "url": "https://github.com/orchestral/canvas.git", - "reference": "31b1f338fb9d2f3c97ccbc62b27d3e5bf86a02e5" + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas/zipball/31b1f338fb9d2f3c97ccbc62b27d3e5bf86a02e5", - "reference": "31b1f338fb9d2f3c97ccbc62b27d3e5bf86a02e5", + "url": "https://api.github.com/repos/orchestral/canvas/zipball/76385dfcf96efae5f8533a4d522d14c3c946ac5a", + "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "composer/semver": "^3.0", - "illuminate/console": "^10.48.4", - "illuminate/database": "^10.48.4", - "illuminate/filesystem": "^10.48.4", - "illuminate/support": "^10.48.4", + "illuminate/console": "^10.48.25", + "illuminate/database": "^10.48.25", + "illuminate/filesystem": "^10.48.25", + "illuminate/support": "^10.48.25", "orchestra/canvas-core": "^8.10.2", - "orchestra/testbench-core": "^8.19", + "orchestra/testbench-core": "^8.30", "php": "^8.1", - "symfony/polyfill-php83": "^1.28", + "symfony/polyfill-php83": "^1.31", "symfony/yaml": "^6.2" }, "require-dev": { - "laravel/framework": "^10.48.4", - "laravel/pint": "^1.6", + "laravel/framework": "^10.48.25", + "laravel/pint": "^1.17", "mockery/mockery": "^1.5.1", - "phpstan/phpstan": "^1.10.56", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^10.5", "spatie/laravel-ray": "^1.33" }, @@ -4545,9 +4143,6 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-master": "9.0-dev" - }, "laravel": { "providers": [ "Orchestra\\Canvas\\LaravelServiceProvider" @@ -4576,29 +4171,30 @@ "description": "Code Generators for Laravel Applications and Packages", "support": { "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas/tree/v8.11.8" + "source": "https://github.com/orchestral/canvas/tree/v8.12.0" }, - "time": "2024-03-21T14:41:18+00:00" + "time": "2024-11-30T15:38:25+00:00" }, { "name": "orchestra/canvas-core", - "version": "v8.10.2", + "version": "v8.11.0", "source": { "type": "git", "url": "https://github.com/orchestral/canvas-core.git", - "reference": "3af8fb6b1ebd85903ba5d0e6df1c81aedacfedfc" + "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/3af8fb6b1ebd85903ba5d0e6df1c81aedacfedfc", - "reference": "3af8fb6b1ebd85903ba5d0e6df1c81aedacfedfc", + "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/609c2eccdd595b4bba21702a7ea46433a28ea611", + "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "composer/semver": "^3.0", - "illuminate/console": "^10.38.1", - "illuminate/filesystem": "^10.38.1", + "illuminate/console": "^10.48.22", + "illuminate/filesystem": "^10.48.22", + "orchestra/sidekick": "~1.1.23|~1.2.20", "php": "^8.1", "symfony/polyfill-php83": "^1.28" }, @@ -4607,23 +4203,24 @@ "orchestra/testbench-core": "<8.2.0" }, "require-dev": { - "laravel/framework": "^10.38.1", - "laravel/pint": "^1.6", + "laravel/framework": "^10.48.22", + "laravel/pint": "^1.17", "mockery/mockery": "^1.5.1", "orchestra/testbench-core": "^8.19", - "phpstan/phpstan": "^1.10.6", + "orchestra/workbench": "^8.18.0", + "phpstan/phpstan": "^2.1.17", "phpunit/phpunit": "^10.1", "symfony/yaml": "^6.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "9.0-dev" - }, "laravel": { "providers": [ "Orchestra\\Canvas\\Core\\LaravelServiceProvider" ] + }, + "branch-alias": { + "dev-master": "9.0-dev" } }, "autoload": { @@ -4648,33 +4245,92 @@ "description": "Code Generators Builder for Laravel Applications and Packages", "support": { "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas-core/tree/v8.10.2" + "source": "https://github.com/orchestral/canvas-core/tree/v8.11.0" + }, + "time": "2026-02-24T13:35:32+00:00" + }, + { + "name": "orchestra/sidekick", + "version": "v1.2.20", + "source": { + "type": "git", + "url": "https://github.com/orchestral/sidekick.git", + "reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/sidekick/zipball/267a71b56cb2fe1a634d69fc99889c671b77ff43", + "reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "php": "^8.1", + "symfony/polyfill-php83": "^1.32" + }, + "require-dev": { + "fakerphp/faker": "^1.21", + "laravel/framework": "^10.48.29|^11.44.7|^12.1.1|^13.0", + "laravel/pint": "^1.4", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^8.37.0|^9.14.0|^10.2.0|^11.0", + "phpstan/phpstan": "^2.1.14", + "phpunit/phpunit": "^10.0|^11.0|^12.0", + "symfony/process": "^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Eloquent/functions.php", + "src/Filesystem/functions.php", + "src/Http/functions.php", + "src/functions.php" + ], + "psr-4": { + "Orchestra\\Sidekick\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Packages Toolkit Utilities and Helpers for Laravel", + "support": { + "issues": "https://github.com/orchestral/sidekick/issues", + "source": "https://github.com/orchestral/sidekick/tree/v1.2.20" }, - "time": "2023-12-28T01:27:59+00:00" + "time": "2026-01-12T11:09:33+00:00" }, { "name": "orchestra/testbench", - "version": "v8.23.2", + "version": "v8.37.0", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "c9f89b66aaa245a2e36f046aa431587ba46a3f2e" + "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/c9f89b66aaa245a2e36f046aa431587ba46a3f2e", - "reference": "c9f89b66aaa245a2e36f046aa431587ba46a3f2e", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/c03266385ad996a7c3c9bb6219df8f6558ecea39", + "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.10", + "laravel/framework": "^10.50.0", "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^8.24.3", - "orchestra/workbench": "^1.4.1 || ^8.5", + "orchestra/testbench-core": "^8.40.0", + "orchestra/workbench": "^8.18.0", "php": "^8.1", - "phpunit/phpunit": "^9.6 || ^10.1", + "phpunit/phpunit": "^9.6|^10.1", "symfony/process": "^6.2", "symfony/yaml": "^6.2", "vlucas/phpdotenv": "^5.4.1" @@ -4703,59 +4359,64 @@ ], "support": { "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v8.23.2" + "source": "https://github.com/orchestral/testbench/tree/v8.37.0" }, - "time": "2024-06-04T12:24:55+00:00" + "time": "2026-01-14T02:47:41+00:00" }, { "name": "orchestra/testbench-core", - "version": "v8.24.3", + "version": "v8.42.1", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "c4daf2f1929242f4e4cb33b5ebdaaf631df30a46" + "reference": "40bbb1d61af3e9663949902e1556d41d80483a6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/c4daf2f1929242f4e4cb33b5ebdaaf631df30a46", - "reference": "c4daf2f1929242f4e4cb33b5ebdaaf631df30a46", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/40bbb1d61af3e9663949902e1556d41d80483a6f", + "reference": "40bbb1d61af3e9663949902e1556d41d80483a6f", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", + "orchestra/sidekick": "~1.1.23|~1.2.20", "php": "^8.1", - "symfony/polyfill-php83": "^1.28" + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-php83": "^1.33" }, "conflict": { - "brianium/paratest": "<6.4.0 || >=7.0.0 <7.1.4 || >=8.0.0", - "laravel/framework": "<10.48.2 || >=11.0.0", - "nunomaduro/collision": "<6.4.0 || >=7.0.0 <7.4.0 || >=8.0.0", - "orchestra/testbench-dusk": "<8.21.0 || >=9.0.0", + "brianium/paratest": "<6.4.0|>=7.0.0 <7.1.4|>=8.0.0", + "laravel/framework": "<10.50.0|>=11.0.0", + "laravel/serializable-closure": "<1.3.0|>=3.0.0", + "nunomaduro/collision": "<6.4.0|>=7.0.0 <7.4.0|>=8.0.0", + "orchestra/testbench-dusk": "<8.32.0|>=9.0.0", "orchestra/workbench": "<1.0.0", - "phpunit/phpunit": "<9.6.0 || >=10.6.0" + "pestphp/pest": "<2.0.0", + "phpunit/phpunit": "<9.6.0|>=10.3.0 <10.3.3|>=10.6.0" }, "require-dev": { "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.2", - "laravel/pint": "^1.6", + "laravel/framework": "^10.50.0", + "laravel/pint": "^1.20", + "laravel/serializable-closure": "^1.3|^2.0", "mockery/mockery": "^1.5.1", - "phpstan/phpstan": "^1.11", + "phpstan/phpstan": "^2.1.33", "phpunit/phpunit": "^10.1", - "spatie/laravel-ray": "^1.32.4", + "spatie/laravel-ray": "^1.40.2", "symfony/process": "^6.2", "symfony/yaml": "^6.2", "vlucas/phpdotenv": "^5.4.1" }, "suggest": { - "brianium/paratest": "Allow using parallel testing (^6.4 || ^7.1.4).", + "brianium/paratest": "Allow using parallel testing (^6.4|^7.1.4).", "ext-pcntl": "Required to use all features of the console signal trapping.", "fakerphp/faker": "Allow using Faker for testing (^1.21).", - "laravel/framework": "Required for testing (^10.48.2).", + "laravel/framework": "Required for testing (^10.48.29).", "mockery/mockery": "Allow using Mockery for testing (^1.5.1).", - "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.4 || ^7.4).", + "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.4|^7.4).", "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^8.0).", "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^8.0).", - "phpunit/phpunit": "Allow using PHPUnit for testing (^9.6 || ^10.1).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^9.6|^10.1).", "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^6.2).", "symfony/yaml": "Required for Testbench CLI (^6.2).", "vlucas/phpdotenv": "Required for Testbench CLI (^5.4.1)." @@ -4797,51 +4458,48 @@ "issues": "https://github.com/orchestral/testbench/issues", "source": "https://github.com/orchestral/testbench-core" }, - "time": "2024-06-04T05:00:04+00:00" + "time": "2026-03-31T02:52:50+00:00" }, { "name": "orchestra/workbench", - "version": "v8.5.0", + "version": "v8.19.0", "source": { "type": "git", "url": "https://github.com/orchestral/workbench.git", - "reference": "dce002c20de63b6bde74e0cae2ca558d031a8a17" + "reference": "7d30294ff1382c8654c27902147826a3aabb9a5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/workbench/zipball/dce002c20de63b6bde74e0cae2ca558d031a8a17", - "reference": "dce002c20de63b6bde74e0cae2ca558d031a8a17", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/7d30294ff1382c8654c27902147826a3aabb9a5a", + "reference": "7d30294ff1382c8654c27902147826a3aabb9a5a", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "fakerphp/faker": "^1.21", - "laravel/framework": "^10.38.1", + "laravel/framework": "^10.48.28", "laravel/tinker": "^2.8.2", - "nunomaduro/collision": "^6.4 || ^7.10", - "orchestra/canvas": "^8.11.4", - "orchestra/testbench-core": "^8.24", + "nunomaduro/collision": "^6.4|^7.10", + "orchestra/canvas": "^8.12.0", + "orchestra/canvas-core": "^8.11.0", + "orchestra/sidekick": "~1.1.23|~1.2.20", + "orchestra/testbench-core": "^8.42.0", "php": "^8.1", - "spatie/laravel-ray": "^1.32.4", - "symfony/polyfill-php83": "^1.28", + "symfony/polyfill-php83": "^1.33", + "symfony/process": "^6.2", "symfony/yaml": "^6.2" }, "require-dev": { - "laravel/pint": "^1.4", + "laravel/pint": "^1.20", "mockery/mockery": "^1.5.1", - "phpstan/phpstan": "^1.11", + "phpstan/phpstan": "^2.1.33", "phpunit/phpunit": "^10.1", - "symfony/process": "^6.2" + "spatie/laravel-ray": "^1.40.2" }, "suggest": { "ext-pcntl": "Required to use all features of the console signal trapping." }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, "autoload": { "psr-4": { "Orchestra\\Workbench\\": "src/" @@ -4866,9 +4524,9 @@ ], "support": { "issues": "https://github.com/orchestral/workbench/issues", - "source": "https://github.com/orchestral/workbench/tree/v8.5.0" + "source": "https://github.com/orchestral/workbench/tree/v8.19.0" }, - "time": "2024-05-20T23:51:13+00:00" + "time": "2026-03-24T15:03:48+00:00" }, { "name": "pdepend/pdepend", @@ -5152,181 +4810,6 @@ }, "time": "2022-02-18T08:23:19+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.4.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.1", - "ext-filter": "*", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.5", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" - }, - "time": "2024-05-21T05:55:05+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "153ae662783729388a584b4361f2545e4d841e3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", - "reference": "153ae662783729388a584b4361f2545e4d841e3c", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" - }, - "time": "2024-02-23T11:10:43+00:00" - }, { "name": "phpmd/phpmd", "version": "2.15.0", @@ -5412,16 +4895,16 @@ }, { "name": "phpoption/phpoption", - "version": "1.9.3", + "version": "1.9.5", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", - "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", "shasum": "" }, "require": { @@ -5429,7 +4912,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" }, "type": "library", "extra": { @@ -5471,7 +4954,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" }, "funding": [ { @@ -5483,67 +4966,15 @@ "type": "tidelift" } ], - "time": "2024-07-20T21:41:07+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.30.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/51b95ec8670af41009e2b2b56873bad96682413e", - "reference": "51b95ec8670af41009e2b2b56873bad96682413e", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.30.1" - }, - "time": "2024-09-07T20:13:05+00:00" + "time": "2025-12-27T19:41:33+00:00" }, { "name": "phpstan/phpstan", - "version": "1.12.7", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0" - }, + "version": "1.12.33", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", + "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", "shasum": "" }, "require": { @@ -5588,7 +5019,7 @@ "type": "github" } ], - "time": "2024-10-18T11:12:07+00:00" + "time": "2026-02-28T20:30:03+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5911,16 +5342,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.33", + "version": "9.6.34", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fea06253ecc0a32faf787bd31b261f56f351d049" + "reference": "b36f02317466907a230d3aa1d34467041271ef4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fea06253ecc0a32faf787bd31b261f56f351d049", - "reference": "fea06253ecc0a32faf787bd31b261f56f351d049", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", + "reference": "b36f02317466907a230d3aa1d34467041271ef4a", "shasum": "" }, "require": { @@ -5994,7 +5425,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.33" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" }, "funding": [ { @@ -6018,87 +5449,34 @@ "type": "tidelift" } ], - "time": "2026-01-27T05:25:09+00:00" + "time": "2026-01-27T05:45:00+00:00" }, { - "name": "pimple/pimple", - "version": "v3.5.0", + "name": "povils/phpmnd", + "version": "v3.6.1", "source": { "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" + "url": "https://github.com/povils/phpmnd.git", + "reference": "2002af50f627a03d94d01529a3eb02754a23578d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", - "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "url": "https://api.github.com/repos/povils/phpmnd/zipball/2002af50f627a03d94d01529a3eb02754a23578d", + "reference": "2002af50f627a03d94d01529a3eb02754a23578d", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1 || ^2.0" + "composer-runtime-api": "^2.0", + "nikic/php-parser": "^4.18 || ^5.0", + "php": "^7.4 || ^8.0", + "php-parallel-lint/php-console-highlighter": "^1.0", + "phpunit/php-timer": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0", + "symfony/console": "^4.4 || ^5.0 || ^6.0 || ^7.0 || ^8.0", + "symfony/finder": "^4.4 || ^5.0 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^5.4@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "https://pimple.symfony.com", - "keywords": [ - "container", - "dependency injection" - ], - "support": { - "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" - }, - "time": "2021-10-28T11:13:42+00:00" - }, - { - "name": "povils/phpmnd", - "version": "v3.6.1", - "source": { - "type": "git", - "url": "https://github.com/povils/phpmnd.git", - "reference": "2002af50f627a03d94d01529a3eb02754a23578d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/povils/phpmnd/zipball/2002af50f627a03d94d01529a3eb02754a23578d", - "reference": "2002af50f627a03d94d01529a3eb02754a23578d", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.0", - "nikic/php-parser": "^4.18 || ^5.0", - "php": "^7.4 || ^8.0", - "php-parallel-lint/php-console-highlighter": "^1.0", - "phpunit/php-timer": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0", - "symfony/console": "^4.4 || ^5.0 || ^6.0 || ^7.0 || ^8.0", - "symfony/finder": "^4.4 || ^5.0 || ^6.0 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.6", - "squizlabs/php_codesniffer": "^2.8.1 || ^3.5" + "phpunit/phpunit": "^9.6", + "squizlabs/php_codesniffer": "^2.8.1 || ^3.5" }, "bin": [ "bin/phpmnd" @@ -6380,16 +5758,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.19", + "version": "v0.12.22", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "a4f766e5c5b6773d8399711019bb7d90875a50ee" + "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a4f766e5c5b6773d8399711019bb7d90875a50ee", - "reference": "a4f766e5c5b6773d8399711019bb7d90875a50ee", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/3be75d5b9244936dd4ac62ade2bfb004d13acf0f", + "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f", "shasum": "" }, "require": { @@ -6453,22 +5831,22 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.19" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.22" }, - "time": "2026-01-30T17:33:13+00:00" + "time": "2026-03-22T23:03:24+00:00" }, { "name": "ramsey/collection", - "version": "2.1.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109" + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", - "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", "shasum": "" }, "require": { @@ -6529,27 +5907,26 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.1.0" + "source": "https://github.com/ramsey/collection/tree/2.1.1" }, - "time": "2025-03-02T04:48:29+00:00" + "time": "2025-03-22T05:38:12+00:00" }, { "name": "ramsey/uuid", - "version": "4.7.6", + "version": "4.9.2", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088" + "reference": "8429c78ca35a09f27565311b98101e2826affde0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", + "reference": "8429c78ca35a09f27565311b98101e2826affde0", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", - "ext-json": "*", + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -6557,26 +5934,23 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "captainhook/captainhook": "^5.10", + "captainhook/captainhook": "^5.25", "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.8", - "ergebnis/composer-normalize": "^2.15", - "mockery/mockery": "^1.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.2", - "php-mock/php-mock-mockery": "^1.3", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.9" + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", @@ -6611,95 +5985,26 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.7.6" - }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", - "type": "tidelift" - } - ], - "time": "2024-04-27T21:32:50+00:00" - }, - { - "name": "rector/rector", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/rectorphp/rector.git", - "reference": "556509e2dcf527369892b7d411379c4a02f31859" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/556509e2dcf527369892b7d411379c4a02f31859", - "reference": "556509e2dcf527369892b7d411379c4a02f31859", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.11" - }, - "conflict": { - "rector/rector-doctrine": "*", - "rector/rector-downgrade-php": "*", - "rector/rector-phpunit": "*", - "rector/rector-symfony": "*" - }, - "suggest": { - "ext-dom": "To manipulate phpunit.xml via the custom-rule command" - }, - "bin": [ - "bin/rector" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Instant Upgrade and Automated Refactoring of any PHP code", - "keywords": [ - "automation", - "dev", - "migration", - "refactoring" - ], - "support": { - "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/1.1.0" + "source": "https://github.com/ramsey/uuid/tree/4.9.2" }, - "funding": [ - { - "url": "https://github.com/tomasvotruba", - "type": "github" - } - ], - "time": "2024-05-18T09:40:27+00:00" + "time": "2025-12-14T04:43:48+00:00" }, { "name": "sanmai/later", - "version": "0.1.4", + "version": "0.1.7", "source": { "type": "git", "url": "https://github.com/sanmai/later.git", - "reference": "e24c4304a4b1349c2a83151a692cec0c10579f60" + "reference": "72a82d783864bca90412d8a26c1878f8981fee97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sanmai/later/zipball/e24c4304a4b1349c2a83151a692cec0c10579f60", - "reference": "e24c4304a4b1349c2a83151a692cec0c10579f60", + "url": "https://api.github.com/repos/sanmai/later/zipball/72a82d783864bca90412d8a26c1878f8981fee97", + "reference": "72a82d783864bca90412d8a26c1878f8981fee97", "shasum": "" }, "require": { - "php": ">=7.4" + "php": ">=8.2" }, "require-dev": { "ergebnis/composer-normalize": "^2.8", @@ -6738,7 +6043,7 @@ "description": "Later: deferred wrapper object", "support": { "issues": "https://github.com/sanmai/later/issues", - "source": "https://github.com/sanmai/later/tree/0.1.4" + "source": "https://github.com/sanmai/later/tree/0.1.7" }, "funding": [ { @@ -6746,34 +6051,37 @@ "type": "github" } ], - "time": "2023-10-24T00:25:28+00:00" + "time": "2025-05-11T01:48:00+00:00" }, { "name": "sanmai/pipeline", - "version": "v6.10", + "version": "6.22", "source": { "type": "git", "url": "https://github.com/sanmai/pipeline.git", - "reference": "cbd2ea30ba8bef596b8dad1adb9c92fb2987e430" + "reference": "fb8d0c23b4ef085315a36d397fafa052203020ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sanmai/pipeline/zipball/cbd2ea30ba8bef596b8dad1adb9c92fb2987e430", - "reference": "cbd2ea30ba8bef596b8dad1adb9c92fb2987e430", + "url": "https://api.github.com/repos/sanmai/pipeline/zipball/fb8d0c23b4ef085315a36d397fafa052203020ce", + "reference": "fb8d0c23b4ef085315a36d397fafa052203020ce", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": ">=8.2" }, "require-dev": { "ergebnis/composer-normalize": "^2.8", + "esi/phpunit-coverage-check": ">2", "friendsofphp/php-cs-fixer": "^3.17", - "infection/infection": ">=0.10.5", + "infection/infection": ">=0.30.3", "league/pipeline": "^0.3 || ^1.0", - "phan/phan": ">=1.1", "php-coveralls/php-coveralls": "^2.4.1", - "phpstan/phpstan": ">=0.10", - "phpunit/phpunit": ">=9.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2", + "phpunit/phpunit": ">=9.4 <12", + "sanmai/phpstan-rules": "^0.3.0", + "sanmai/phpunit-double-colon-syntax": "^0.1.1", "vimeo/psalm": ">=2" }, "type": "library", @@ -6803,7 +6111,7 @@ "description": "General-purpose collections pipeline", "support": { "issues": "https://github.com/sanmai/pipeline/issues", - "source": "https://github.com/sanmai/pipeline/tree/v6.10" + "source": "https://github.com/sanmai/pipeline/tree/6.22" }, "funding": [ { @@ -6811,7 +6119,7 @@ "type": "github" } ], - "time": "2024-03-16T01:33:30+00:00" + "time": "2025-07-22T09:07:07+00:00" }, { "name": "sebastian/cli-parser", @@ -7825,102 +7133,123 @@ "time": "2020-09-28T06:39:44+00:00" }, { - "name": "spatie/array-to-xml", - "version": "3.3.0", + "name": "squizlabs/php_codesniffer", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/spatie/array-to-xml.git", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "0525c73950de35ded110cffafb9892946d7771b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f56b220fe2db1ade4c88098d83413ebdfc3bf876", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0525c73950de35ded110cffafb9892946d7771b5", + "reference": "0525c73950de35ded110cffafb9892946d7771b5", "shasum": "" }, "require": { - "ext-dom": "*", - "php": "^8.0" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=7.2.0" }, "require-dev": { - "mockery/mockery": "^1.2", - "pestphp/pest": "^1.21", - "spatie/pest-plugin-snapshots": "^1.1" + "phpunit/phpunit": "^8.4.0 || ^9.3.4 || ^10.5.32 || 11.3.3 - 11.5.28 || ^11.5.31" }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Spatie\\ArrayToXml\\": "src" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://freek.dev", - "role": "Developer" + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], - "description": "Convert an array to xml", - "homepage": "https://github.com/spatie/array-to-xml", + "description": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ - "array", - "convert", - "xml" + "phpcs", + "standards", + "static analysis" ], "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.3.0" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" + "url": "https://github.com/PHPCSStandards", + "type": "github" }, { - "url": "https://github.com/spatie", + "url": "https://github.com/jrfnl", "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-05-01T10:20:27+00:00" + "time": "2025-11-10T16:43:36+00:00" }, { - "name": "spatie/backtrace", - "version": "1.6.1", + "name": "symfony/config", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/spatie/backtrace.git", - "reference": "8373b9d51638292e3bfd736a9c19a654111b4a23" + "url": "https://github.com/symfony/config.git", + "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/8373b9d51638292e3bfd736a9c19a654111b4a23", - "reference": "8373b9d51638292e3bfd736a9c19a654111b4a23", + "url": "https://api.github.com/repos/symfony/config/zipball/2d19dde43fa2ff720b9a40763ace7226594f503b", + "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1|^8.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" }, "require-dev": { - "ext-json": "*", - "laravel/serializable-closure": "^1.3", - "phpunit/phpunit": "^9.3", - "spatie/phpunit-snapshot-assertions": "^4.2", - "symfony/var-dumper": "^5.1" + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Spatie\\Backtrace\\": "src" - } + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7928,461 +7257,91 @@ ], "authors": [ { - "name": "Freek Van de Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "A better backtrace", - "homepage": "https://github.com/spatie/backtrace", - "keywords": [ - "Backtrace", - "spatie" - ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", "support": { - "source": "https://github.com/spatie/backtrace/tree/1.6.1" + "source": "https://github.com/symfony/config/tree/v7.4.8" }, "funding": [ { - "url": "https://github.com/sponsors/spatie", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" }, { - "url": "https://spatie.be/open-source/support-us", - "type": "other" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-04-24T13:22:11+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "spatie/laravel-ray", - "version": "1.36.2", + "name": "symfony/console", + "version": "v6.4.36", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-ray.git", - "reference": "1852faa96e5aa6778ea3401ec3176eee77268718" + "url": "https://github.com/symfony/console.git", + "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/1852faa96e5aa6778ea3401ec3176eee77268718", - "reference": "1852faa96e5aa6778ea3401ec3176eee77268718", + "url": "https://api.github.com/repos/symfony/console/zipball/9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", + "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/contracts": "^7.20|^8.19|^9.0|^10.0|^11.0", - "illuminate/database": "^7.20|^8.19|^9.0|^10.0|^11.0", - "illuminate/queue": "^7.20|^8.19|^9.0|^10.0|^11.0", - "illuminate/support": "^7.20|^8.19|^9.0|^10.0|^11.0", - "php": "^7.4|^8.0", - "rector/rector": "^0.19.2|^1.0", - "spatie/backtrace": "^1.0", - "spatie/ray": "^1.41.1", - "symfony/stopwatch": "4.2|^5.1|^6.0|^7.0", - "zbateson/mail-mime-parser": "^1.3.1|^2.0" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "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|3.0" }, "require-dev": { - "guzzlehttp/guzzle": "^7.3", - "laravel/framework": "^7.20|^8.19|^9.0|^10.0|^11.0", - "orchestra/testbench-core": "^5.0|^6.0|^7.0|^8.0|^9.0", - "pestphp/pest": "^1.22|^2.0", - "phpstan/phpstan": "^1.10.57", - "phpunit/phpunit": "^9.3|^10.1", - "spatie/pest-plugin-snapshots": "^1.1|^2.0", - "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - }, - "laravel": { - "providers": [ - "Spatie\\LaravelRay\\RayServiceProvider" - ] - } - }, "autoload": { "psr-4": { - "Spatie\\LaravelRay\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Easily debug Laravel apps", - "homepage": "https://github.com/spatie/laravel-ray", - "keywords": [ - "laravel-ray", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-ray/issues", - "source": "https://github.com/spatie/laravel-ray/tree/1.36.2" - }, - "funding": [ - { - "url": "https://github.com/sponsors/spatie", - "type": "github" - }, - { - "url": "https://spatie.be/open-source/support-us", - "type": "other" - } - ], - "time": "2024-05-02T08:26:02+00:00" - }, - { - "name": "spatie/macroable", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/macroable.git", - "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", - "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", - "shasum": "" - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.0|^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Macroable\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A trait to dynamically add methods to a class", - "homepage": "https://github.com/spatie/macroable", - "keywords": [ - "macroable", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/macroable/issues", - "source": "https://github.com/spatie/macroable/tree/2.0.0" - }, - "time": "2021-03-26T22:39:02+00:00" - }, - { - "name": "spatie/ray", - "version": "1.41.2", - "source": { - "type": "git", - "url": "https://github.com/spatie/ray.git", - "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/ray/zipball/c44f8cfbf82c69909b505de61d8d3f2d324e93fc", - "reference": "c44f8cfbf82c69909b505de61d8d3f2d324e93fc", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "php": "^7.3|^8.0", - "ramsey/uuid": "^3.0|^4.1", - "spatie/backtrace": "^1.1", - "spatie/macroable": "^1.0|^2.0", - "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", - "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" - }, - "require-dev": { - "illuminate/support": "6.x|^8.18|^9.0", - "nesbot/carbon": "^2.63", - "pestphp/pest": "^1.22", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.19.2", - "spatie/phpunit-snapshot-assertions": "^4.2", - "spatie/test-time": "^1.2" - }, - "bin": [ - "bin/remove-ray.sh" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Spatie\\Ray\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Debug with Ray to fix problems faster", - "homepage": "https://github.com/spatie/ray", - "keywords": [ - "ray", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/ray/issues", - "source": "https://github.com/spatie/ray/tree/1.41.2" - }, - "funding": [ - { - "url": "https://github.com/sponsors/spatie", - "type": "github" - }, - { - "url": "https://spatie.be/open-source/support-us", - "type": "other" - } - ], - "time": "2024-04-24T14:21:46+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "0525c73950de35ded110cffafb9892946d7771b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0525c73950de35ded110cffafb9892946d7771b5", - "reference": "0525c73950de35ded110cffafb9892946d7771b5", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=7.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.4.0 || ^9.3.4 || ^10.5.32 || 11.3.3 - 11.5.28 || ^11.5.31" - }, - "bin": [ - "bin/phpcbf", - "bin/phpcs" - ], - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "Former lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "Current lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" - }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" - }, - { - "url": "https://thanks.dev/u/gh/phpcsstandards", - "type": "thanks_dev" - } - ], - "time": "2025-11-10T16:43:36+00:00" - }, - { - "name": "symfony/config", - "version": "v6.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/5d33e0fb707d603330e0edfd4691803a1253572e", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^5.4|^6.0|^7.0", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/finder": "<5.4", - "symfony/service-contracts": "<2.5" - }, - "require-dev": { - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/config/tree/v6.4.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": "2023-11-09T08:28:32+00:00" - }, - { - "name": "symfony/console", - "version": "v6.4.32", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", - "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" - }, - "conflict": { - "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|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -8407,7 +7366,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.32" + "source": "https://github.com/symfony/console/tree/v6.4.36" }, "funding": [ { @@ -8427,24 +7386,24 @@ "type": "tidelift" } ], - "time": "2026-01-13T08:45:59+00:00" + "time": "2026-03-27T15:30:51+00:00" }, { "name": "symfony/css-selector", - "version": "v6.4.13", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e" + "reference": "8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/cb23e97813c5837a041b73a6d63a9ddff0778f5e", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed", + "reference": "8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.4" }, "type": "library", "autoload": { @@ -8476,7 +7435,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.13" + "source": "https://github.com/symfony/css-selector/tree/v8.0.8" }, "funding": [ { @@ -8487,49 +7446,52 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.1", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f88ff6428afbeb17cc648c8003bd608534750baf" + "reference": "f7025fd7b687c240426562f86ada06a93b1e771d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f88ff6428afbeb17cc648c8003bd608534750baf", - "reference": "f88ff6428afbeb17cc648c8003bd608534750baf", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7025fd7b687c240426562f86ada06a93b1e771d", + "reference": "f7025fd7b687c240426562f86ada06a93b1e771d", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.2.10|^7.0" + "symfony/service-contracts": "^3.6", + "symfony/var-exporter": "^6.4.20|^7.2.5|^8.0" }, "conflict": { "ext-psr": "<1.1|>=2", - "symfony/config": "<6.1", - "symfony/finder": "<5.4", - "symfony/proxy-manager-bridge": "<6.3", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "psr/container-implementation": "1.1|2.0", "symfony/service-implementation": "1.1|2.0|3.0" }, "require-dev": { - "symfony/config": "^6.1|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -8557,7 +7519,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.1" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.8" }, "funding": [ { @@ -8568,25 +7530,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-12-01T14:56:37+00:00" + "time": "2026-03-31T06:50:29+00:00" }, { "name": "symfony/error-handler", - "version": "v6.4.19", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "3d4e55cd2b8f1979a65eba9ab749d6466c316f71" + "reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/3d4e55cd2b8f1979a65eba9ab749d6466c316f71", - "reference": "3d4e55cd2b8f1979a65eba9ab749d6466c316f71", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/2ea68f0e1835ad6a126f93bbc14cd236c10ab361", + "reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361", "shasum": "" }, "require": { @@ -8632,7 +7598,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.19" + "source": "https://github.com/symfony/error-handler/tree/v6.4.36" }, "funding": [ { @@ -8643,33 +7609,37 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-02-02T20:16:33+00:00" + "time": "2026-03-10T15:56:14+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.4.13", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e" + "reference": "f57b899fa736fd71121168ef268f23c206083f0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", - "reference": "0ffc48080ab3e9132ea74ef4e09d8dcf26bf897e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", + "reference": "f57b899fa736fd71121168ef268f23c206083f0a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4", + "symfony/dependency-injection": "<6.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -8678,13 +7648,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0|^7.0" + "symfony/stopwatch": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -8712,7 +7683,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.13" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" }, "funding": [ { @@ -8723,12 +7694,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2026-03-30T13:54:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -8808,25 +7783,25 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.9", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b51ef8059159330b74a4d52f68e671033c0fe463" + "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b51ef8059159330b74a4d52f68e671033c0fe463", - "reference": "b51ef8059159330b74a4d52f68e671033c0fe463", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/58b9790d12f9670b7f53a1c1738febd3108970a5", + "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^5.4|^6.4|^7.0" + "symfony/process": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -8854,7 +7829,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.9" + "source": "https://github.com/symfony/filesystem/tree/v7.4.8" }, "funding": [ { @@ -8865,25 +7840,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-06-28T09:49:33+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/finder", - "version": "v6.4.33", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "24965ca011dac87431729640feef8bcf7b5523e0" + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/24965ca011dac87431729640feef8bcf7b5523e0", - "reference": "24965ca011dac87431729640feef8bcf7b5523e0", + "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", + "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", "shasum": "" }, "require": { @@ -8918,7 +7897,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.33" + "source": "https://github.com/symfony/finder/tree/v6.4.34" }, "funding": [ { @@ -8938,20 +7917,20 @@ "type": "tidelift" } ], - "time": "2026-01-26T13:03:48+00:00" + "time": "2026-01-28T15:16:37+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.29", + "version": "v6.4.35", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88" + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b03d11e015552a315714c127d8d1e0f9e970ec88", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cffffd0a2c037117b742b4f8b379a22a2a33f6d2", + "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2", "shasum": "" }, "require": { @@ -8999,7 +7978,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.29" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.35" }, "funding": [ { @@ -9019,20 +7998,20 @@ "type": "tidelift" } ], - "time": "2025-11-08T16:40:12+00:00" + "time": "2026-03-06T11:15:58+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.19", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "88f2c9f7feff86bb7b9105c5151bc2c1404cd64c" + "reference": "4087ec02119de450e9ebb60806d69c6bb8c6e468" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/88f2c9f7feff86bb7b9105c5151bc2c1404cd64c", - "reference": "88f2c9f7feff86bb7b9105c5151bc2c1404cd64c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4087ec02119de450e9ebb60806d69c6bb8c6e468", + "reference": "4087ec02119de450e9ebb60806d69c6bb8c6e468", "shasum": "" }, "require": { @@ -9073,7 +8052,7 @@ "symfony/config": "^6.1|^7.0", "symfony/console": "^5.4|^6.0|^7.0", "symfony/css-selector": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.1|^7.0.1", "symfony/dom-crawler": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/finder": "^5.4|^6.0|^7.0", @@ -9117,7 +8096,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.19" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.36" }, "funding": [ { @@ -9128,25 +8107,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-02-26T10:51:37+00:00" + "time": "2026-03-31T20:38:11+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.18", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "e93a6ae2767d7f7578c2b7961d9d8e27580b2b11" + "reference": "01b846f48e53ee4096692a383637a1fa4d577301" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/e93a6ae2767d7f7578c2b7961d9d8e27580b2b11", - "reference": "e93a6ae2767d7f7578c2b7961d9d8e27580b2b11", + "url": "https://api.github.com/repos/symfony/mailer/zipball/01b846f48e53ee4096692a383637a1fa4d577301", + "reference": "01b846f48e53ee4096692a383637a1fa4d577301", "shasum": "" }, "require": { @@ -9197,7 +8180,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.18" + "source": "https://github.com/symfony/mailer/tree/v6.4.34" }, "funding": [ { @@ -9208,25 +8191,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-01-24T15:27:15+00:00" + "time": "2026-02-24T09:34:36+00:00" }, { "name": "symfony/mime", - "version": "v6.4.26", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "61ab9681cdfe315071eb4fa79b6ad6ab030a9235" + "reference": "9c31726137c70798f815fb98293ffb8a2a47694c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/61ab9681cdfe315071eb4fa79b6ad6ab030a9235", - "reference": "61ab9681cdfe315071eb4fa79b6ad6ab030a9235", + "url": "https://api.github.com/repos/symfony/mime/zipball/9c31726137c70798f815fb98293ffb8a2a47694c", + "reference": "9c31726137c70798f815fb98293ffb8a2a47694c", "shasum": "" }, "require": { @@ -9282,7 +8269,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.26" + "source": "https://github.com/symfony/mime/tree/v6.4.36" }, "funding": [ { @@ -9302,7 +8289,7 @@ "type": "tidelift" } ], - "time": "2025-09-16T08:22:30+00:00" + "time": "2026-03-30T09:31:23+00:00" }, { "name": "symfony/polyfill-ctype", @@ -9387,86 +8374,6 @@ ], "time": "2024-09-09T11:45:10+00:00" }, - { - "name": "symfony/polyfill-iconv", - "version": "v1.29.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", - "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-iconv": "*" - }, - "suggest": { - "ext-iconv": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Iconv\\": "" - } - }, - "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 for the Iconv extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "iconv", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.29.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": "2024-01-29T20:11:03+00:00" - }, { "name": "symfony/polyfill-intl-grapheme", "version": "v1.33.0", @@ -9972,7 +8879,7 @@ }, { "name": "symfony/polyfill-uuid", - "version": "v1.31.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", @@ -10031,7 +8938,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" }, "funding": [ { @@ -10042,6 +8949,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -10116,16 +9027,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.18", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "e9bfc94953019089acdfb9be51c1b9142c4afa68" + "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e9bfc94953019089acdfb9be51c1b9142c4afa68", - "reference": "e9bfc94953019089acdfb9be51c1b9142c4afa68", + "url": "https://api.github.com/repos/symfony/routing/zipball/5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", + "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", "shasum": "" }, "require": { @@ -10175,94 +9086,11 @@ "keywords": [ "router", "routing", - "uri", - "url" - ], - "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.18" - }, - "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": "2025-01-09T08:51:02+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.6.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.6-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "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": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "uri", + "url" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + "source": "https://github.com/symfony/routing/tree/v6.4.34" }, "funding": [ { @@ -10282,33 +9110,46 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:30:57+00:00" + "time": "2026-02-24T17:34:50+00:00" }, { - "name": "symfony/stopwatch", - "version": "v6.4.8", + "name": "symfony/service-contracts", + "version": "v3.6.1", "source": { "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "63e069eb616049632cde9674c46957819454b8aa" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/63e069eb616049632cde9674c46957819454b8aa", - "reference": "63e069eb616049632cde9674c46957819454b8aa", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/service-contracts": "^2.5|^3" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" + "Symfony\\Contracts\\Service\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -10317,18 +9158,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a way to profile code", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.4.8" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" }, "funding": [ { @@ -10339,31 +9188,36 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2025-07-15T11:30:57+00:00" }, { "name": "symfony/string", - "version": "v6.4.30", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb" + "reference": "114ac57257d75df748eda23dd003878080b8e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/50590a057841fa6bf69d12eceffce3465b9e32cb", - "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb", + "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", + "reference": "114ac57257d75df748eda23dd003878080b8e688", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-grapheme": "~1.33", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, @@ -10371,10 +9225,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "symfony/emoji": "^7.1|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/intl": "^6.4|^7.0|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -10413,7 +9268,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.30" + "source": "https://github.com/symfony/string/tree/v7.4.8" }, "funding": [ { @@ -10433,20 +9288,20 @@ "type": "tidelift" } ], - "time": "2025-11-21T18:03:05+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/translation", - "version": "v6.4.19", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "3b9bf9f33997c064885a7bfc126c14b9daa0e00e" + "reference": "d07d117db41341511671b0a1a2be48f2772189ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/3b9bf9f33997c064885a7bfc126c14b9daa0e00e", - "reference": "3b9bf9f33997c064885a7bfc126c14b9daa0e00e", + "url": "https://api.github.com/repos/symfony/translation/zipball/d07d117db41341511671b0a1a2be48f2772189ce", + "reference": "d07d117db41341511671b0a1a2be48f2772189ce", "shasum": "" }, "require": { @@ -10512,7 +9367,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.19" + "source": "https://github.com/symfony/translation/tree/v6.4.34" }, "funding": [ { @@ -10523,12 +9378,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-02-13T10:18:43+00:00" + "time": "2026-02-16T20:44:03+00:00" }, { "name": "symfony/translation-contracts", @@ -10614,16 +9473,16 @@ }, { "name": "symfony/uid", - "version": "v6.4.13", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "18eb207f0436a993fffbdd811b5b8fa35fa5e007" + "reference": "6b973c385f00341b246f697d82dc01a09107acdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/18eb207f0436a993fffbdd811b5b8fa35fa5e007", - "reference": "18eb207f0436a993fffbdd811b5b8fa35fa5e007", + "url": "https://api.github.com/repos/symfony/uid/zipball/6b973c385f00341b246f697d82dc01a09107acdd", + "reference": "6b973c385f00341b246f697d82dc01a09107acdd", "shasum": "" }, "require": { @@ -10668,7 +9527,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v6.4.13" + "source": "https://github.com/symfony/uid/tree/v6.4.32" }, "funding": [ { @@ -10679,25 +9538,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2025-12-23T15:07:59+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.32", + "version": "v6.4.36", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "131fc9915e0343052af5ed5040401b481ca192aa" + "reference": "7c8ad9ce4faf6c8a99948e70ce02b601a0439782" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/131fc9915e0343052af5ed5040401b481ca192aa", - "reference": "131fc9915e0343052af5ed5040401b481ca192aa", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7c8ad9ce4faf6c8a99948e70ce02b601a0439782", + "reference": "7c8ad9ce4faf6c8a99948e70ce02b601a0439782", "shasum": "" }, "require": { @@ -10752,7 +9615,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.32" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.36" }, "funding": [ { @@ -10772,28 +9635,29 @@ "type": "tidelift" } ], - "time": "2026-01-01T13:34:06+00:00" + "time": "2026-03-30T15:36:00+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.1", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "2d08ca6b9cc704dce525615d1e6d1788734f36d9" + "reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/2d08ca6b9cc704dce525615d1e6d1788734f36d9", - "reference": "2d08ca6b9cc704dce525615d1e6d1788734f36d9", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/15776bb07a91b089037da89f8832fa41d5fa6ec6", + "reference": "15776bb07a91b089037da89f8832fa41d5fa6ec6", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=8.4" }, "require-dev": { - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/property-access": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -10831,7 +9695,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.1" + "source": "https://github.com/symfony/var-exporter/tree/v8.0.8" }, "funding": [ { @@ -10842,25 +9706,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-11-30T10:32:10+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.8", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "52903de178d542850f6f341ba92995d3d63e60c9" + "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9", - "reference": "52903de178d542850f6f341ba92995d3d63e60c9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7bca30dabed7900a08c5ad4f1d6483f881a64d0f", + "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f", "shasum": "" }, "require": { @@ -10903,7 +9771,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.8" + "source": "https://github.com/symfony/yaml/tree/v6.4.34" }, "funding": [ { @@ -10914,12 +9782,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2026-02-06T18:32:11+00:00" }, { "name": "theseer/tokenizer", @@ -10973,23 +9845,23 @@ }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d" + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41", + "reference": "f0292ccf0ec75843d65027214426b6b163b48b41", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "php": "^7.4 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.0 || ^7.0" + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { "phpstan/phpstan": "^2.0", @@ -11022,142 +9894,32 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0" - }, - "time": "2024-12-21T16:25:41+00:00" - }, - { - "name": "vimeo/psalm", - "version": "5.26.1", - "source": { - "type": "git", - "url": "https://github.com/vimeo/psalm.git", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", - "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", - "shasum": "" - }, - "require": { - "amphp/amp": "^2.4.2", - "amphp/byte-stream": "^1.5", - "composer-runtime-api": "^2", - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^2.0 || ^3.0", - "dnoegel/php-xdg-base-dir": "^0.1.1", - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-simplexml": "*", - "ext-tokenizer": "*", - "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", - "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", - "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", - "nikic/php-parser": "^4.17", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", - "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" - }, - "conflict": { - "nikic/php-parser": "4.17.0" - }, - "provide": { - "psalm/psalm": "self.version" - }, - "require-dev": { - "amphp/phpunit-util": "^2.0", - "bamarni/composer-bin-plugin": "^1.4", - "brianium/paratest": "^6.9", - "ext-curl": "*", - "mockery/mockery": "^1.5", - "nunomaduro/mock-final-classes": "^1.1", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpdoc-parser": "^1.6", - "phpunit/phpunit": "^9.6", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "ext-curl": "In order to send data to shepherd", - "ext-igbinary": "^2.0.5 is required, used to serialize caching data" - }, - "bin": [ - "psalm", - "psalm-language-server", - "psalm-plugin", - "psalm-refactor", - "psalter" - ], - "type": "project", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", - "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psalm\\": "src/Psalm/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthew Brown" - } - ], - "description": "A static analysis tool for finding errors in PHP applications", - "keywords": [ - "code", - "inspection", - "php", - "static analysis" - ], - "support": { - "docs": "https://psalm.dev/docs", - "issues": "https://github.com/vimeo/psalm/issues", - "source": "https://github.com/vimeo/psalm" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.4.0" }, - "time": "2024-09-08T18:53:08+00:00" + "time": "2025-12-02T11:56:42+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.6.1", + "version": "v5.6.3", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2" + "reference": "955e7815d677a3eaa7075231212f2110983adecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", + "reference": "955e7815d677a3eaa7075231212f2110983adecc", "shasum": "" }, "require": { "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.3", + "graham-campbell/result-type": "^1.1.4", "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" + "phpoption/phpoption": "^1.9.5", + "symfony/polyfill-ctype": "^1.26", + "symfony/polyfill-mbstring": "^1.26", + "symfony/polyfill-php80": "^1.26" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -11206,7 +9968,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" }, "funding": [ { @@ -11218,7 +9980,7 @@ "type": "tidelift" } ], - "time": "2024-07-20T21:52:34+00:00" + "time": "2025-12-27T19:49:13+00:00" }, { "name": "voku/portable-ascii", @@ -11296,28 +10058,28 @@ }, { "name": "webmozart/assert", - "version": "1.11.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", "shasum": "" }, "require": { "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", "php": "^7.2 || ^8.0" }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" }, "type": "library", "extra": { @@ -11348,216 +10110,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - }, - { - "name": "zbateson/mail-mime-parser", - "version": "2.4.1", - "source": { - "type": "git", - "url": "https://github.com/zbateson/mail-mime-parser.git", - "reference": "ff49e02f6489b38f7cc3d1bd3971adc0f872569c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/ff49e02f6489b38f7cc3d1bd3971adc0f872569c", - "reference": "ff49e02f6489b38f7cc3d1bd3971adc0f872569c", - "shasum": "" - }, - "require": { - "guzzlehttp/psr7": "^1.7.0|^2.0", - "php": ">=7.1", - "pimple/pimple": "^3.0", - "zbateson/mb-wrapper": "^1.0.1", - "zbateson/stream-decorators": "^1.0.6" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "*", - "mikey179/vfsstream": "^1.6.0", - "phpstan/phpstan": "*", - "phpunit/phpunit": "<10" - }, - "suggest": { - "ext-iconv": "For best support/performance", - "ext-mbstring": "For best support/performance" - }, - "type": "library", - "autoload": { - "psr-4": { - "ZBateson\\MailMimeParser\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Zaahid Bateson" - }, - { - "name": "Contributors", - "homepage": "https://github.com/zbateson/mail-mime-parser/graphs/contributors" - } - ], - "description": "MIME email message parser", - "homepage": "https://mail-mime-parser.org", - "keywords": [ - "MimeMailParser", - "email", - "mail", - "mailparse", - "mime", - "mimeparse", - "parser", - "php-imap" - ], - "support": { - "docs": "https://mail-mime-parser.org/#usage-guide", - "issues": "https://github.com/zbateson/mail-mime-parser/issues", - "source": "https://github.com/zbateson/mail-mime-parser" - }, - "funding": [ - { - "url": "https://github.com/zbateson", - "type": "github" - } - ], - "time": "2024-04-28T00:58:54+00:00" - }, - { - "name": "zbateson/mb-wrapper", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/zbateson/mb-wrapper.git", - "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/09a8b77eb94af3823a9a6623dcc94f8d988da67f", - "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f", - "shasum": "" - }, - "require": { - "php": ">=7.1", - "symfony/polyfill-iconv": "^1.9", - "symfony/polyfill-mbstring": "^1.9" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "*", - "phpstan/phpstan": "*", - "phpunit/phpunit": "<10.0" - }, - "suggest": { - "ext-iconv": "For best support/performance", - "ext-mbstring": "For best support/performance" - }, - "type": "library", - "autoload": { - "psr-4": { - "ZBateson\\MbWrapper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Zaahid Bateson" - } - ], - "description": "Wrapper for mbstring with fallback to iconv for encoding conversion and string manipulation", - "keywords": [ - "charset", - "encoding", - "http", - "iconv", - "mail", - "mb", - "mb_convert_encoding", - "mbstring", - "mime", - "multibyte", - "string" - ], - "support": { - "issues": "https://github.com/zbateson/mb-wrapper/issues", - "source": "https://github.com/zbateson/mb-wrapper/tree/1.2.1" - }, - "funding": [ - { - "url": "https://github.com/zbateson", - "type": "github" - } - ], - "time": "2024-03-18T04:31:04+00:00" - }, - { - "name": "zbateson/stream-decorators", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/zbateson/stream-decorators.git", - "reference": "783b034024fda8eafa19675fb2552f8654d3a3e9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/783b034024fda8eafa19675fb2552f8654d3a3e9", - "reference": "783b034024fda8eafa19675fb2552f8654d3a3e9", - "shasum": "" - }, - "require": { - "guzzlehttp/psr7": "^1.9 | ^2.0", - "php": ">=7.2", - "zbateson/mb-wrapper": "^1.0.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "*", - "phpstan/phpstan": "*", - "phpunit/phpunit": "<10.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "ZBateson\\StreamDecorators\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Zaahid Bateson" - } - ], - "description": "PHP psr7 stream decorators for mime message part streams", - "keywords": [ - "base64", - "charset", - "decorators", - "mail", - "mime", - "psr7", - "quoted-printable", - "stream", - "uuencode" - ], - "support": { - "issues": "https://github.com/zbateson/stream-decorators/issues", - "source": "https://github.com/zbateson/stream-decorators/tree/1.2.1" + "source": "https://github.com/webmozarts/assert/tree/1.12.1" }, - "funding": [ - { - "url": "https://github.com/zbateson", - "type": "github" - } - ], - "time": "2023-05-30T22:51:52+00:00" + "time": "2025-10-29T15:56:20+00:00" } ], "aliases": [], diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index af1211c9e..000000000 --- a/psalm.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - diff --git a/src/Api/Api.php b/src/Api/Api.php index 31ef7ff14..64525cb3e 100644 --- a/src/Api/Api.php +++ b/src/Api/Api.php @@ -116,7 +116,7 @@ public function sendRequest(string $controller, string $action, array $input): a 'status' => 'error', 'date' => date('c'), 'errors' => [ - $exception + $exception->getMessage() ] ]; } diff --git a/src/Api/Capabilities/CanAddAttachment.php b/src/Api/Capabilities/CanAddAttachment.php index c5ffbbc5a..0fd604547 100644 --- a/src/Api/Capabilities/CanAddAttachment.php +++ b/src/Api/Capabilities/CanAddAttachment.php @@ -12,8 +12,8 @@ public function attachmentAdd(array $input): array { return $this ->sendRequest( - self::$name, - 'attachment_add', + 'attachment', + 'add', $input ); } diff --git a/src/Api/Capabilities/CanAddLine.php b/src/Api/Capabilities/CanAddLine.php index 201613a54..a55de6c82 100644 --- a/src/Api/Capabilities/CanAddLine.php +++ b/src/Api/Capabilities/CanAddLine.php @@ -12,8 +12,8 @@ public function lineAdd(array $input): array { return $this ->sendRequest( - self::$name, - mb_strtolower(self::$name) . 'line_add', + mb_strtolower(self::$name) . 'line', + 'add', $input ); } diff --git a/src/Api/Capabilities/CanDeleteAttachment.php b/src/Api/Capabilities/CanDeleteAttachment.php index 4c0059b33..dd820d5f3 100644 --- a/src/Api/Capabilities/CanDeleteAttachment.php +++ b/src/Api/Capabilities/CanDeleteAttachment.php @@ -12,8 +12,8 @@ public function attachmentDelete(array $input): array { return $this ->sendRequest( - self::$name, - 'attachment_delete', + 'attachment', + 'delete', $input ); } diff --git a/src/Api/Capabilities/CanDeleteLine.php b/src/Api/Capabilities/CanDeleteLine.php index c7cd9a38d..7d60a6856 100644 --- a/src/Api/Capabilities/CanDeleteLine.php +++ b/src/Api/Capabilities/CanDeleteLine.php @@ -12,8 +12,8 @@ public function lineDelete(array $input): array { return $this ->sendRequest( - self::$name, - mb_strtolower(self::$name) . 'line_delete', + mb_strtolower(self::$name) . 'line', + 'delete', $input ); } diff --git a/src/Api/Capabilities/CanDownloadAttachment.php b/src/Api/Capabilities/CanDownloadAttachment.php index 656f7dff0..b4f78b8c4 100644 --- a/src/Api/Capabilities/CanDownloadAttachment.php +++ b/src/Api/Capabilities/CanDownloadAttachment.php @@ -12,8 +12,8 @@ public function attachmentDownload(array $input): array { return $this ->sendRequest( - self::$name, - 'attachment_download', + 'attachment', + 'download', $input ); } diff --git a/src/Api/Capabilities/CanEmailAccountInfo.php b/src/Api/Capabilities/CanEmailAccountInfo.php new file mode 100644 index 000000000..ad12d2636 --- /dev/null +++ b/src/Api/Capabilities/CanEmailAccountInfo.php @@ -0,0 +1,20 @@ + $input + * @return array + */ + public function emailAccountData(array $input): array + { + return $this + ->sendRequest( + self::$name, + 'sendaccountinfobyemail', + $input + ); + } +} diff --git a/src/Api/Capabilities/CanPaymentProcessPause.php b/src/Api/Capabilities/CanPaymentProcessPause.php index 058d30e79..797d26fe2 100644 --- a/src/Api/Capabilities/CanPaymentProcessPause.php +++ b/src/Api/Capabilities/CanPaymentProcessPause.php @@ -13,7 +13,7 @@ public function paymentProcessPause(array $input): array return $this ->sendRequest( self::$name, - 'payment_process_pause', + 'paymentprocesspause', $input ); } diff --git a/src/Api/Capabilities/CanPaymentProcessReactivate.php b/src/Api/Capabilities/CanPaymentProcessReactivate.php index 1f5efeb6a..98586a504 100644 --- a/src/Api/Capabilities/CanPaymentProcessReactivate.php +++ b/src/Api/Capabilities/CanPaymentProcessReactivate.php @@ -13,7 +13,7 @@ public function paymentProcessReactivate(array $input): array return $this ->sendRequest( self::$name, - 'payment_process_reactivate', + 'paymentprocessreactivate', $input ); } diff --git a/src/Api/Capabilities/CanResendApproverEmail.php b/src/Api/Capabilities/CanResendApproverEmail.php index 5ffd4cc4a..882576994 100644 --- a/src/Api/Capabilities/CanResendApproverEmail.php +++ b/src/Api/Capabilities/CanResendApproverEmail.php @@ -13,7 +13,7 @@ public function resendApproverEmail(array $input): array return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + 'resendapprovermail', $input ); } diff --git a/src/Api/Controllers/Hosting.php b/src/Api/Controllers/Hosting.php index 3072c0405..2ce6f8311 100644 --- a/src/Api/Controllers/Hosting.php +++ b/src/Api/Controllers/Hosting.php @@ -7,7 +7,7 @@ use Hyperized\Hostfact\Api\Capabilities\CanCreate; use Hyperized\Hostfact\Api\Capabilities\CanDelete; use Hyperized\Hostfact\Api\Capabilities\CanEdit; -use Hyperized\Hostfact\Api\Capabilities\CanEmailAccountData; +use Hyperized\Hostfact\Api\Capabilities\CanEmailAccountInfo; use Hyperized\Hostfact\Api\Capabilities\CanGetDomainList; use Hyperized\Hostfact\Api\Capabilities\CanList; use Hyperized\Hostfact\Api\Capabilities\CanRemoveFromServer; @@ -33,7 +33,7 @@ class Hosting extends Api implements HostingInterface use CanCreate; use CanRemoveFromServer; use CanGetDomainList; - use CanEmailAccountData; + use CanEmailAccountInfo; use CanUpDowngrade; protected static string $name = 'hosting'; From 63c95100db102267b4ff1217415ff525b4b71669 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 01:50:15 +0200 Subject: [PATCH 02/30] Update PHP version requirements to supported versions only Drop EOL PHP 8.1, require ^8.2. Test matrix now covers 8.2, 8.3, 8.4, 8.5 per php.net/supported-versions. --- .github/workflows/main.yml | 4 +++- composer.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d3ffcb50b..a582f6a5c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,8 +10,10 @@ jobs: fail-fast: false matrix: php: - - 8.1 - 8.2 + - 8.3 + - 8.4 + - 8.5 dependency-version: # - prefer-lowest - prefer-stable diff --git a/composer.json b/composer.json index 5e84a4adb..41c428a78 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "guzzlehttp/guzzle": "^7.5", "hyperized/value-objects": "^0.3.0", "thecodingmachine/safe": "^2.4" From b293a415b9e7ea70e118251a9543af429b4cc40d Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 03:20:21 +0200 Subject: [PATCH 03/30] Update all dependencies to latest major versions Production: - hyperized/value-objects: ^0.3.0 -> ^1.0.0 (update ByteArrayInterface namespace) - thecodingmachine/safe: ^2.4 -> ^3.4 Dev: - phpunit/phpunit: ^9.5 -> ^13.0 (update phpunit.xml.dist to v13 schema) - orchestra/testbench: ^7.15||^8.0 -> ^11.0 - phpstan/phpstan: ^1.9 -> ^2.0 - infection/infection: ^0.26.16||^0.27.0 -> ^0.32 --- composer.json | 12 +- composer.lock | 3300 +++++++++++++++--------- phpunit.xml.dist | 10 +- src/Http/HttpClient.php | 2 +- src/Interfaces/HttpClientInterface.php | 2 +- 5 files changed, 2066 insertions(+), 1260 deletions(-) diff --git a/composer.json b/composer.json index 41c428a78..9ac31da94 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,17 @@ "require": { "php": "^8.2", "guzzlehttp/guzzle": "^7.5", - "hyperized/value-objects": "^0.3.0", - "thecodingmachine/safe": "^2.4" + "hyperized/value-objects": "^1.0.0", + "thecodingmachine/safe": "^3.4" }, "require-dev": { - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^13.0", "phpmd/phpmd": "^2.13", - "orchestra/testbench": "^7.15 || ^8.0", - "phpstan/phpstan": "^1.9", + "orchestra/testbench": "^11.0", + "phpstan/phpstan": "^2.0", "squizlabs/php_codesniffer": "^3.7 || ^4.0", "povils/phpmnd": "^3.0", - "infection/infection": "^0.26.16 || ^0.27.0" + "infection/infection": "^0.32" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 9aab1e5dd..39df769ba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "df3a354a6f6eef895b7ea067ecaae8c4", + "content-hash": "bed4754e3bc0e593537b5ba01eed97d7", "packages": [ { "name": "guzzlehttp/guzzle", @@ -334,26 +334,25 @@ }, { "name": "hyperized/value-objects", - "version": "v0.3.0", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/hyperized/value-objects.git", - "reference": "4a4a4c938a76bede63bee34a6b073f261f40af4c" + "reference": "481fcde24adba424a7b9c8f6242f37075ea75c67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperized/value-objects/zipball/4a4a4c938a76bede63bee34a6b073f261f40af4c", - "reference": "4a4a4c938a76bede63bee34a6b073f261f40af4c", + "url": "https://api.github.com/repos/hyperized/value-objects/zipball/481fcde24adba424a7b9c8f6242f37075ea75c67", + "reference": "481fcde24adba424a7b9c8f6242f37075ea75c67", "shasum": "" }, "require": { - "ext-json": "*", - "php": "^7.4|^8.0" + "php": "^8.3" }, "require-dev": { - "phpstan/phpstan": "^1.2", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.13" + "infection/infection": "^0.32.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^12.5.17 || ^13.1" }, "type": "library", "autoload": { @@ -374,9 +373,9 @@ "description": "A basic value objects collection", "support": { "issues": "https://github.com/hyperized/value-objects/issues", - "source": "https://github.com/hyperized/value-objects/tree/v0.3.0" + "source": "https://github.com/hyperized/value-objects/tree/v1.0.0" }, - "time": "2021-11-24T20:10:20+00:00" + "time": "2026-04-11T01:12:35+00:00" }, { "name": "psr/http-client", @@ -651,46 +650,31 @@ }, { "name": "thecodingmachine/safe", - "version": "v2.5.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/thecodingmachine/safe.git", - "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0" + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/3115ecd6b4391662b4931daac4eba6b07a2ac1f0", - "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/705683a25bacf0d4860c7dea4d7947bfd09eea19", + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19", "shasum": "" }, "require": { - "php": "^8.0" + "php": "^8.1" }, "require-dev": { - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "^3.2", - "thecodingmachine/phpstan-strict-rules": "^1.0" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10", + "squizlabs/php_codesniffer": "^3.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, "autoload": { "files": [ - "deprecated/apc.php", - "deprecated/array.php", - "deprecated/datetime.php", - "deprecated/libevent.php", - "deprecated/misc.php", - "deprecated/password.php", - "deprecated/mssql.php", - "deprecated/stats.php", - "deprecated/strings.php", "lib/special_cases.php", - "deprecated/mysqli.php", "generated/apache.php", "generated/apcu.php", "generated/array.php", @@ -730,6 +714,7 @@ "generated/mbstring.php", "generated/misc.php", "generated/mysql.php", + "generated/mysqli.php", "generated/network.php", "generated/oci8.php", "generated/opcache.php", @@ -742,6 +727,7 @@ "generated/ps.php", "generated/pspell.php", "generated/readline.php", + "generated/rnp.php", "generated/rpminfo.php", "generated/rrd.php", "generated/sem.php", @@ -773,7 +759,6 @@ "lib/DateTime.php", "lib/DateTimeImmutable.php", "lib/Exceptions/", - "deprecated/Exceptions/", "generated/Exceptions/" ] }, @@ -784,33 +769,51 @@ "description": "PHP core functions that throw exceptions instead of returning FALSE on error", "support": { "issues": "https://github.com/thecodingmachine/safe/issues", - "source": "https://github.com/thecodingmachine/safe/tree/v2.5.0" + "source": "https://github.com/thecodingmachine/safe/tree/v3.4.0" }, - "time": "2023-04-05T11:54:14+00:00" + "funding": [ + { + "url": "https://github.com/OskarStark", + "type": "github" + }, + { + "url": "https://github.com/shish", + "type": "github" + }, + { + "url": "https://github.com/silasjoisten", + "type": "github" + }, + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2026-02-04T18:08:13+00:00" } ], "packages-dev": [ { "name": "brick/math", - "version": "0.12.3", + "version": "0.14.8", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", - "reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", + "url": "https://api.github.com/repos/brick/math/zipball/63422359a44b7f06cae63c3b429b59e8efcc0629", + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.2" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "6.8.8" + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" }, "type": "library", "autoload": { @@ -840,7 +843,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.3" + "source": "https://github.com/brick/math/tree/0.14.8" }, "funding": [ { @@ -848,30 +851,30 @@ "type": "github" } ], - "time": "2025-02-28T13:11:00+00:00" + "time": "2026-02-10T14:33:43+00:00" }, { "name": "carbonphp/carbon-doctrine-types", - "version": "2.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb" + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", - "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "conflict": { - "doctrine/dbal": "<3.7.0 || >=4.0.0" + "doctrine/dbal": "<4.0.0 || >=5.0.0" }, "require-dev": { - "doctrine/dbal": "^3.7.0", + "doctrine/dbal": "^4.0.0", "nesbot/carbon": "^2.71.0 || ^3.0.0", "phpunit/phpunit": "^10.3" }, @@ -901,7 +904,7 @@ ], "support": { "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0" + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" }, "funding": [ { @@ -917,37 +920,34 @@ "type": "tidelift" } ], - "time": "2023-12-11T17:09:12+00:00" + "time": "2024-02-09T16:56:22+00:00" }, { "name": "colinodell/json5", - "version": "v2.3.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/colinodell/json5.git", - "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710" + "reference": "5724d21bc5c910c2560af1b8915f0cc0163579c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinodell/json5/zipball/15b063f8cb5e6deb15f0cd39123264ec0d19c710", - "reference": "15b063f8cb5e6deb15f0cd39123264ec0d19c710", + "url": "https://api.github.com/repos/colinodell/json5/zipball/5724d21bc5c910c2560af1b8915f0cc0163579c8", + "reference": "5724d21bc5c910c2560af1b8915f0cc0163579c8", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "php": "^7.1.3|^8.0" - }, - "conflict": { - "scrutinizer/ocular": "1.7.*" + "php": "^8.0" }, "require-dev": { - "mikehaertl/php-shellcommand": "^1.2.5", - "phpstan/phpstan": "^1.4", - "scrutinizer/ocular": "^1.6", - "squizlabs/php_codesniffer": "^2.3 || ^3.0", - "symfony/finder": "^4.4|^5.4|^6.0", - "symfony/phpunit-bridge": "^5.4|^6.0" + "mikehaertl/php-shellcommand": "^1.7.0", + "phpstan/phpstan": "^1.10.57", + "scrutinizer/ocular": "^1.9", + "squizlabs/php_codesniffer": "^3.8.1", + "symfony/finder": "^6.0|^7.0", + "symfony/phpunit-bridge": "^7.0.3" }, "bin": [ "bin/json5" @@ -955,7 +955,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -988,7 +988,7 @@ ], "support": { "issues": "https://github.com/colinodell/json5/issues", - "source": "https://github.com/colinodell/json5/tree/v2.3.0" + "source": "https://github.com/colinodell/json5/tree/v3.0.0" }, "funding": [ { @@ -1008,7 +1008,7 @@ "type": "patreon" } ], - "time": "2022-12-27T16:44:40+00:00" + "time": "2024-02-09T13:06:12+00:00" }, { "name": "composer/pcre", @@ -1397,75 +1397,6 @@ ], "time": "2025-08-10T19:31:58+00:00" }, - { - "name": "doctrine/instantiator", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", - "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", - "shasum": "" - }, - "require": { - "php": "^8.4" - }, - "require-dev": { - "doctrine/coding-standard": "^14", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^10.5.58" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.1.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2026-01-05T06:47:08+00:00" - }, { "name": "doctrine/lexer", "version": "3.0.1", @@ -2318,66 +2249,71 @@ }, { "name": "infection/infection", - "version": "0.27.11", + "version": "0.32.6", "source": { "type": "git", "url": "https://github.com/infection/infection.git", - "reference": "6d55979c457eef2a5d0d80446c67ca533f201961" + "reference": "4ed769947eaf2ecf42203027301bad2bedf037e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/infection/infection/zipball/6d55979c457eef2a5d0d80446c67ca533f201961", - "reference": "6d55979c457eef2a5d0d80446c67ca533f201961", + "url": "https://api.github.com/repos/infection/infection/zipball/4ed769947eaf2ecf42203027301bad2bedf037e5", + "reference": "4ed769947eaf2ecf42203027301bad2bedf037e5", "shasum": "" }, "require": { - "colinodell/json5": "^2.2", + "colinodell/json5": "^3.0", "composer-runtime-api": "^2.0", - "composer/xdebug-handler": "^2.0 || ^3.0", + "composer/xdebug-handler": "^3.0", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", - "fidry/cpu-core-counter": "^0.4.0 || ^0.5.0 || ^1.0", + "fidry/cpu-core-counter": "^1.0", "infection/abstract-testframework-adapter": "^0.5.0", "infection/extension-installer": "^0.1.0", "infection/include-interceptor": "^0.2.5", - "justinrainbow/json-schema": "^5.2.10", - "nikic/php-parser": "^4.15.1", + "infection/mutator": "^0.4", + "justinrainbow/json-schema": "^6.0", + "nikic/php-parser": "^5.6.2", "ondram/ci-detector": "^4.1.0", - "php": "^8.1", - "sanmai/later": "^0.1.1", - "sanmai/pipeline": "^5.1 || ^6", - "sebastian/diff": "^3.0.2 || ^4.0 || ^5.0 || ^6.0", - "symfony/console": "^5.4 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/finder": "^5.4 || ^6.0 || ^7.0", - "symfony/process": "^5.4 || ^6.0 || ^7.0", - "thecodingmachine/safe": "^2.1.2", - "webmozart/assert": "^1.11" + "php": "^8.2", + "psr/log": "^2.0 || ^3.0", + "sanmai/di-container": "^0.1.12", + "sanmai/duoclock": "^0.1.0", + "sanmai/later": "^0.1.7", + "sanmai/pipeline": "^7.2", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0", + "symfony/console": "^6.4 || ^7.0 || ^8.0", + "symfony/filesystem": "^6.4 || ^7.0 || ^8.0", + "symfony/finder": "^6.4 || ^7.0 || ^8.0", + "symfony/polyfill-php85": "^1.33", + "symfony/process": "^6.4 || ^7.0 || ^8.0", + "thecodingmachine/safe": "^v3.0", + "webmozart/assert": "^1.11 || ^2.0" }, "conflict": { "antecedent/patchwork": "<2.1.25", - "dg/bypass-finals": "<1.4.1", - "phpunit/php-code-coverage": ">9,<9.1.4 || >9.2.17,<9.2.21" + "dg/bypass-finals": "<1.4.1" }, "require-dev": { - "brianium/paratest": "^6.11", "ext-simplexml": "*", "fidry/makefile": "^1.0", - "helmich/phpunit-json-assert": "^3.0", - "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.1.0", - "phpstan/phpstan": "^1.10.15", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.1.0", - "phpstan/phpstan-webmozart-assert": "^1.0.2", - "phpunit/phpunit": "^9.6", - "rector/rector": "^0.16.0", - "sidz/phpstan-rules": "^0.4.0", - "symfony/yaml": "^5.4 || ^6.0 || ^7.0", - "thecodingmachine/phpstan-safe-rule": "^1.2.0" + "fig/log-test": "^1.2", + "phpbench/phpbench": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpstan/phpstan-webmozart-assert": "^2.0", + "phpunit/phpunit": "^11.5.27", + "rector/rector": "^2.2.4", + "shipmonk/dead-code-detector": "^0.14.0", + "shipmonk/name-collision-detector": "^2.1", + "sidz/phpstan-rules": "^0.5.1", + "symfony/yaml": "^6.4 || ^7.0 || ^8.0", + "thecodingmachine/phpstan-safe-rule": "^1.4", + "webmozarts/strict-phpunit": "^7.15" }, "bin": [ "bin/infection" @@ -2433,7 +2369,60 @@ ], "support": { "issues": "https://github.com/infection/infection/issues", - "source": "https://github.com/infection/infection/tree/0.27.11" + "source": "https://github.com/infection/infection/tree/0.32.6" + }, + "funding": [ + { + "url": "https://github.com/infection", + "type": "github" + }, + { + "url": "https://opencollective.com/infection", + "type": "open_collective" + } + ], + "time": "2026-02-26T14:34:26+00:00" + }, + { + "name": "infection/mutator", + "version": "0.4.1", + "source": { + "type": "git", + "url": "https://github.com/infection/mutator.git", + "reference": "3c976d721b02b32f851ee4e15d553ef1e9186d1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/infection/mutator/zipball/3c976d721b02b32f851ee4e15d553ef1e9186d1d", + "reference": "3c976d721b02b32f851ee4e15d553ef1e9186d1d", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Infection\\Mutator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Maks Rafalko", + "email": "maks.rafalko@gmail.com" + } + ], + "description": "Mutator interface to implement custom mutators (mutation operators) for Infection", + "support": { + "issues": "https://github.com/infection/mutator/issues", + "source": "https://github.com/infection/mutator/tree/0.4.1" }, "funding": [ { @@ -2445,34 +2434,44 @@ "type": "open_collective" } ], - "time": "2024-03-20T07:48:57+00:00" + "time": "2025-04-29T08:19:52+00:00" }, { "name": "justinrainbow/json-schema", - "version": "5.3.3", + "version": "6.8.0", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e" + "reference": "89ac92bcfe5d0a8a4433c7b89d394553ae7250cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/a0b7c13588b102d7d6536823e96d1c88d3dba85e", - "reference": "a0b7c13588b102d7d6536823e96d1c88d3dba85e", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/89ac92bcfe5d0a8a4433c7b89d394553ae7250cc", + "reference": "89ac92bcfe5d0a8a4433c7b89d394553ae7250cc", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-json": "*", + "marc-mabe/php-enum": "^4.4", + "php": "^7.2 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", - "json-schema/json-schema-test-suite": "1.2.0", - "phpunit/phpunit": "^4.8.35" + "friendsofphp/php-cs-fixer": "3.3.0", + "json-schema/json-schema-test-suite": "^23.2", + "marc-mabe/php-enum-phpstan": "^2.0", + "phpspec/prophecy": "^1.19", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "^8.5" }, "bin": [ "bin/validate-json" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -2501,37 +2500,37 @@ } ], "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", + "homepage": "https://github.com/jsonrainbow/json-schema", "keywords": [ "json", "schema" ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.3" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.8.0" }, - "time": "2026-03-24T18:47:53+00:00" + "time": "2026-04-02T12:43:11+00:00" }, { "name": "laravel/framework", - "version": "10.50.2", + "version": "v13.4.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc" + "reference": "912de244f88a69742b76e8a2807f6765947776da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/3ff39b7a9b83e633383ec9b019827ed54b6d38bc", - "reference": "3ff39b7a9b83e633383ec9b019827ed54b6d38bc", + "url": "https://api.github.com/repos/laravel/framework/zipball/912de244f88a69742b76e8a2807f6765947776da", + "reference": "912de244f88a69742b76e8a2807f6765947776da", "shasum": "" }, "require": { - "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17", "composer-runtime-api": "^2.2", "doctrine/inflector": "^2.0.5", - "dragonmantank/cron-expression": "^3.3.2", - "egulias/email-validator": "^3.2.1|^4.0", + "dragonmantank/cron-expression": "^3.4", + "egulias/email-validator": "^4.0", "ext-ctype": "*", "ext-filter": "*", "ext-hash": "*", @@ -2539,45 +2538,48 @@ "ext-openssl": "*", "ext-session": "*", "ext-tokenizer": "*", - "fruitcake/php-cors": "^1.2", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/promises": "^2.0.3", "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.1.9", - "laravel/serializable-closure": "^1.3", - "league/commonmark": "^2.2.1", - "league/flysystem": "^3.8.0", + "laravel/prompts": "^0.3.0", + "laravel/serializable-closure": "^2.0.10", + "league/commonmark": "^2.8.1", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "league/uri": "^7.5.1", "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.67", - "nunomaduro/termwind": "^1.13", - "php": "^8.1", - "psr/container": "^1.1.1|^2.0.1", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", + "nesbot/carbon": "^3.8.4", + "nunomaduro/termwind": "^2.0", + "php": "^8.3", + "psr/container": "^1.1.1 || ^2.0.1", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^4.7", - "symfony/console": "^6.2", - "symfony/error-handler": "^6.2", - "symfony/finder": "^6.2", - "symfony/http-foundation": "^6.4", - "symfony/http-kernel": "^6.2", - "symfony/mailer": "^6.2", - "symfony/mime": "^6.2", - "symfony/process": "^6.2", - "symfony/routing": "^6.2", - "symfony/uid": "^6.2", - "symfony/var-dumper": "^6.2", + "symfony/console": "^7.4.0 || ^8.0.0", + "symfony/error-handler": "^7.4.0 || ^8.0.0", + "symfony/finder": "^7.4.0 || ^8.0.0", + "symfony/http-foundation": "^7.4.0 || ^8.0.0", + "symfony/http-kernel": "^7.4.0 || ^8.0.0", + "symfony/mailer": "^7.4.0 || ^8.0.0", + "symfony/mime": "^7.4.0 || ^8.0.0", + "symfony/polyfill-php84": "^1.33", + "symfony/polyfill-php85": "^1.33", + "symfony/process": "^7.4.5 || ^8.0.5", + "symfony/routing": "^7.4.0 || ^8.0.0", + "symfony/uid": "^7.4.0 || ^8.0.0", + "symfony/var-dumper": "^7.4.0 || ^8.0.0", "tijsverkoyen/css-to-inline-styles": "^2.2.5", - "vlucas/phpdotenv": "^5.4.1", - "voku/portable-ascii": "^2.0" + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" }, "conflict": { - "carbonphp/carbon-doctrine-types": ">=3.0", - "doctrine/dbal": ">=4.0", - "mockery/mockery": "1.6.8", - "phpunit/phpunit": ">=11.0.0", "tightenco/collect": "<5.5.33" }, "provide": { - "psr/container-implementation": "1.1|2.0", - "psr/simple-cache-implementation": "1.0|2.0|3.0" + "psr/container-implementation": "1.1 || 2.0", + "psr/log-implementation": "1.0 || 2.0 || 3.0", + "psr/simple-cache-implementation": "1.0 || 2.0 || 3.0" }, "replace": { "illuminate/auth": "self.version", @@ -2585,6 +2587,7 @@ "illuminate/bus": "self.version", "illuminate/cache": "self.version", "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", "illuminate/conditionable": "self.version", "illuminate/config": "self.version", "illuminate/console": "self.version", @@ -2597,6 +2600,7 @@ "illuminate/filesystem": "self.version", "illuminate/hashing": "self.version", "illuminate/http": "self.version", + "illuminate/json-schema": "self.version", "illuminate/log": "self.version", "illuminate/macroable": "self.version", "illuminate/mail": "self.version", @@ -2606,42 +2610,47 @@ "illuminate/process": "self.version", "illuminate/queue": "self.version", "illuminate/redis": "self.version", + "illuminate/reflection": "self.version", "illuminate/routing": "self.version", "illuminate/session": "self.version", "illuminate/support": "self.version", "illuminate/testing": "self.version", "illuminate/translation": "self.version", "illuminate/validation": "self.version", - "illuminate/view": "self.version" + "illuminate/view": "self.version", + "spatie/once": "*" }, "require-dev": { "ably/ably-php": "^1.0", - "aws/aws-sdk-php": "^3.235.5", - "doctrine/dbal": "^3.5.1", + "aws/aws-sdk-php": "^3.322.9", "ext-gmp": "*", - "fakerphp/faker": "^1.21", - "guzzlehttp/guzzle": "^7.5", - "league/flysystem-aws-s3-v3": "^3.0", - "league/flysystem-ftp": "^3.0", - "league/flysystem-path-prefixing": "^3.3", - "league/flysystem-read-only": "^3.3", - "league/flysystem-sftp-v3": "^3.0", - "mockery/mockery": "^1.5.1", - "nyholm/psr7": "^1.2", - "orchestra/testbench-core": "^8.23.4", - "pda/pheanstalk": "^4.0", - "phpstan/phpstan": "~1.11.11", - "phpunit/phpunit": "^10.0.7", - "predis/predis": "^2.0.2", - "symfony/cache": "^6.2", - "symfony/http-client": "^6.2.4", - "symfony/psr-http-message-bridge": "^2.0" + "fakerphp/faker": "^1.24", + "guzzlehttp/psr7": "^2.4", + "laravel/pint": "^1.18", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "opis/json-schema": "^2.4.1", + "orchestra/testbench-core": "^11.0.0", + "pda/pheanstalk": "^7.0.0 || ^8.0.0", + "php-http/discovery": "^1.15", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11.5.50 || ^12.5.8 || ^13.0.3", + "predis/predis": "^2.3 || ^3.0", + "rector/rector": "^2.3", + "resend/resend-php": "^1.0", + "symfony/cache": "^7.4.0 || ^8.0.0", + "symfony/http-client": "^7.4.0 || ^8.0.0", + "symfony/psr-http-message-bridge": "^7.4.0 || ^8.0.0", + "symfony/translation": "^7.4.0 || ^8.0.0" }, "suggest": { "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", - "brianium/paratest": "Required to run tests in parallel (^6.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", + "brianium/paratest": "Required to run tests in parallel (^7.0 || ^8.0).", "ext-apcu": "Required to use the APC cache driver.", "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", @@ -2650,34 +2659,34 @@ "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", "ext-pdo": "Required to use all database features.", "ext-posix": "Required to use all features of the queue worker.", - "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0 || ^5.0 || ^6.0).", + "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.5).", "laravel/tinker": "Required to use the tinker console command (^2.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", - "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", - "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", - "league/flysystem-read-only": "Required to use read-only disks (^3.3)", - "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", - "mockery/mockery": "Required to use mocking (^1.5.1).", - "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", - "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8|^10.0.7).", - "predis/predis": "Required to use the predis connector (^2.0.2).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "mockery/mockery": "Required to use mocking (^1.6).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^7.0 || ^8.0).", + "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", + "phpunit/phpunit": "Required to use assertions and run tests (^11.5.50 || ^12.5.8 || ^13.0.3).", + "predis/predis": "Required to use the predis connector (^2.3 || ^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^6.2).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.2).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.2).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.2).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0 || ^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0 || ^1.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.4 || ^8.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.4 || ^8.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.4 || ^8.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.4 || ^8.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.4 || ^8.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.4 || ^8.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "10.x-dev" + "dev-master": "13.0.x-dev" } }, "autoload": { @@ -2687,6 +2696,9 @@ "src/Illuminate/Events/functions.php", "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", + "src/Illuminate/Reflection/helpers.php", + "src/Illuminate/Support/functions.php", "src/Illuminate/Support/helpers.php" ], "psr-4": { @@ -2694,7 +2706,8 @@ "Illuminate\\Support\\": [ "src/Illuminate/Macroable/", "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" + "src/Illuminate/Conditionable/", + "src/Illuminate/Reflection/" ] } }, @@ -2718,37 +2731,118 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-02-15T14:12:07+00:00" + "time": "2026-04-07T13:38:26+00:00" + }, + { + "name": "laravel/pail", + "version": "v1.2.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/pail.git", + "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pail/zipball/aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/console": "^10.24|^11.0|^12.0|^13.0", + "illuminate/contracts": "^10.24|^11.0|^12.0|^13.0", + "illuminate/log": "^10.24|^11.0|^12.0|^13.0", + "illuminate/process": "^10.24|^11.0|^12.0|^13.0", + "illuminate/support": "^10.24|^11.0|^12.0|^13.0", + "nunomaduro/termwind": "^1.15|^2.0", + "php": "^8.2", + "symfony/console": "^6.0|^7.0|^8.0" + }, + "require-dev": { + "laravel/framework": "^10.24|^11.0|^12.0|^13.0", + "laravel/pint": "^1.13", + "orchestra/testbench-core": "^8.13|^9.17|^10.8|^11.0", + "pestphp/pest": "^2.20|^3.0|^4.0", + "pestphp/pest-plugin-type-coverage": "^2.3|^3.0|^4.0", + "phpstan/phpstan": "^1.12.27", + "symfony/var-dumper": "^6.3|^7.0|^8.0", + "symfony/yaml": "^6.3|^7.0|^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Pail\\PailServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Pail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Easily delve into your Laravel application's log files directly from the command line.", + "homepage": "https://github.com/laravel/pail", + "keywords": [ + "dev", + "laravel", + "logs", + "php", + "tail" + ], + "support": { + "issues": "https://github.com/laravel/pail/issues", + "source": "https://github.com/laravel/pail" + }, + "time": "2026-02-09T13:44:54+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.25", + "version": "v0.3.16", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95" + "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/7b4029a84c37cb2725fc7f011586e2997040bc95", - "reference": "7b4029a84c37cb2725fc7f011586e2997040bc95", + "url": "https://api.github.com/repos/laravel/prompts/zipball/11e7d5f93803a2190b00e145142cb00a33d17ad2", + "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2", "shasum": "" }, "require": { + "composer-runtime-api": "^2.2", "ext-mbstring": "*", - "illuminate/collections": "^10.0|^11.0", "php": "^8.1", - "symfony/console": "^6.2|^7.0" + "symfony/console": "^6.2|^7.0|^8.0" }, "conflict": { "illuminate/console": ">=10.17.0 <10.25.0", "laravel/framework": ">=10.17.0 <10.25.0" }, "require-dev": { + "illuminate/collections": "^10.0|^11.0|^12.0|^13.0", "mockery/mockery": "^1.5", - "pestphp/pest": "^2.3", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-mockery": "^1.1" + "pestphp/pest": "^2.3|^3.4|^4.0", + "phpstan/phpstan": "^1.12.28", + "phpstan/phpstan-mockery": "^1.1.3" }, "suggest": { "ext-pcntl": "Required for the spinner to be animated." @@ -2756,7 +2850,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "0.1.x-dev" + "dev-main": "0.3.x-dev" } }, "autoload": { @@ -2774,38 +2868,38 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.25" + "source": "https://github.com/laravel/prompts/tree/v0.3.16" }, - "time": "2024-08-12T22:06:33+00:00" + "time": "2026-03-23T14:35:33+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.3.7", + "version": "v2.0.11", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "4f48ade902b94323ca3be7646db16209ec76be3d" + "reference": "d1af40ac4a6ccc12bd062a7184f63c9995a63bdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/4f48ade902b94323ca3be7646db16209ec76be3d", - "reference": "4f48ade902b94323ca3be7646db16209ec76be3d", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/d1af40ac4a6ccc12bd062a7184f63c9995a63bdd", + "reference": "d1af40ac4a6ccc12bd062a7184f63c9995a63bdd", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.1" }, "require-dev": { - "illuminate/support": "^8.0|^9.0|^10.0|^11.0", - "nesbot/carbon": "^2.61|^3.0", - "pestphp/pest": "^1.21.3", - "phpstan/phpstan": "^1.8.2", - "symfony/var-dumper": "^5.4.11|^6.2.0|^7.0.0" + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36|^3.0|^4.0", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0|^8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -2837,37 +2931,37 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2024-11-14T18:34:49+00:00" + "time": "2026-04-07T13:32:18+00:00" }, { "name": "laravel/tinker", - "version": "v2.11.1", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741" + "reference": "cc74081282ba2e3dae1f0068ccb330370d24634e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/c9f80cc835649b5c1842898fb043f8cc098dd741", - "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741", + "url": "https://api.github.com/repos/laravel/tinker/zipball/cc74081282ba2e3dae1f0068ccb330370d24634e", + "reference": "cc74081282ba2e3dae1f0068ccb330370d24634e", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^7.2.5|^8.0", - "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0|^8.0" + "illuminate/console": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "php": "^8.1", + "psy/psysh": "^0.12.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0|^8.0" }, "require-dev": { "mockery/mockery": "~1.3.3|^1.4.2", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" + "phpunit/phpunit": "^10.5|^11.5" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." + "illuminate/database": "The Illuminate Database package (^8.0|^9.0|^10.0|^11.0|^12.0|^13.0)." }, "type": "library", "extra": { @@ -2875,6 +2969,9 @@ "providers": [ "Laravel\\Tinker\\TinkerServiceProvider" ] + }, + "branch-alias": { + "dev-master": "3.x-dev" } }, "autoload": { @@ -2901,9 +2998,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.11.1" + "source": "https://github.com/laravel/tinker/tree/v3.0.0" }, - "time": "2026-02-06T14:12:35+00:00" + "time": "2026-03-17T14:53:17+00:00" }, { "name": "league/commonmark", @@ -3283,79 +3380,334 @@ "time": "2024-09-21T08:32:55+00:00" }, { - "name": "mockery/mockery", - "version": "1.6.12", + "name": "league/uri", + "version": "7.8.1", "source": { "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", "shasum": "" }, "require": { - "hamcrest/hamcrest-php": "^2.0.1", - "lib-pcre": ">=7.0", - "php": ">=7.3" + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" }, "conflict": { - "phpunit/phpunit": "<8.0" + "league/uri-schemes": "^1.0" }, - "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.6.17", - "symplify/easy-coding-standard": "^12.1.14" + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, "autoload": { - "files": [ - "library/helpers.php", - "library/Mockery.php" - ], "psr-4": { - "Mockery\\": "library/Mockery" + "League\\Uri\\": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "https://github.com/padraic", - "role": "Author" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "https://davedevelopment.co.uk", - "role": "Developer" - }, - { - "name": "Nathanael Esayeas", - "email": "nathanael.esayeas@protonmail.com", - "homepage": "https://github.com/ghostwriter", - "role": "Lead Developer" + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" } ], - "description": "Mockery is a simple yet flexible PHP mock object framework", - "homepage": "https://github.com/mockery/mockery", + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-15T20:22:25+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-08T20:05:35+00:00" + }, + { + "name": "marc-mabe/php-enum", + "version": "v4.7.2", + "source": { + "type": "git", + "url": "https://github.com/marc-mabe/php-enum.git", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef", + "shasum": "" + }, + "require": { + "ext-reflection": "*", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpbench/phpbench": "^0.16.10 || ^1.0.4", + "phpstan/phpstan": "^1.3.1", + "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11", + "vimeo/psalm": "^4.17.0 | ^5.26.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.2-dev", + "dev-master": "4.7-dev" + } + }, + "autoload": { + "psr-4": { + "MabeEnum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Marc Bennewitz", + "email": "dev@mabe.berlin", + "homepage": "https://mabe.berlin/", + "role": "Lead" + } + ], + "description": "Simple and fast implementation of enumerations with native PHP", + "homepage": "https://github.com/marc-mabe/php-enum", + "keywords": [ + "enum", + "enum-map", + "enum-set", + "enumeration", + "enumerator", + "enummap", + "enumset", + "map", + "set", + "type", + "type-hint", + "typehint" + ], + "support": { + "issues": "https://github.com/marc-mabe/php-enum/issues", + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.2" + }, + "time": "2025-09-14T11:18:39+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], "support": { "docs": "https://docs.mockery.io/", "issues": "https://github.com/mockery/mockery/issues", @@ -3530,42 +3882,40 @@ }, { "name": "nesbot/carbon", - "version": "2.73.0", + "version": "3.11.4", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075" + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075", - "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { - "carbonphp/carbon-doctrine-types": "*", + "carbonphp/carbon-doctrine-types": "<100.0", "ext-json": "*", - "php": "^7.1.8 || ^8.0", + "php": "^8.1", "psr/clock": "^1.0", + "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" }, "provide": { "psr/clock-implementation": "1.0" }, "require-dev": { - "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", - "doctrine/orm": "^2.7 || ^3.0", - "friendsofphp/php-cs-fixer": "^3.0", - "kylekatarnls/multi-tester": "^2.0", - "ondrejmirtes/better-reflection": "<6", - "phpmd/phpmd": "^2.9", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.99 || ^1.7.14", - "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", - "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", - "squizlabs/php_codesniffer": "^3.4" + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^v3.87.1", + "kylekatarnls/multi-tester": "^2.5.3", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.22", + "phpunit/phpunit": "^10.5.53", + "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" }, "bin": [ "bin/carbon" @@ -3608,16 +3958,16 @@ } ], "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbon.nesbot.com", + "homepage": "https://carbonphp.github.io/carbon/", "keywords": [ "date", "datetime", "time" ], "support": { - "docs": "https://carbon.nesbot.com/docs", - "issues": "https://github.com/briannesbitt/Carbon/issues", - "source": "https://github.com/briannesbitt/Carbon" + "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", + "issues": "https://github.com/CarbonPHP/carbon/issues", + "source": "https://github.com/CarbonPHP/carbon" }, "funding": [ { @@ -3633,7 +3983,7 @@ "type": "tidelift" } ], - "time": "2025-01-08T20:10:23+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { "name": "nette/schema", @@ -3795,30 +4145,37 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.5", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", - "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" @@ -3840,46 +4197,42 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2025-12-06T11:45:25+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "nunomaduro/collision", - "version": "v7.12.0", + "version": "v8.9.3", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a" + "reference": "b0d8ab95b29c3189aeeb902d81215231df4c1b64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/995245421d3d7593a6960822063bdba4f5d7cf1a", - "reference": "995245421d3d7593a6960822063bdba4f5d7cf1a", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/b0d8ab95b29c3189aeeb902d81215231df4c1b64", + "reference": "b0d8ab95b29c3189aeeb902d81215231df4c1b64", "shasum": "" }, "require": { - "filp/whoops": "^2.17.0", - "nunomaduro/termwind": "^1.17.0", - "php": "^8.1.0", - "symfony/console": "^6.4.17" + "filp/whoops": "^2.18.4", + "nunomaduro/termwind": "^2.4.0", + "php": "^8.2.0", + "symfony/console": "^7.4.8 || ^8.0.4" }, "conflict": { - "laravel/framework": ">=11.0.0" + "laravel/framework": "<11.48.0 || >=14.0.0", + "phpunit/phpunit": "<11.5.50 || >=14.0.0" }, "require-dev": { - "brianium/paratest": "^7.4.8", - "laravel/framework": "^10.48.29", - "laravel/pint": "^1.21.2", - "laravel/sail": "^1.41.0", - "laravel/sanctum": "^3.3.3", - "laravel/tinker": "^2.10.1", - "nunomaduro/larastan": "^2.10.0", - "orchestra/testbench-core": "^8.35.0", - "pestphp/pest": "^2.36.0", - "phpunit/phpunit": "^10.5.36", - "sebastian/environment": "^6.1.0", - "spatie/laravel-ignition": "^2.9.1" + "brianium/paratest": "^7.8.5", + "larastan/larastan": "^3.9.3", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.2.0", + "laravel/pint": "^1.29.0", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.0.0", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.0.0" }, "type": "library", "extra": { @@ -3887,6 +4240,9 @@ "providers": [ "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" } }, "autoload": { @@ -3913,6 +4269,7 @@ "cli", "command-line", "console", + "dev", "error", "handling", "laravel", @@ -3938,36 +4295,35 @@ "type": "patreon" } ], - "time": "2025-03-14T22:35:49+00:00" + "time": "2026-04-06T19:25:53+00:00" }, { "name": "nunomaduro/termwind", - "version": "v1.17.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301" + "reference": "712a31b768f5daea284c2169a7d227031001b9a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/5369ef84d8142c1d87e4ec278711d4ece3cbf301", - "reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^8.1", - "symfony/console": "^6.4.15" + "php": "^8.2", + "symfony/console": "^7.4.4 || ^8.0.4" }, "require-dev": { - "illuminate/console": "^10.48.24", - "illuminate/support": "^10.48.24", - "laravel/pint": "^1.18.2", - "pestphp/pest": "^2.36.0", - "pestphp/pest-plugin-mock": "2.0.0", - "phpstan/phpstan": "^1.12.11", - "phpstan/phpstan-strict-rules": "^1.6.1", - "symfony/var-dumper": "^6.4.15", + "illuminate/console": "^11.47.0", + "laravel/pint": "^1.27.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.3.2", + "phpstan/phpstan": "^1.12.32", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.3.5 || ^8.0.4", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -3976,6 +4332,9 @@ "providers": [ "Termwind\\Laravel\\TermwindServiceProvider" ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -3996,7 +4355,7 @@ "email": "enunomaduro@gmail.com" } ], - "description": "Its like Tailwind CSS, but for the console.", + "description": "It's like Tailwind CSS, but for the console.", "keywords": [ "cli", "console", @@ -4007,7 +4366,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v1.17.0" + "source": "https://github.com/nunomaduro/termwind/tree/v2.4.0" }, "funding": [ { @@ -4023,7 +4382,7 @@ "type": "github" } ], - "time": "2024-11-21T10:36:35+00:00" + "time": "2026-02-16T23:10:27+00:00" }, { "name": "ondram/ci-detector", @@ -4105,38 +4464,37 @@ }, { "name": "orchestra/canvas", - "version": "v8.12.0", + "version": "v11.0.1", "source": { "type": "git", "url": "https://github.com/orchestral/canvas.git", - "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a" + "reference": "d240410f4cd89b380d7d89b5bbaf60c32f4fb691" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas/zipball/76385dfcf96efae5f8533a4d522d14c3c946ac5a", - "reference": "76385dfcf96efae5f8533a4d522d14c3c946ac5a", + "url": "https://api.github.com/repos/orchestral/canvas/zipball/d240410f4cd89b380d7d89b5bbaf60c32f4fb691", + "reference": "d240410f4cd89b380d7d89b5bbaf60c32f4fb691", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "composer/semver": "^3.0", - "illuminate/console": "^10.48.25", - "illuminate/database": "^10.48.25", - "illuminate/filesystem": "^10.48.25", - "illuminate/support": "^10.48.25", - "orchestra/canvas-core": "^8.10.2", - "orchestra/testbench-core": "^8.30", - "php": "^8.1", - "symfony/polyfill-php83": "^1.31", - "symfony/yaml": "^6.2" + "illuminate/console": "^13.0.0", + "illuminate/database": "^13.0.0", + "illuminate/filesystem": "^13.0.0", + "illuminate/support": "^13.0.0", + "orchestra/canvas-core": "^11.0.0", + "orchestra/sidekick": "~1.1.23|~1.2.20", + "orchestra/testbench-core": "^11.0.0", + "php": "^8.3", + "symfony/yaml": "^7.4.0|^8.0.0" }, "require-dev": { - "laravel/framework": "^10.48.25", - "laravel/pint": "^1.17", - "mockery/mockery": "^1.5.1", - "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "^10.5", - "spatie/laravel-ray": "^1.33" + "laravel/framework": "^13.0.0", + "laravel/pint": "^1.24", + "mockery/mockery": "^1.6.10", + "phpstan/phpstan": "^2.1.14", + "phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0" }, "bin": [ "canvas" @@ -4171,46 +4529,40 @@ "description": "Code Generators for Laravel Applications and Packages", "support": { "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas/tree/v8.12.0" + "source": "https://github.com/orchestral/canvas/tree/v11.0.1" }, - "time": "2024-11-30T15:38:25+00:00" + "time": "2026-03-18T22:46:12+00:00" }, { "name": "orchestra/canvas-core", - "version": "v8.11.0", + "version": "v11.0.0", "source": { "type": "git", "url": "https://github.com/orchestral/canvas-core.git", - "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611" + "reference": "88d091ff989748e2ca447bca0cd06ab14671ba82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/609c2eccdd595b4bba21702a7ea46433a28ea611", - "reference": "609c2eccdd595b4bba21702a7ea46433a28ea611", + "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/88d091ff989748e2ca447bca0cd06ab14671ba82", + "reference": "88d091ff989748e2ca447bca0cd06ab14671ba82", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "composer/semver": "^3.0", - "illuminate/console": "^10.48.22", - "illuminate/filesystem": "^10.48.22", + "illuminate/console": "^13.0", + "illuminate/support": "^13.0", "orchestra/sidekick": "~1.1.23|~1.2.20", - "php": "^8.1", - "symfony/polyfill-php83": "^1.28" - }, - "conflict": { - "orchestra/canvas": "<8.11.0", - "orchestra/testbench-core": "<8.2.0" + "php": "^8.3" }, "require-dev": { - "laravel/framework": "^10.48.22", - "laravel/pint": "^1.17", - "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^8.19", - "orchestra/workbench": "^8.18.0", + "laravel/framework": "^13.0", + "laravel/pint": "^1.24", + "mockery/mockery": "^1.6.10", + "orchestra/testbench-core": "^11.0", "phpstan/phpstan": "^2.1.17", - "phpunit/phpunit": "^10.1", - "symfony/yaml": "^6.2" + "phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0", + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "extra": { @@ -4218,9 +4570,6 @@ "providers": [ "Orchestra\\Canvas\\Core\\LaravelServiceProvider" ] - }, - "branch-alias": { - "dev-master": "9.0-dev" } }, "autoload": { @@ -4245,9 +4594,9 @@ "description": "Code Generators Builder for Laravel Applications and Packages", "support": { "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas-core/tree/v8.11.0" + "source": "https://github.com/orchestral/canvas-core/tree/v11.0.0" }, - "time": "2026-02-24T13:35:32+00:00" + "time": "2026-03-16T15:10:50+00:00" }, { "name": "orchestra/sidekick", @@ -4310,30 +4659,30 @@ }, { "name": "orchestra/testbench", - "version": "v8.37.0", + "version": "v11.1.0", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39" + "reference": "997f33e5200c7e8db4756b35a9deb3f5f3086759" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/c03266385ad996a7c3c9bb6219df8f6558ecea39", - "reference": "c03266385ad996a7c3c9bb6219df8f6558ecea39", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/997f33e5200c7e8db4756b35a9deb3f5f3086759", + "reference": "997f33e5200c7e8db4756b35a9deb3f5f3086759", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", - "fakerphp/faker": "^1.21", - "laravel/framework": "^10.50.0", - "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^8.40.0", - "orchestra/workbench": "^8.18.0", - "php": "^8.1", - "phpunit/phpunit": "^9.6|^10.1", - "symfony/process": "^6.2", - "symfony/yaml": "^6.2", - "vlucas/phpdotenv": "^5.4.1" + "fakerphp/faker": "^1.23", + "laravel/framework": "^13.1.1", + "mockery/mockery": "^1.6.10", + "orchestra/testbench-core": "^11.2.0", + "orchestra/workbench": "^11.0.1", + "php": "^8.3", + "phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0", + "symfony/process": "^7.4.5|^8.0.5", + "symfony/yaml": "^7.4|^8.0", + "vlucas/phpdotenv": "^5.6.1" }, "type": "library", "notification-url": "https://packagist.org/downloads/", @@ -4359,67 +4708,62 @@ ], "support": { "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v8.37.0" + "source": "https://github.com/orchestral/testbench/tree/v11.1.0" }, - "time": "2026-01-14T02:47:41+00:00" + "time": "2026-04-09T05:11:06+00:00" }, { "name": "orchestra/testbench-core", - "version": "v8.42.1", + "version": "v11.2.1", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "40bbb1d61af3e9663949902e1556d41d80483a6f" + "reference": "2ad327323951238a005a3f81cbcd22268bb72985" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/40bbb1d61af3e9663949902e1556d41d80483a6f", - "reference": "40bbb1d61af3e9663949902e1556d41d80483a6f", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/2ad327323951238a005a3f81cbcd22268bb72985", + "reference": "2ad327323951238a005a3f81cbcd22268bb72985", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", "orchestra/sidekick": "~1.1.23|~1.2.20", - "php": "^8.1", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-php83": "^1.33" + "php": "^8.3", + "symfony/deprecation-contracts": "^2.5|^3.0" }, "conflict": { - "brianium/paratest": "<6.4.0|>=7.0.0 <7.1.4|>=8.0.0", - "laravel/framework": "<10.50.0|>=11.0.0", - "laravel/serializable-closure": "<1.3.0|>=3.0.0", - "nunomaduro/collision": "<6.4.0|>=7.0.0 <7.4.0|>=8.0.0", - "orchestra/testbench-dusk": "<8.32.0|>=9.0.0", - "orchestra/workbench": "<1.0.0", - "pestphp/pest": "<2.0.0", - "phpunit/phpunit": "<9.6.0|>=10.3.0 <10.3.3|>=10.6.0" + "brianium/paratest": "<7.3.0|>=8.0.0", + "laravel/framework": "<13.4.0|>=14.0.0", + "laravel/serializable-closure": ">=2.0.0 <2.0.10|>=3.0.0", + "nunomaduro/collision": "<8.9.0|>=9.0.0", + "phpunit/phpunit": "<11.5.50|>=12.0.0 <12.5.8|>=13.2.0" }, "require-dev": { - "fakerphp/faker": "^1.21", - "laravel/framework": "^10.50.0", - "laravel/pint": "^1.20", - "laravel/serializable-closure": "^1.3|^2.0", - "mockery/mockery": "^1.5.1", - "phpstan/phpstan": "^2.1.33", - "phpunit/phpunit": "^10.1", - "spatie/laravel-ray": "^1.40.2", - "symfony/process": "^6.2", - "symfony/yaml": "^6.2", - "vlucas/phpdotenv": "^5.4.1" + "fakerphp/faker": "^1.24", + "laravel/framework": "^13.4.0", + "laravel/pint": "^1.24", + "laravel/serializable-closure": "^2.0.10", + "mockery/mockery": "^1.6.10", + "phpstan/phpstan": "^2.1.38", + "phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0", + "spatie/laravel-ray": "^1.43.6", + "symfony/process": "^7.4.5|^8.0.5", + "symfony/yaml": "^7.4.0|^8.0.0", + "vlucas/phpdotenv": "^5.6.1" }, "suggest": { - "brianium/paratest": "Allow using parallel testing (^6.4|^7.1.4).", + "brianium/paratest": "Allow using parallel testing (^7.3).", "ext-pcntl": "Required to use all features of the console signal trapping.", - "fakerphp/faker": "Allow using Faker for testing (^1.21).", - "laravel/framework": "Required for testing (^10.48.29).", - "mockery/mockery": "Allow using Mockery for testing (^1.5.1).", - "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^6.4|^7.4).", - "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^8.0).", - "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^8.0).", - "phpunit/phpunit": "Allow using PHPUnit for testing (^9.6|^10.1).", - "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^6.2).", - "symfony/yaml": "Required for Testbench CLI (^6.2).", - "vlucas/phpdotenv": "Required for Testbench CLI (^5.4.1)." + "fakerphp/faker": "Allow using Faker for testing (^1.23).", + "laravel/framework": "Required for testing (^13.1.1).", + "mockery/mockery": "Allow using Mockery for testing (^1.6).", + "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^8.9).", + "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^11.0).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^11.5.50|^12.5.8|^13.0.0).", + "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^7.4|^8.0).", + "symfony/yaml": "Required for Testbench CLI (^7.4|^8.0).", + "vlucas/phpdotenv": "Required for Testbench CLI (^5.6.1)." }, "bin": [ "testbench" @@ -4458,43 +4802,42 @@ "issues": "https://github.com/orchestral/testbench/issues", "source": "https://github.com/orchestral/testbench-core" }, - "time": "2026-03-31T02:52:50+00:00" + "time": "2026-04-09T03:55:53+00:00" }, { "name": "orchestra/workbench", - "version": "v8.19.0", + "version": "v11.1.0", "source": { "type": "git", "url": "https://github.com/orchestral/workbench.git", - "reference": "7d30294ff1382c8654c27902147826a3aabb9a5a" + "reference": "e750c7bcae4405e054ff286475502e23274de04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/workbench/zipball/7d30294ff1382c8654c27902147826a3aabb9a5a", - "reference": "7d30294ff1382c8654c27902147826a3aabb9a5a", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/e750c7bcae4405e054ff286475502e23274de04b", + "reference": "e750c7bcae4405e054ff286475502e23274de04b", "shasum": "" }, "require": { "composer-runtime-api": "^2.2", - "fakerphp/faker": "^1.21", - "laravel/framework": "^10.48.28", - "laravel/tinker": "^2.8.2", - "nunomaduro/collision": "^6.4|^7.10", - "orchestra/canvas": "^8.12.0", - "orchestra/canvas-core": "^8.11.0", + "fakerphp/faker": "^1.23", + "laravel/framework": "^13.0.0", + "laravel/pail": "^1.2.5", + "laravel/tinker": "^3.0.0", + "nunomaduro/collision": "^8.9", + "orchestra/canvas": "^11.0.1", "orchestra/sidekick": "~1.1.23|~1.2.20", - "orchestra/testbench-core": "^8.42.0", - "php": "^8.1", - "symfony/polyfill-php83": "^1.33", - "symfony/process": "^6.2", - "symfony/yaml": "^6.2" + "orchestra/testbench-core": "^11.1.0", + "php": "^8.3", + "symfony/process": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0" }, "require-dev": { - "laravel/pint": "^1.20", - "mockery/mockery": "^1.5.1", + "laravel/pint": "^1.22.0", + "mockery/mockery": "^1.6.12", "phpstan/phpstan": "^2.1.33", - "phpunit/phpunit": "^10.1", - "spatie/laravel-ray": "^1.40.2" + "phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0", + "spatie/laravel-ray": "^1.43.6" }, "suggest": { "ext-pcntl": "Required to use all features of the console signal trapping." @@ -4524,9 +4867,9 @@ ], "support": { "issues": "https://github.com/orchestral/workbench/issues", - "source": "https://github.com/orchestral/workbench/tree/v8.19.0" + "source": "https://github.com/orchestral/workbench/tree/v11.1.0" }, - "time": "2026-03-24T15:03:48+00:00" + "time": "2026-03-24T23:09:55+00:00" }, { "name": "pdepend/pdepend", @@ -4970,15 +5313,15 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.33", + "version": "2.1.46", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", - "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a193923fc2d6325ef4e741cf3af8c3e8f54dbf25", + "reference": "a193923fc2d6325ef4e741cf3af8c3e8f54dbf25", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -5019,39 +5362,38 @@ "type": "github" } ], - "time": "2026-02-28T20:30:03+00:00" + "time": "2026-04-01T09:25:14+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.32", + "version": "14.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + "reference": "24f1d7300e54e910197ee65e83d27a1e4bdc917e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/24f1d7300e54e910197ee65e83d27a1e4bdc917e", + "reference": "24f1d7300e54e910197ee65e83d27a1e4bdc917e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-text-template": "^2.0.4", - "sebastian/code-unit-reverse-lookup": "^2.0.3", - "sebastian/complexity": "^2.0.3", - "sebastian/environment": "^5.1.5", - "sebastian/lines-of-code": "^1.0.4", - "sebastian/version": "^3.0.2", - "theseer/tokenizer": "^1.2.3" + "nikic/php-parser": "^5.7.0", + "php": ">=8.4", + "phpunit/php-text-template": "^6.0", + "sebastian/complexity": "^6.0", + "sebastian/environment": "^9.1", + "sebastian/git-state": "^1.0", + "sebastian/lines-of-code": "^5.0", + "sebastian/version": "^7.0", + "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^13.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -5060,7 +5402,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "9.2.x-dev" + "dev-main": "14.0.x-dev" } }, "autoload": { @@ -5089,40 +5431,52 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/14.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" } ], - "time": "2024-08-22T04:23:01+00:00" + "time": "2026-04-03T05:11:05+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", + "reference": "6e5aa1fb0a95b1703d83e721299ee18bb4e2de50", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -5149,36 +5503,49 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2026-02-06T04:33:26+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88", + "reference": "42e5c5cae0c65df12d1b1a3ab52bf3f50f244d88", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "suggest": { "ext-pcntl": "*" @@ -5186,7 +5553,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -5212,40 +5579,53 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-invoker", + "type": "tidelift" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2026-02-06T04:34:47+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/a47af19f93f76aa3368303d752aa5272ca3299f4", + "reference": "a47af19f93f76aa3368303d752aa5272ca3299f4", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -5271,40 +5651,53 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/6.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-text-template", + "type": "tidelift" + } + ], + "time": "2026-02-06T04:36:37+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "9.0.0", + "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a0e12065831f6ab0d83120dc61513eb8d9a966f6", + "reference": "a0e12065831f6ab0d83120dc61513eb8d9a966f6", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "9.0-dev" } }, "autoload": { @@ -5330,32 +5723,44 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/9.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-timer", + "type": "tidelift" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2026-02-06T04:37:53+00:00" }, { "name": "phpunit/phpunit", - "version": "9.6.34", + "version": "13.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b36f02317466907a230d3aa1d34467041271ef4a" + "reference": "bf114c99266501d45acc00ad96d5606f3f7ad99c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", - "reference": "b36f02317466907a230d3aa1d34467041271ef4a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bf114c99266501d45acc00ad96d5606f3f7ad99c", + "reference": "bf114c99266501d45acc00ad96d5606f3f7ad99c", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -5365,27 +5770,24 @@ "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.32", - "phpunit/php-file-iterator": "^3.0.6", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.4", - "phpunit/php-timer": "^5.0.3", - "sebastian/cli-parser": "^1.0.2", - "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.10", - "sebastian/diff": "^4.0.6", - "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.8", - "sebastian/global-state": "^5.0.8", - "sebastian/object-enumerator": "^4.0.4", - "sebastian/resource-operations": "^3.0.4", - "sebastian/type": "^3.2.1", - "sebastian/version": "^3.0.2" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "php": ">=8.4.1", + "phpunit/php-code-coverage": "^14.0", + "phpunit/php-file-iterator": "^7.0.0", + "phpunit/php-invoker": "^7.0.0", + "phpunit/php-text-template": "^6.0.0", + "phpunit/php-timer": "^9.0.0", + "sebastian/cli-parser": "^5.0.0", + "sebastian/comparator": "^8.1.0", + "sebastian/diff": "^8.1.0", + "sebastian/environment": "^9.2.0", + "sebastian/exporter": "^8.0.0", + "sebastian/git-state": "^1.0", + "sebastian/global-state": "^9.0.0", + "sebastian/object-enumerator": "^8.0.0", + "sebastian/recursion-context": "^8.0.0", + "sebastian/type": "^7.0.0", + "sebastian/version": "^7.0.0", + "staabm/side-effects-detector": "^1.0.5" }, "bin": [ "phpunit" @@ -5393,7 +5795,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-main": "13.1-dev" } }, "autoload": { @@ -5425,31 +5827,15 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" + "source": "https://github.com/sebastianbergmann/phpunit/tree/13.1.1" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" + "url": "https://phpunit.de/sponsoring.html", + "type": "other" } ], - "time": "2026-01-27T05:45:00+00:00" + "time": "2026-04-08T03:07:38+00:00" }, { "name": "povils/phpmnd", @@ -5990,60 +6376,75 @@ "time": "2025-12-14T04:43:48+00:00" }, { - "name": "sanmai/later", - "version": "0.1.7", + "name": "sanmai/di-container", + "version": "0.1.12", "source": { "type": "git", - "url": "https://github.com/sanmai/later.git", - "reference": "72a82d783864bca90412d8a26c1878f8981fee97" + "url": "https://github.com/sanmai/di-container.git", + "reference": "8b9ad72f6ac1f9e185e5bd060dc9479cb5191d8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sanmai/later/zipball/72a82d783864bca90412d8a26c1878f8981fee97", - "reference": "72a82d783864bca90412d8a26c1878f8981fee97", + "url": "https://api.github.com/repos/sanmai/di-container/zipball/8b9ad72f6ac1f9e185e5bd060dc9479cb5191d8b", + "reference": "8b9ad72f6ac1f9e185e5bd060dc9479cb5191d8b", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "psr/container": "^1.1.2 || ^2.0", + "sanmai/pipeline": "^6.17 || ^7.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.8", - "friendsofphp/php-cs-fixer": "^3.35.1", - "infection/infection": ">=0.27.6", - "phan/phan": ">=2", - "php-coveralls/php-coveralls": "^2.0", - "phpstan/phpstan": ">=1.4.5", - "phpunit/phpunit": ">=9.5 <10", - "vimeo/psalm": ">=2" + "friendsofphp/php-cs-fixer": "^3.17", + "infection/infection": ">=0.31", + "php-coveralls/php-coveralls": "^2.4.1", + "phpbench/phpbench": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpunit/phpunit": "^11.5.25", + "sanmai/phpstan-rules": "^0.3.10" }, "type": "library", "extra": { "branch-alias": { "dev-main": "0.1.x-dev" - } + }, + "preferred-install": "dist" }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Later\\": "src/" + "DIContainer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "Apache-2.0" + "BSD-3-Clause" ], "authors": [ { "name": "Alexey Kopytko", - "email": "alexey@kopytko.com" + "email": "alexey@kopytko.com", + "homepage": "https://github.com/sanmai" + }, + { + "name": "Maks Rafalko", + "homepage": "https://twitter.com/maks_rafalko" + }, + { + "name": "Théo FIDRY", + "homepage": "https://twitter.com/tfidry" } ], - "description": "Later: deferred wrapper object", + "description": "dependency injection container with automatic constructor dependency resolution", + "keywords": [ + "Autowiring", + "constructor di", + "di container", + "psr 11" + ], "support": { - "issues": "https://github.com/sanmai/later/issues", - "source": "https://github.com/sanmai/later/tree/0.1.7" + "issues": "https://github.com/sanmai/di-container/issues", + "source": "https://github.com/sanmai/di-container/tree/0.1.12" }, "funding": [ { @@ -6051,51 +6452,46 @@ "type": "github" } ], - "time": "2025-05-11T01:48:00+00:00" + "time": "2026-01-27T08:25:46+00:00" }, { - "name": "sanmai/pipeline", - "version": "6.22", + "name": "sanmai/duoclock", + "version": "0.1.3", "source": { "type": "git", - "url": "https://github.com/sanmai/pipeline.git", - "reference": "fb8d0c23b4ef085315a36d397fafa052203020ce" + "url": "https://github.com/sanmai/DuoClock.git", + "reference": "47461e3ff65b7308635047831a55615652e7be1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sanmai/pipeline/zipball/fb8d0c23b4ef085315a36d397fafa052203020ce", - "reference": "fb8d0c23b4ef085315a36d397fafa052203020ce", + "url": "https://api.github.com/repos/sanmai/DuoClock/zipball/47461e3ff65b7308635047831a55615652e7be1a", + "reference": "47461e3ff65b7308635047831a55615652e7be1a", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.8", - "esi/phpunit-coverage-check": ">2", "friendsofphp/php-cs-fixer": "^3.17", - "infection/infection": ">=0.30.3", - "league/pipeline": "^0.3 || ^1.0", + "infection/infection": ">=0.29", "php-coveralls/php-coveralls": "^2.4.1", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2", - "phpunit/phpunit": ">=9.4 <12", - "sanmai/phpstan-rules": "^0.3.0", - "sanmai/phpunit-double-colon-syntax": "^0.1.1", - "vimeo/psalm": ">=2" + "phpunit/phpunit": "^11.5.25", + "sanmai/phpstan-rules": "^0.3.1" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "v6.x-dev" - } + "preferred-install": "dist" }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Pipeline\\": "src/" + "DuoClock\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -6108,10 +6504,10 @@ "email": "alexey@kopytko.com" } ], - "description": "General-purpose collections pipeline", + "description": "PHP time mocking for tests - PSR-20 clock with mockable sleep(), time(), and TimeSpy for PHPUnit testing", "support": { - "issues": "https://github.com/sanmai/pipeline/issues", - "source": "https://github.com/sanmai/pipeline/tree/6.22" + "issues": "https://github.com/sanmai/DuoClock/issues", + "source": "https://github.com/sanmai/DuoClock/tree/0.1.3" }, "funding": [ { @@ -6119,144 +6515,164 @@ "type": "github" } ], - "time": "2025-07-22T09:07:07+00:00" + "time": "2025-12-26T06:12:34+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.2", + "name": "sanmai/later", + "version": "0.1.7", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + "url": "https://github.com/sanmai/later.git", + "reference": "72a82d783864bca90412d8a26c1878f8981fee97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "url": "https://api.github.com/repos/sanmai/later/zipball/72a82d783864bca90412d8a26c1878f8981fee97", + "reference": "72a82d783864bca90412d8a26c1878f8981fee97", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "ergebnis/composer-normalize": "^2.8", + "friendsofphp/php-cs-fixer": "^3.35.1", + "infection/infection": ">=0.27.6", + "phan/phan": ">=2", + "php-coveralls/php-coveralls": "^2.0", + "phpstan/phpstan": ">=1.4.5", + "phpunit/phpunit": ">=9.5 <10", + "vimeo/psalm": ">=2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "0.1.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/functions.php" + ], + "psr-4": { + "Later\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "Apache-2.0" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Alexey Kopytko", + "email": "alexey@kopytko.com" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Later: deferred wrapper object", "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + "issues": "https://github.com/sanmai/later/issues", + "source": "https://github.com/sanmai/later/tree/0.1.7" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/sanmai", "type": "github" } ], - "time": "2024-03-02T06:27:43+00:00" + "time": "2025-05-11T01:48:00+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.8", + "name": "sanmai/pipeline", + "version": "7.9", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "url": "https://github.com/sanmai/pipeline.git", + "reference": "d7046ecce91ae57fca403be694888371a21250eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sanmai/pipeline/zipball/d7046ecce91ae57fca403be694888371a21250eb", + "reference": "d7046ecce91ae57fca403be694888371a21250eb", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "ergebnis/composer-normalize": "^2.8", + "esi/phpunit-coverage-check": ">2", + "friendsofphp/php-cs-fixer": "^3.17", + "infection/infection": ">=0.32.3", + "league/pipeline": "^0.3 || ^1.0", + "php-coveralls/php-coveralls": "^2.4.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2", + "phpunit/phpunit": ">=9.4 <12", + "sanmai/phpstan-rules": "^0.3.11", + "sanmai/phpunit-double-colon-syntax": "^0.1.1", + "vimeo/psalm": ">=2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "7.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/functions.php" + ], + "psr-4": { + "Pipeline\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "Apache-2.0" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Alexey Kopytko", + "email": "alexey@kopytko.com" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "General-purpose collections pipeline", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "issues": "https://github.com/sanmai/pipeline/issues", + "source": "https://github.com/sanmai/pipeline/tree/7.9" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/sanmai", "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2026-01-16T11:54:05+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "name": "sebastian/cli-parser", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/48a4654fa5e48c1c81214e9930048a572d4b23ca", + "reference": "48a4654fa5e48c1c81214e9930048a572d4b23ca", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -6271,49 +6687,68 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/5.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2026-02-06T04:39:44+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.10", + "version": "8.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" + "reference": "44b063d0a64da0e8ea74fb6464d8de2b1429ab7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", - "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/44b063d0a64da0e8ea74fb6464d8de2b1429ab7e", + "reference": "44b063d0a64da0e8ea74fb6464d8de2b1429ab7e", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.4", + "sebastian/diff": "^8.1", + "sebastian/exporter": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -6352,7 +6787,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/8.1.1" }, "funding": [ { @@ -6372,33 +6808,33 @@ "type": "tidelift" } ], - "time": "2026-01-24T09:22:56+00:00" + "time": "2026-04-08T04:47:31+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.3", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "reference": "c5651c795c98093480df79350cb050813fc7a2f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/c5651c795c98093480df79350cb050813fc7a2f3", + "reference": "c5651c795c98093480df79350cb050813fc7a2f3", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6421,41 +6857,54 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/6.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/complexity", + "type": "tidelift" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2026-02-06T04:41:32+00:00" }, { "name": "sebastian/diff", - "version": "4.0.6", + "version": "8.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + "reference": "9c957d730257f49c873f3761674559bd90098a7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/9c957d730257f49c873f3761674559bd90098a7d", + "reference": "9c957d730257f49c873f3761674559bd90098a7d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^13.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -6487,35 +6936,48 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/8.1.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/diff", + "type": "tidelift" } ], - "time": "2024-03-02T06:30:58+00:00" + "time": "2026-04-05T12:02:33+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "9.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "c0964f624fcac84e318fc9ef0193cbb9809a331a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/c0964f624fcac84e318fc9ef0193cbb9809a331a", + "reference": "c0964f624fcac84e318fc9ef0193cbb9809a331a", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "suggest": { "ext-posix": "*" @@ -6523,7 +6985,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "9.2-dev" } }, "autoload": { @@ -6542,7 +7004,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -6550,42 +7012,55 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/9.2.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2026-04-05T07:07:20+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.8", + "version": "8.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c" + "reference": "40801a527c8c3eaed8aa7f95ab7f144599bb1854" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c", - "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/40801a527c8c3eaed8aa7f95ab7f144599bb1854", + "reference": "40801a527c8c3eaed8aa7f95ab7f144599bb1854", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.4", + "sebastian/recursion-context": "^8.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -6627,7 +7102,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/8.0.1" }, "funding": [ { @@ -6647,38 +7123,104 @@ "type": "tidelift" } ], - "time": "2025-09-24T06:03:27+00:00" + "time": "2026-04-10T12:56:23+00:00" + }, + { + "name": "sebastian/git-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/git-state.git", + "reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/git-state/zipball/792a952e0eba55b6960a48aeceb9f371aad1f76b", + "reference": "792a952e0eba55b6960a48aeceb9f371aad1f76b", + "shasum": "" + }, + "require": { + "php": ">=8.4" + }, + "require-dev": { + "phpunit/phpunit": "^13.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for describing the state of a Git checkout", + "homepage": "https://github.com/sebastianbergmann/git-state", + "support": { + "issues": "https://github.com/sebastianbergmann/git-state/issues", + "security": "https://github.com/sebastianbergmann/git-state/security/policy", + "source": "https://github.com/sebastianbergmann/git-state/tree/1.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/git-state", + "type": "tidelift" + } + ], + "time": "2026-03-21T12:54:28+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.8", + "version": "9.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" + "reference": "e52e3dc22441e6218c710afe72c3042f8fc41ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", - "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e52e3dc22441e6218c710afe72c3042f8fc41ea7", + "reference": "e52e3dc22441e6218c710afe72c3042f8fc41ea7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.4", + "sebastian/object-reflector": "^6.0", + "sebastian/recursion-context": "^8.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "9.0-dev" } }, "autoload": { @@ -6697,13 +7239,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/9.0.0" }, "funding": [ { @@ -6723,33 +7266,33 @@ "type": "tidelift" } ], - "time": "2025-08-10T07:10:35+00:00" + "time": "2026-02-06T04:45:13+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "reference": "4f21bb7768e1c997722ccc7efb1d6b5c11bfd471" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/4f21bb7768e1c997722ccc7efb1d6b5c11bfd471", + "reference": "4f21bb7768e1c997722ccc7efb1d6b5c11bfd471", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -6772,42 +7315,55 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/5.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/lines-of-code", + "type": "tidelift" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2026-02-06T04:45:54+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", + "reference": "b39ab125fd9a7434b0ecbc4202eebce11a98cfc5", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.4", + "sebastian/object-reflector": "^6.0", + "sebastian/recursion-context": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -6829,40 +7385,53 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/8.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/object-enumerator", + "type": "tidelift" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2026-02-06T04:46:36+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", + "reference": "3ca042c2c60b0eab094f8a1b6a7093f4d4c72200", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6884,40 +7453,53 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/6.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/object-reflector", + "type": "tidelift" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2026-02-06T04:47:13+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.6", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "539c6691e0623af6dc6f9c20384c120f963465a0" + "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0", - "reference": "539c6691e0623af6dc6f9c20384c120f963465a0", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/74c5af21f6a5833e91767ca068c4d3dfec15317e", + "reference": "74c5af21f6a5833e91767ca068c4d3dfec15317e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -6947,7 +7529,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/8.0.0" }, "funding": [ { @@ -6967,86 +7550,32 @@ "type": "tidelift" } ], - "time": "2025-08-10T06:57:39+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2026-02-06T04:51:28+00:00" }, { "name": "sebastian/type", - "version": "3.2.1", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "reference": "42412224607bd3931241bbd17f38e0f972f5a916" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/42412224607bd3931241bbd17f38e0f972f5a916", + "reference": "42412224607bd3931241bbd17f38e0f972f5a916", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^13.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -7069,37 +7598,50 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2026-02-06T04:52:09+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ad37a5552c8e2b88572249fdc19b6da7792e021b", + "reference": "ad37a5552c8e2b88572249fdc19b6da7792e021b", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -7122,15 +7664,28 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/7.0.0" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/version", + "type": "tidelift" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2026-02-06T04:52:52+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -7174,42 +7729,171 @@ "role": "Current lead" }, { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-11-10T16:43:36+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/clock", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", "keywords": [ - "phpcs", - "standards", - "static analysis" + "clock", + "psr20", + "time" ], "support": { - "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", - "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", - "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", - "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + "source": "https://github.com/symfony/clock/tree/v8.0.8" }, "funding": [ { - "url": "https://github.com/PHPCSStandards", - "type": "github" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "url": "https://github.com/jrfnl", + "url": "https://github.com/fabpot", "type": "github" }, { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "url": "https://thanks.dev/u/gh/phpcsstandards", - "type": "thanks_dev" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-11-10T16:43:36+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/config", @@ -7292,47 +7976,39 @@ }, { "name": "symfony/console", - "version": "v6.4.36", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5" + "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", - "reference": "9f481cfb580db8bcecc9b2d4c63f3e13df022ad5", + "url": "https://api.github.com/repos/symfony/console/zipball/5b66d385dc58f69652e56f78a4184615e3f2b7f7", + "reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/string": "^7.4|^8.0" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7366,7 +8042,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.36" + "source": "https://github.com/symfony/console/tree/v8.0.8" }, "funding": [ { @@ -7386,7 +8062,7 @@ "type": "tidelift" } ], - "time": "2026-03-27T15:30:51+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/css-selector", @@ -7543,31 +8219,33 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.36", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361" + "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/2ea68f0e1835ad6a126f93bbc14cd236c10ab361", - "reference": "2ea68f0e1835ad6a126f93bbc14cd236c10ab361", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c1119fe8dcfc3825ec74ec061b96ef0c8f281517", + "reference": "c1119fe8dcfc3825ec74ec061b96ef0c8f281517", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.4", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0|^7.0" + "symfony/polyfill-php85": "^1.32", + "symfony/var-dumper": "^7.4|^8.0" }, "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" + "symfony/deprecation-contracts": "<2.5" }, "require-dev": { + "symfony/console": "^7.4|^8.0", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^5.4|^6.0|^7.0" + "symfony/http-kernel": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0", + "symfony/webpack-encore-bundle": "^1.0|^2.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -7598,7 +8276,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.36" + "source": "https://github.com/symfony/error-handler/tree/v8.0.8" }, "funding": [ { @@ -7618,28 +8296,28 @@ "type": "tidelift" } ], - "time": "2026-03-10T15:56:14+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.4.8", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a" + "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", - "reference": "f57b899fa736fd71121168ef268f23c206083f0a", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f662acc6ab22a3d6d716dcb44c381c6002940df6", + "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<6.4", + "symfony/security-http": "<7.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -7648,14 +8326,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/error-handler": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/framework-bundle": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0|^8.0" + "symfony/stopwatch": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7683,7 +8361,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.8" }, "funding": [ { @@ -7703,7 +8381,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -7853,23 +8531,23 @@ }, { "name": "symfony/finder", - "version": "v6.4.34", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896" + "reference": "8da41214757b87d97f181e3d14a4179286151007" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9590e86be1d1c57bfbb16d0dd040345378c20896", - "reference": "9590e86be1d1c57bfbb16d0dd040345378c20896", + "url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007", + "reference": "8da41214757b87d97f181e3d14a4179286151007", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.4" }, "require-dev": { - "symfony/filesystem": "^6.0|^7.0" + "symfony/filesystem": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7897,7 +8575,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.34" + "source": "https://github.com/symfony/finder/tree/v8.0.8" }, "funding": [ { @@ -7917,40 +8595,39 @@ "type": "tidelift" } ], - "time": "2026-01-28T15:16:37+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.35", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2" + "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cffffd0a2c037117b742b4f8b379a22a2a33f6d2", - "reference": "cffffd0a2c037117b742b4f8b379a22a2a33f6d2", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/02656f7ebeae5c155d659e946f6b3a33df24051b", + "reference": "02656f7ebeae5c155d659e946f6b3a33df24051b", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.1" }, "conflict": { - "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + "doctrine/dbal": "<4.3" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/dbal": "^4.3", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/rate-limiter": "^5.4|^6.0|^7.0" + "symfony/cache": "^7.4|^8.0", + "symfony/clock": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/rate-limiter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7978,7 +8655,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.35" + "source": "https://github.com/symfony/http-foundation/tree/v8.0.8" }, "funding": [ { @@ -7998,77 +8675,63 @@ "type": "tidelift" } ], - "time": "2026-03-06T11:15:58+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.36", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "4087ec02119de450e9ebb60806d69c6bb8c6e468" + "reference": "1770f6818d83b2fddc12185025b93f39a90cb628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4087ec02119de450e9ebb60806d69c6bb8c6e468", - "reference": "4087ec02119de450e9ebb60806d69c6bb8c6e468", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1770f6818d83b2fddc12185025b93f39a90cb628", + "reference": "1770f6818d83b2fddc12185025b93f39a90cb628", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.4", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^6.4|^7.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.4", - "symfony/config": "<6.1", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", + "symfony/flex": "<2.10", "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/translation": "<5.4", "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<5.4", - "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.3", - "twig/twig": "<2.13" + "twig/twig": "<3.21" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0|^7.0", - "symfony/clock": "^6.2|^7.0", - "symfony/config": "^6.1|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/css-selector": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^6.4.1|^7.0.1", - "symfony/dom-crawler": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/browser-kit": "^7.4|^8.0", + "symfony/clock": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/css-selector": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/dom-crawler": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/finder": "^7.4|^8.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/property-access": "^5.4.5|^6.0.5|^7.0", - "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.4.4|^7.0.4", - "symfony/stopwatch": "^5.4|^6.0|^7.0", - "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/process": "^7.4|^8.0", + "symfony/property-access": "^7.4|^8.0", + "symfony/routing": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/translation": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^5.4|^6.4|^7.0", - "symfony/var-exporter": "^6.2|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0", + "twig/twig": "^3.21" }, "type": "library", "autoload": { @@ -8096,7 +8759,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.36" + "source": "https://github.com/symfony/http-kernel/tree/v8.0.8" }, "funding": [ { @@ -8116,43 +8779,39 @@ "type": "tidelift" } ], - "time": "2026-03-31T20:38:11+00:00" + "time": "2026-03-31T21:14:05+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.34", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "01b846f48e53ee4096692a383637a1fa4d577301" + "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/01b846f48e53ee4096692a383637a1fa4d577301", - "reference": "01b846f48e53ee4096692a383637a1fa4d577301", + "url": "https://api.github.com/repos/symfony/mailer/zipball/ca5f6edaf8780ece814404b58a4482b22b509c56", + "reference": "ca5f6edaf8780ece814404b58a4482b22b509c56", "shasum": "" }, "require": { "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.1", + "php": ">=8.4", "psr/event-dispatcher": "^1", "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^5.4|^6.0|^7.0", - "symfony/mime": "^6.2|^7.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", - "symfony/messenger": "<6.2", - "symfony/mime": "<6.2", - "symfony/twig-bridge": "<6.2.1" + "symfony/http-client-contracts": "<2.5" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/messenger": "^6.2|^7.0", - "symfony/twig-bridge": "^6.2|^7.0" + "symfony/console": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/twig-bridge": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -8180,7 +8839,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.34" + "source": "https://github.com/symfony/mailer/tree/v8.0.8" }, "funding": [ { @@ -8200,44 +8859,41 @@ "type": "tidelift" } ], - "time": "2026-02-24T09:34:36+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/mime", - "version": "v6.4.36", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "9c31726137c70798f815fb98293ffb8a2a47694c" + "reference": "ddff21f14c7ce04b98101b399a9463dce8b0ce66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/9c31726137c70798f815fb98293ffb8a2a47694c", - "reference": "9c31726137c70798f815fb98293ffb8a2a47694c", + "url": "https://api.github.com/repos/symfony/mime/zipball/ddff21f14c7ce04b98101b399a9463dce8b0ce66", + "reference": "ddff21f14c7ce04b98101b399a9463dce8b0ce66", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.4", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<5.4", - "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.4|^7.0", - "symfony/property-access": "^5.4|^6.0|^7.0", - "symfony/property-info": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.4.3|^7.0.3" + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/property-access": "^7.4|^8.0", + "symfony/property-info": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -8269,7 +8925,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.36" + "source": "https://github.com/symfony/mime/tree/v8.0.8" }, "funding": [ { @@ -8289,7 +8945,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T09:31:23+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/polyfill-ctype", @@ -8877,6 +9533,166 @@ ], "time": "2025-07-08T02:45:35+00:00" }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "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 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, + { + "name": "symfony/polyfill-php85", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php85.git", + "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php85\\": "" + }, + "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 8.5+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-23T16:12:55+00:00" + }, { "name": "symfony/polyfill-uuid", "version": "v1.33.0", @@ -8962,20 +9778,20 @@ }, { "name": "symfony/process", - "version": "v6.4.33", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "c46e854e79b52d07666e43924a20cb6dc546644e" + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c46e854e79b52d07666e43924a20cb6dc546644e", - "reference": "c46e854e79b52d07666e43924a20cb6dc546644e", + "url": "https://api.github.com/repos/symfony/process/zipball/cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", + "reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.4" }, "type": "library", "autoload": { @@ -9003,7 +9819,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.33" + "source": "https://github.com/symfony/process/tree/v8.0.8" }, "funding": [ { @@ -9023,40 +9839,33 @@ "type": "tidelift" } ], - "time": "2026-01-23T16:02:12+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/routing", - "version": "v6.4.34", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47" + "reference": "0de330ec2ea922a7b08ec45615bd51179de7fda4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", - "reference": "5ab3a3e1a03535ec5ca6ce2d39e4369a1096ae47", + "url": "https://api.github.com/repos/symfony/routing/zipball/0de330ec2ea922a7b08ec45615bd51179de7fda4", + "reference": "0de330ec2ea922a7b08ec45615bd51179de7fda4", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.4", "symfony/deprecation-contracts": "^2.5|^3" }, - "conflict": { - "doctrine/annotations": "<1.12", - "symfony/config": "<6.2", - "symfony/dependency-injection": "<5.4", - "symfony/yaml": "<5.4" - }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "psr/log": "^1|^2|^3", - "symfony/config": "^6.2|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/expression-language": "^5.4|^6.0|^7.0", - "symfony/http-foundation": "^5.4|^6.0|^7.0", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9090,7 +9899,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.34" + "source": "https://github.com/symfony/routing/tree/v8.0.8" }, "funding": [ { @@ -9110,7 +9919,7 @@ "type": "tidelift" } ], - "time": "2026-02-24T17:34:50+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/service-contracts", @@ -9201,35 +10010,34 @@ }, { "name": "symfony/string", - "version": "v7.4.8", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "114ac57257d75df748eda23dd003878080b8e688" + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", - "reference": "114ac57257d75df748eda23dd003878080b8e688", + "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", + "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.33", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1|^8.0", - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0" + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9268,7 +10076,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.8" + "source": "https://github.com/symfony/string/tree/v8.0.8" }, "funding": [ { @@ -9288,55 +10096,49 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation", - "version": "v6.4.34", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "d07d117db41341511671b0a1a2be48f2772189ce" + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d07d117db41341511671b0a1a2be48f2772189ce", - "reference": "d07d117db41341511671b0a1a2be48f2772189ce", + "url": "https://api.github.com/repos/symfony/translation/zipball/27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", + "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5|^3.0" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation-contracts": "^3.6.1" }, "conflict": { - "symfony/config": "<5.4", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", + "nikic/php-parser": "<5.0", "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<5.4", - "symfony/yaml": "<5.4" + "symfony/service-contracts": "<2.5" }, "provide": { "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { - "nikic/php-parser": "^4.18|^5.0", + "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/finder": "^7.4|^8.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/routing": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9367,7 +10169,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.34" + "source": "https://github.com/symfony/translation/tree/v8.0.8" }, "funding": [ { @@ -9387,7 +10189,7 @@ "type": "tidelift" } ], - "time": "2026-02-16T20:44:03+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/translation-contracts", @@ -9473,24 +10275,24 @@ }, { "name": "symfony/uid", - "version": "v6.4.32", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "6b973c385f00341b246f697d82dc01a09107acdd" + "reference": "f63fa6096a24147283bce4d29327d285326438e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/6b973c385f00341b246f697d82dc01a09107acdd", - "reference": "6b973c385f00341b246f697d82dc01a09107acdd", + "url": "https://api.github.com/repos/symfony/uid/zipball/f63fa6096a24147283bce4d29327d285326438e0", + "reference": "f63fa6096a24147283bce4d29327d285326438e0", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.4", "symfony/polyfill-uuid": "^1.15" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -9527,7 +10329,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v6.4.32" + "source": "https://github.com/symfony/uid/tree/v8.0.8" }, "funding": [ { @@ -9547,37 +10349,36 @@ "type": "tidelift" } ], - "time": "2025-12-23T15:07:59+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.36", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "7c8ad9ce4faf6c8a99948e70ce02b601a0439782" + "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7c8ad9ce4faf6c8a99948e70ce02b601a0439782", - "reference": "7c8ad9ce4faf6c8a99948e70ce02b601a0439782", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", + "reference": "cfb7badd53bf4177f6e9416cfbbccc13c0e773a1", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<7.4", + "symfony/error-handler": "<7.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/error-handler": "^6.3|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/uid": "^5.4|^6.0|^7.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/console": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "twig/twig": "^3.12" }, "bin": [ "Resources/bin/var-dump-server" @@ -9615,7 +10416,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.36" + "source": "https://github.com/symfony/var-dumper/tree/v8.0.8" }, "funding": [ { @@ -9635,7 +10436,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:36:00+00:00" + "time": "2026-03-31T07:15:36+00:00" }, { "name": "symfony/var-exporter", @@ -9719,28 +10520,27 @@ }, { "name": "symfony/yaml", - "version": "v6.4.34", + "version": "v8.0.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f" + "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/7bca30dabed7900a08c5ad4f1d6483f881a64d0f", - "reference": "7bca30dabed7900a08c5ad4f1d6483f881a64d0f", + "url": "https://api.github.com/repos/symfony/yaml/zipball/54174ab48c0c0f9e21512b304be17f8150ccf8f1", + "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.4", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<7.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^7.4|^8.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -9771,7 +10571,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.34" + "source": "https://github.com/symfony/yaml/tree/v8.0.8" }, "funding": [ { @@ -9791,27 +10591,27 @@ "type": "tidelift" } ], - "time": "2026-02-06T18:32:11+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { "name": "theseer/tokenizer", - "version": "1.3.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4", + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.1" }, "type": "library", "autoload": { @@ -9833,7 +10633,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + "source": "https://github.com/theseer/tokenizer/tree/2.0.1" }, "funding": [ { @@ -9841,7 +10641,7 @@ "type": "github" } ], - "time": "2025-11-17T20:03:58+00:00" + "time": "2025-12-08T11:19:18+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -10058,23 +10858,23 @@ }, { "name": "webmozart/assert", - "version": "1.12.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/1b99650e7ffcad232624a260bc7fbdec2ffc407c", + "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c", "shasum": "" }, "require": { "ext-ctype": "*", "ext-date": "*", "ext-filter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.2" }, "suggest": { "ext-intl": "", @@ -10084,7 +10884,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-feature/2-0": "2.0-dev" } }, "autoload": { @@ -10100,6 +10900,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", @@ -10110,9 +10914,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.1" + "source": "https://github.com/webmozarts/assert/tree/2.2.0" }, - "time": "2025-10-29T15:56:20+00:00" + "time": "2026-04-09T16:54:47+00:00" } ], "aliases": [], @@ -10121,7 +10925,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.1" + "php": "^8.2" }, "platform-dev": {}, "plugin-api-version": "2.9.0" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 07a2ab376..3aaf3f160 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,13 +1,16 @@ - + executionOrder="random" + failOnWarning="false"> + src/ + + @@ -17,7 +20,6 @@ ./tests/ - diff --git a/src/Http/HttpClient.php b/src/Http/HttpClient.php index eff1f8b9e..1341fd221 100644 --- a/src/Http/HttpClient.php +++ b/src/Http/HttpClient.php @@ -5,7 +5,7 @@ use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\HandlerStack; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\ValueObjects\Interfaces\Strings\ByteArrayInterface; +use Hyperized\ValueObjects\Contracts\Strings\ByteArrayInterface; final class HttpClient implements HttpClientInterface { diff --git a/src/Interfaces/HttpClientInterface.php b/src/Interfaces/HttpClientInterface.php index 05830d8fe..b42e9196d 100644 --- a/src/Interfaces/HttpClientInterface.php +++ b/src/Interfaces/HttpClientInterface.php @@ -3,7 +3,7 @@ namespace Hyperized\Hostfact\Interfaces; use GuzzleHttp\ClientInterface; -use Hyperized\ValueObjects\Interfaces\Strings\ByteArrayInterface; +use Hyperized\ValueObjects\Contracts\Strings\ByteArrayInterface; interface HttpClientInterface { From c0c728bb75c079670d05b8a64d2024ce562e2e47 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 03:22:50 +0200 Subject: [PATCH 04/30] Update GitHub workflow actions and dependabot config - actions/checkout: v1 -> v4 - Remove deprecated --no-suggest flag and unnecessary composer self-update step - Add github-actions ecosystem to dependabot for automatic action updates - Use local PHPUnit XSD schema reference for infection compatibility --- .github/dependabot.yml | 6 ++++++ .github/workflows/main.yml | 7 ++----- phpunit.xml.dist | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index da755ec83..2efd5e5c0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,3 +7,9 @@ updates: interval: weekly time: "08:00" open-pull-requests-limit: 10 + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + time: "08:00" + open-pull-requests-limit: 5 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a582f6a5c..5582f3ea2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,19 +26,16 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: curl, json coverage: pcov - - name: Composer self-update - run: | - composer self-update - name: Composer update run: | - composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest + composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - name: Composer ${{ matrix.test }}-${{ matrix.os }} run: | composer ${{ matrix.test }} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3aaf3f160..0fa6cd9b9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ Date: Sat, 11 Apr 2026 03:23:37 +0200 Subject: [PATCH 05/30] Remove deprecated delete_head_branch from mergify config The delete_head_branch action is deprecated by Mergify (deadline: 2026-07-31). Use GitHub's native 'Automatically delete head branches' setting instead. Supersedes #339. --- .mergify.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 08ba0487f..57ec8225a 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -14,9 +14,3 @@ pull_request_rules: actions: merge: method: merge - - - name: delete head branch after merge - conditions: - - merged - actions: - delete_head_branch: From ada37bc2ea2fd3af876111bda1b31232a8ce4448 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:18:47 +0200 Subject: [PATCH 06/30] Update dependencies and drop PHP 8.2 from CI --- .github/workflows/main.yml | 1 - composer.json | 2 +- composer.lock | 16 ++++++++-------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5582f3ea2..15b5009c9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,6 @@ jobs: fail-fast: false matrix: php: - - 8.2 - 8.3 - 8.4 - 8.5 diff --git a/composer.json b/composer.json index 9ac31da94..0eb895809 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.2", + "php": "^8.3", "guzzlehttp/guzzle": "^7.5", "hyperized/value-objects": "^1.0.0", "thecodingmachine/safe": "^3.4" diff --git a/composer.lock b/composer.lock index 39df769ba..fbcf97d78 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bed4754e3bc0e593537b5ba01eed97d7", + "content-hash": "121e338838aba8893eb1079a8f89349b", "packages": [ { "name": "guzzlehttp/guzzle", @@ -334,16 +334,16 @@ }, { "name": "hyperized/value-objects", - "version": "v1.0.0", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/hyperized/value-objects.git", - "reference": "481fcde24adba424a7b9c8f6242f37075ea75c67" + "reference": "1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperized/value-objects/zipball/481fcde24adba424a7b9c8f6242f37075ea75c67", - "reference": "481fcde24adba424a7b9c8f6242f37075ea75c67", + "url": "https://api.github.com/repos/hyperized/value-objects/zipball/1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c", + "reference": "1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c", "shasum": "" }, "require": { @@ -373,9 +373,9 @@ "description": "A basic value objects collection", "support": { "issues": "https://github.com/hyperized/value-objects/issues", - "source": "https://github.com/hyperized/value-objects/tree/v1.0.0" + "source": "https://github.com/hyperized/value-objects/tree/v1.1.0" }, - "time": "2026-04-11T01:12:35+00:00" + "time": "2026-04-11T11:42:56+00:00" }, { "name": "psr/http-client", @@ -10925,7 +10925,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.2" + "php": "^8.3" }, "platform-dev": {}, "plugin-api-version": "2.9.0" From 42bf1306bfaf1e2f1cff342aa540518578b2118a Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:19:00 +0200 Subject: [PATCH 07/30] Add typed response system with DataBag, ApiResponse subclasses, and ResponseFactory --- src/Api/Response/ActionResponse.php | 7 ++ src/Api/Response/ApiResponse.php | 36 ++++++ src/Api/Response/DataBag.php | 180 +++++++++++++++++++++++++++ src/Api/Response/ErrorResponse.php | 21 ++++ src/Api/Response/ListResponse.php | 26 ++++ src/Api/Response/Pagination.php | 35 ++++++ src/Api/Response/ResponseFactory.php | 160 ++++++++++++++++++++++++ src/Api/Response/ShowResponse.php | 23 ++++ src/Api/Response/Status.php | 9 ++ 9 files changed, 497 insertions(+) create mode 100644 src/Api/Response/ActionResponse.php create mode 100644 src/Api/Response/ApiResponse.php create mode 100644 src/Api/Response/DataBag.php create mode 100644 src/Api/Response/ErrorResponse.php create mode 100644 src/Api/Response/ListResponse.php create mode 100644 src/Api/Response/Pagination.php create mode 100644 src/Api/Response/ResponseFactory.php create mode 100644 src/Api/Response/ShowResponse.php create mode 100644 src/Api/Response/Status.php diff --git a/src/Api/Response/ActionResponse.php b/src/Api/Response/ActionResponse.php new file mode 100644 index 000000000..848c7aa66 --- /dev/null +++ b/src/Api/Response/ActionResponse.php @@ -0,0 +1,7 @@ + $raw + */ + public function __construct( + public string $controller, + public string $action, + public Status $status, + public \DateTimeImmutable $date, + protected array $raw, + ) { + } + + public function isSuccess(): bool + { + return $this->status === Status::Success; + } + + public function isError(): bool + { + return $this->status === Status::Error; + } + + /** + * @return array + */ + public function toArray(): array + { + return $this->raw; + } +} diff --git a/src/Api/Response/DataBag.php b/src/Api/Response/DataBag.php new file mode 100644 index 000000000..512a09d7e --- /dev/null +++ b/src/Api/Response/DataBag.php @@ -0,0 +1,180 @@ + + */ +final readonly class DataBag implements \ArrayAccess, \Countable +{ + /** + * @param array $data + */ + public function __construct(private array $data) + { + } + + public function string(string $key): string + { + $value = $this->require($key); + + if (!is_scalar($value)) { + throw new \InvalidArgumentException("Field '{$key}' cannot be cast to string"); + } + + return (string) $value; + } + + public function int(string $key): int + { + $value = $this->require($key); + + if (!is_scalar($value)) { + throw new \InvalidArgumentException("Field '{$key}' cannot be cast to int"); + } + + return (int) $value; + } + + public function float(string $key): float + { + $value = $this->require($key); + + if (!is_scalar($value)) { + throw new \InvalidArgumentException("Field '{$key}' cannot be cast to float"); + } + + return (float) $value; + } + + public function bool(string $key): bool + { + $value = $this->require($key); + + return match ($value) { + 'yes', true, 1, '1' => true, + 'no', false, 0, '0' => false, + default => throw new \InvalidArgumentException( + "Field '{$key}' cannot be cast to bool, got: " . var_export($value, true) + ), + }; + } + + public function nullableString(string $key): ?string + { + $value = $this->data[$key] ?? null; + + if ($value === null) { + return null; + } + + if (!is_scalar($value)) { + throw new \InvalidArgumentException("Field '{$key}' cannot be cast to string"); + } + + return (string) $value; + } + + public function nullableInt(string $key): ?int + { + $value = $this->data[$key] ?? null; + + if ($value === null) { + return null; + } + + if (!is_scalar($value)) { + throw new \InvalidArgumentException("Field '{$key}' cannot be cast to int"); + } + + return (int) $value; + } + + /** + * @return array + */ + public function array(string $key): array + { + $value = $this->require($key); + + if (!is_array($value)) { + throw new \InvalidArgumentException("Field '{$key}' is not an array"); + } + + /** @var array $value */ + return $value; + } + + public function bag(string $key): self + { + return new self($this->array($key)); + } + + /** + * @return list + */ + public function bags(string $key): array + { + $items = $this->array($key); + + /** @var list $result */ + $result = []; + foreach ($items as $item) { + if (is_array($item)) { + /** @var array $item */ + $result[] = new self($item); + } + } + + return $result; + } + + public function has(string $key): bool + { + return array_key_exists($key, $this->data); + } + + /** + * @return array + */ + public function toArray(): array + { + return $this->data; + } + + public function offsetExists(mixed $offset): bool + { + return $this->has((string) $offset); + } + + public function offsetGet(mixed $offset): mixed + { + return $this->data[$offset] ?? null; + } + + public function offsetSet(mixed $offset, mixed $value): never + { + throw new \LogicException('DataBag is immutable'); + } + + public function offsetUnset(mixed $offset): never + { + throw new \LogicException('DataBag is immutable'); + } + + public function count(): int + { + return count($this->data); + } + + private function require(string $key): mixed + { + if (!$this->has($key)) { + throw new \InvalidArgumentException("Required field '{$key}' is missing"); + } + + return $this->data[$key]; + } +} diff --git a/src/Api/Response/ErrorResponse.php b/src/Api/Response/ErrorResponse.php new file mode 100644 index 000000000..56fb4c96a --- /dev/null +++ b/src/Api/Response/ErrorResponse.php @@ -0,0 +1,21 @@ + $errors + * @param array $raw + */ + public function __construct( + string $controller, + string $action, + Status $status, + \DateTimeImmutable $date, + public array $errors, + array $raw, + ) { + parent::__construct($controller, $action, $status, $date, $raw); + } +} diff --git a/src/Api/Response/ListResponse.php b/src/Api/Response/ListResponse.php new file mode 100644 index 000000000..8b464d53c --- /dev/null +++ b/src/Api/Response/ListResponse.php @@ -0,0 +1,26 @@ + $items + * @param list $entities + * @param array $raw + */ + public function __construct( + string $controller, + string $action, + Status $status, + \DateTimeImmutable $date, + public Pagination $pagination, + public array $items, + public array $entities, + array $raw, + ) { + parent::__construct($controller, $action, $status, $date, $raw); + } +} diff --git a/src/Api/Response/Pagination.php b/src/Api/Response/Pagination.php new file mode 100644 index 000000000..89c75f56b --- /dev/null +++ b/src/Api/Response/Pagination.php @@ -0,0 +1,35 @@ + $data + */ + public static function fromArray(array $data): self + { + $totalResults = $data['totalresults'] ?? 0; + $currentResults = $data['currentresults'] ?? 0; + $offset = $data['offset'] ?? 0; + + return new self( + totalResults: is_int($totalResults) + ? $totalResults + : (int) (is_scalar($totalResults) ? $totalResults : 0), + currentResults: is_int($currentResults) + ? $currentResults + : (int) (is_scalar($currentResults) ? $currentResults : 0), + offset: is_int($offset) + ? $offset + : (int) (is_scalar($offset) ? $offset : 0), + ); + } +} diff --git a/src/Api/Response/ResponseFactory.php b/src/Api/Response/ResponseFactory.php new file mode 100644 index 000000000..01ef658cc --- /dev/null +++ b/src/Api/Response/ResponseFactory.php @@ -0,0 +1,160 @@ + + */ + private const SINGULAR_KEYS = [ + 'product' => 'product', + 'invoice' => 'invoice', + 'debtor' => 'debtor', + 'domain' => 'domain', + 'hosting' => 'hosting', + 'service' => 'service', + 'ssl' => 'ssl', + 'vps' => 'vps', + 'ticket' => 'ticket', + 'order' => 'order', + 'pricequote' => 'pricequote', + 'creditor' => 'creditor', + 'creditinvoice' => 'creditinvoice', + 'group' => 'group', + 'handle' => 'handle', + ]; + + /** + * @var array + */ + private const PLURAL_KEYS = [ + 'product' => 'products', + 'invoice' => 'invoices', + 'debtor' => 'debtors', + 'domain' => 'domains', + 'hosting' => 'hostings', + 'service' => 'services', + 'ssl' => 'ssls', + 'vps' => 'vpses', + 'ticket' => 'tickets', + 'order' => 'orders', + 'pricequote' => 'pricequotes', + 'creditor' => 'creditors', + 'creditinvoice' => 'creditinvoices', + 'group' => 'groups', + 'handle' => 'handles', + ]; + + /** + * @param array $data + */ + public static function fromArray(array $data): ApiResponse + { + $controller = self::extractString($data, 'controller', 'unknown'); + $action = self::extractString($data, 'action', 'unknown'); + $status = Status::tryFrom( + self::extractString($data, 'status', '') + ) ?? Status::Error; + $date = new \DateTimeImmutable( + self::extractString($data, 'date', 'now') + ); + + if ($status === Status::Error) { + return new ErrorResponse( + $controller, + $action, + $status, + $date, + self::extractErrors($data), + $data, + ); + } + + $pluralKey = self::PLURAL_KEYS[$controller] ?? null; + if ($pluralKey !== null) { + $pluralData = $data[$pluralKey] ?? null; + if (is_array($pluralData)) { + /** @var list $items */ + $items = []; + $entities = []; + foreach ($pluralData as $item) { + if (is_array($item)) { + /** @var array $item */ + $bag = new DataBag($item); + $items[] = $bag; + $entities[] = EntityFactory::fromBag($controller, $bag); + } + } + + return new ListResponse( + $controller, + $action, + $status, + $date, + Pagination::fromArray($data), + $items, + $entities, + $data, + ); + } + } + + $singularKey = self::SINGULAR_KEYS[$controller] ?? null; + if ($singularKey !== null) { + $singularData = $data[$singularKey] ?? null; + if (is_array($singularData)) { + /** @var array $entityData */ + $entityData = $singularData; + $bag = new DataBag($entityData); + + return new ShowResponse( + $controller, + $action, + $status, + $date, + $bag, + EntityFactory::fromBag($controller, $bag), + $data, + ); + } + } + + return new ActionResponse($controller, $action, $status, $date, $data); + } + + /** + * @param array $data + */ + private static function extractString( + array $data, + string $key, + string $default + ): string { + $value = $data[$key] ?? null; + + return is_string($value) ? $value : $default; + } + + /** + * @param array $data + * @return list + */ + private static function extractErrors(array $data): array + { + $raw = $data['errors'] ?? []; + + /** @var list $errors */ + $errors = []; + + if (is_array($raw)) { + foreach ($raw as $error) { + $errors[] = is_scalar($error) ? (string) $error : ''; + } + } + + return $errors; + } +} diff --git a/src/Api/Response/ShowResponse.php b/src/Api/Response/ShowResponse.php new file mode 100644 index 000000000..40e779e2e --- /dev/null +++ b/src/Api/Response/ShowResponse.php @@ -0,0 +1,23 @@ + $raw + */ + public function __construct( + string $controller, + string $action, + Status $status, + \DateTimeImmutable $date, + public DataBag $data, + public Entity|DataBag $entity, + array $raw, + ) { + parent::__construct($controller, $action, $status, $date, $raw); + } +} diff --git a/src/Api/Response/Status.php b/src/Api/Response/Status.php new file mode 100644 index 000000000..2051163b1 --- /dev/null +++ b/src/Api/Response/Status.php @@ -0,0 +1,9 @@ + Date: Sat, 11 Apr 2026 16:19:08 +0200 Subject: [PATCH 08/30] Refactor API layer to return typed responses --- src/Api/Api.php | 63 ++++-------- src/Api/Capabilities/CanAccept.php | 6 +- src/Api/Capabilities/CanAdd.php | 6 +- src/Api/Capabilities/CanAddAttachment.php | 6 +- src/Api/Capabilities/CanAddLine.php | 8 +- src/Api/Capabilities/CanAddMessage.php | 8 +- src/Api/Capabilities/CanAutoRenew.php | 8 +- src/Api/Capabilities/CanBlock.php | 6 +- src/Api/Capabilities/CanCancelSchedule.php | 8 +- src/Api/Capabilities/CanChangeNameserver.php | 8 +- src/Api/Capabilities/CanChangeOwner.php | 8 +- src/Api/Capabilities/CanChangeStatus.php | 8 +- src/Api/Capabilities/CanCheck.php | 6 +- src/Api/Capabilities/CanCheckLogin.php | 8 +- src/Api/Capabilities/CanCreate.php | 6 +- src/Api/Capabilities/CanCredit.php | 6 +- src/Api/Capabilities/CanDecline.php | 6 +- src/Api/Capabilities/CanDelete.php | 6 +- src/Api/Capabilities/CanDeleteAttachment.php | 6 +- src/Api/Capabilities/CanDeleteLine.php | 8 +- src/Api/Capabilities/CanDownload.php | 6 +- .../Capabilities/CanDownloadAccountData.php | 6 +- .../Capabilities/CanDownloadAttachment.php | 6 +- src/Api/Capabilities/CanEdit.php | 6 +- src/Api/Capabilities/CanEditDnsZone.php | 8 +- src/Api/Capabilities/CanEditWhois.php | 8 +- src/Api/Capabilities/CanEmailAccountData.php | 6 +- src/Api/Capabilities/CanEmailAccountInfo.php | 6 +- src/Api/Capabilities/CanGeneratePdf.php | 8 +- src/Api/Capabilities/CanGetDnsZone.php | 8 +- src/Api/Capabilities/CanGetDomainList.php | 8 +- src/Api/Capabilities/CanGetStatus.php | 8 +- src/Api/Capabilities/CanGetToken.php | 8 +- src/Api/Capabilities/CanList.php | 6 +- src/Api/Capabilities/CanListDnsTemplates.php | 8 +- src/Api/Capabilities/CanListDomain.php | 8 +- src/Api/Capabilities/CanLock.php | 6 +- src/Api/Capabilities/CanMarkAsInstalled.php | 6 +- src/Api/Capabilities/CanMarkAsPaid.php | 8 +- src/Api/Capabilities/CanMarkAsUninstalled.php | 6 +- src/Api/Capabilities/CanMarkAsUnpaid.php | 8 +- src/Api/Capabilities/CanPause.php | 6 +- src/Api/Capabilities/CanPayPartial.php | 6 +- .../Capabilities/CanPaymentProcessPause.php | 6 +- .../CanPaymentProcessReactivate.php | 6 +- src/Api/Capabilities/CanProcess.php | 6 +- src/Api/Capabilities/CanRegister.php | 6 +- src/Api/Capabilities/CanReissue.php | 6 +- src/Api/Capabilities/CanRemoveFromServer.php | 8 +- src/Api/Capabilities/CanRenew.php | 6 +- src/Api/Capabilities/CanRequest.php | 6 +- .../Capabilities/CanResendApproverEmail.php | 6 +- src/Api/Capabilities/CanRestart.php | 6 +- src/Api/Capabilities/CanRevoke.php | 6 +- src/Api/Capabilities/CanSchedule.php | 6 +- src/Api/Capabilities/CanSendByEmail.php | 8 +- src/Api/Capabilities/CanSendEmail.php | 8 +- .../Capabilities/CanSendReminderByEmail.php | 8 +- .../Capabilities/CanSendSummationByEmail.php | 8 +- src/Api/Capabilities/CanShow.php | 6 +- src/Api/Capabilities/CanStart.php | 6 +- src/Api/Capabilities/CanSuspend.php | 6 +- src/Api/Capabilities/CanSyncWhois.php | 8 +- src/Api/Capabilities/CanTerminate.php | 6 +- src/Api/Capabilities/CanTransfer.php | 6 +- src/Api/Capabilities/CanUnblock.php | 6 +- src/Api/Capabilities/CanUnlock.php | 6 +- src/Api/Capabilities/CanUnsuspend.php | 6 +- src/Api/Capabilities/CanUpDowngrade.php | 8 +- .../CanUpdateLoginCredentials.php | 8 +- src/Api/Controllers/CreditInvoice.php | 2 +- src/Api/Controllers/Creditor.php | 2 +- src/Api/Controllers/Debtor.php | 2 +- src/Api/Controllers/Domain.php | 2 +- src/Api/Controllers/Group.php | 2 +- src/Api/Controllers/Handle.php | 2 +- src/Api/Controllers/Hosting.php | 2 +- src/Api/Controllers/Invoice.php | 2 +- src/Api/Controllers/Order.php | 2 +- src/Api/Controllers/PriceQuote.php | 2 +- src/Api/Controllers/Product.php | 2 +- src/Api/Controllers/Service.php | 2 +- src/Api/Controllers/Ssl.php | 2 +- src/Api/Controllers/Ticket.php | 2 +- src/Api/Controllers/Vps.php | 2 +- src/Exceptions/InvalidArgumentException.php | 5 - src/HostfactFacade.php | 5 - src/Http/HttpClient.php | 33 +++---- src/Interfaces/ApiInterface.php | 6 +- src/Interfaces/CreditInvoiceInterface.php | 50 +++++----- src/Interfaces/CreditorInterface.php | 34 ++++--- src/Interfaces/DebtorInterface.php | 46 ++++----- src/Interfaces/DomainInterface.php | 78 ++++++++------- src/Interfaces/GroupInterface.php | 22 +++-- src/Interfaces/HandleInterface.php | 26 ++--- src/Interfaces/HostingInterface.php | 54 +++++----- src/Interfaces/HttpClientInterface.php | 4 +- src/Interfaces/InvoiceInterface.php | 98 ++++++++++--------- src/Interfaces/OrderInterface.php | 30 +++--- src/Interfaces/PriceQuoteInterface.php | 58 +++++------ src/Interfaces/ProductInterface.php | 22 +++-- src/Interfaces/ServiceInterface.php | 22 +++-- src/Interfaces/SslInterface.php | 58 +++++------ src/Interfaces/TicketInterface.php | 38 +++---- src/Interfaces/VpsInterface.php | 54 +++++----- src/Providers/HostfactServiceProvider.php | 15 +-- src/Types/FormParameter.php | 10 +- src/Types/Url.php | 18 ---- 108 files changed, 723 insertions(+), 626 deletions(-) delete mode 100644 src/Types/Url.php diff --git a/src/Api/Api.php b/src/Api/Api.php index 64525cb3e..06e214798 100644 --- a/src/Api/Api.php +++ b/src/Api/Api.php @@ -6,6 +6,10 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Utils; use Hyperized\Hostfact\Exceptions\InvalidArgumentException; +use Hyperized\Hostfact\Api\Response\ApiResponse; +use Hyperized\Hostfact\Api\Response\ErrorResponse; +use Hyperized\Hostfact\Api\Response\ResponseFactory; +use Hyperized\Hostfact\Api\Response\Status; use Hyperized\Hostfact\Interfaces\ApiInterface; use Hyperized\Hostfact\Interfaces\FormParameterInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; @@ -16,35 +20,16 @@ abstract class Api implements ApiInterface { - private HttpClientInterface $httpClient; - protected function __construct( - HttpClientInterface $httpClient + private readonly HttpClientInterface $httpClient ) { - $this->httpClient = $httpClient; } - /** - * @return RequestInterface - * - * uri will be filled in with HTTPClient uri - * Body will be empty as this client only sends form parameters via POST - */ public static function getRequest(): RequestInterface { return new Request('POST', '', [], Utils::streamFor()); } - /** - * @param HttpClientInterface $client - * @param RequestInterface $request - * @param FormParameterInterface $formParameter - * @param string $controller - * @param string $action - * @return ResponseInterface - * - * This method slipstreams the api_key and controller information into the form parameters - */ public static function getResponse( HttpClientInterface $client, RequestInterface $request, @@ -58,14 +43,12 @@ public static function getResponse( ->send( $request, [ - 'form_params' => array_merge( - $formParameter->toArray(), - [ - 'api_key' => config('Hostfact.api_v2_key'), - 'controller' => $controller, - 'action' => $action, - ] - ), + 'form_params' => [ + ...$formParameter->toArray(), + 'api_key' => config('Hostfact.api_v2_key'), + 'controller' => $controller, + 'action' => $action, + ], ] ); } catch (GuzzleException $exception) { @@ -86,12 +69,9 @@ public function getHttpClient(): HttpClientInterface } /** - * @param string $controller - * @param string $action * @param array $input - * @return array */ - public function sendRequest(string $controller, string $action, array $input): array + public function sendRequest(string $controller, string $action, array $input): ApiResponse { try { /** @@ -110,18 +90,17 @@ public function sendRequest(string $controller, string $action, array $input): a true ); } catch (JsonException $exception) { - $result = [ - 'controller' => 'invalid', - 'action' => 'invalid', - 'status' => 'error', - 'date' => date('c'), - 'errors' => [ - $exception->getMessage() - ] - ]; + return new ErrorResponse( + 'invalid', + 'invalid', + Status::Error, + new \DateTimeImmutable(), + [$exception->getMessage()], + [], + ); } - return $result; + return ResponseFactory::fromArray($result); } public static function getUrlFromConfig(): string diff --git a/src/Api/Capabilities/CanAccept.php b/src/Api/Capabilities/CanAccept.php index f052598f0..b6b68e19e 100644 --- a/src/Api/Capabilities/CanAccept.php +++ b/src/Api/Capabilities/CanAccept.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAccept { /** * @param array $input - * @return array + * @return ApiResponse */ - public function accept(array $input): array + public function accept(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanAdd.php b/src/Api/Capabilities/CanAdd.php index ff761895a..4ed252078 100644 --- a/src/Api/Capabilities/CanAdd.php +++ b/src/Api/Capabilities/CanAdd.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAdd { /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array + public function add(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanAddAttachment.php b/src/Api/Capabilities/CanAddAttachment.php index 0fd604547..af58e51a2 100644 --- a/src/Api/Capabilities/CanAddAttachment.php +++ b/src/Api/Capabilities/CanAddAttachment.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAddAttachment { /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array + public function attachmentAdd(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanAddLine.php b/src/Api/Capabilities/CanAddLine.php index a55de6c82..7a31975c0 100644 --- a/src/Api/Capabilities/CanAddLine.php +++ b/src/Api/Capabilities/CanAddLine.php @@ -2,17 +2,19 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAddLine { /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineAdd(array $input): array + public function lineAdd(array $input): ApiResponse { return $this ->sendRequest( - mb_strtolower(self::$name) . 'line', + self::$name . 'line', 'add', $input ); diff --git a/src/Api/Capabilities/CanAddMessage.php b/src/Api/Capabilities/CanAddMessage.php index 1d489b11c..3a17d500d 100644 --- a/src/Api/Capabilities/CanAddMessage.php +++ b/src/Api/Capabilities/CanAddMessage.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAddMessage { /** * @param array $input - * @return array + * @return ApiResponse */ - public function addMessage(array $input): array + public function addMessage(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanAutoRenew.php b/src/Api/Capabilities/CanAutoRenew.php index 8541ed01c..07c12091e 100644 --- a/src/Api/Capabilities/CanAutoRenew.php +++ b/src/Api/Capabilities/CanAutoRenew.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanAutoRenew { /** * @param array $input - * @return array + * @return ApiResponse */ - public function autoRenew(array $input): array + public function autoRenew(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanBlock.php b/src/Api/Capabilities/CanBlock.php index 5e4d43d67..0498b9c98 100644 --- a/src/Api/Capabilities/CanBlock.php +++ b/src/Api/Capabilities/CanBlock.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanBlock { /** * @param array $input - * @return array + * @return ApiResponse */ - public function block(array $input): array + public function block(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanCancelSchedule.php b/src/Api/Capabilities/CanCancelSchedule.php index b493de717..ee5f1f727 100644 --- a/src/Api/Capabilities/CanCancelSchedule.php +++ b/src/Api/Capabilities/CanCancelSchedule.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanCancelSchedule { /** * @param array $input - * @return array + * @return ApiResponse */ - public function cancelSchedule(array $input): array + public function cancelSchedule(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanChangeNameserver.php b/src/Api/Capabilities/CanChangeNameserver.php index 02042f60f..028f4c34d 100644 --- a/src/Api/Capabilities/CanChangeNameserver.php +++ b/src/Api/Capabilities/CanChangeNameserver.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanChangeNameserver { /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeNameserver(array $input): array + public function changeNameserver(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanChangeOwner.php b/src/Api/Capabilities/CanChangeOwner.php index 09c2c9ff5..4d53e5c30 100644 --- a/src/Api/Capabilities/CanChangeOwner.php +++ b/src/Api/Capabilities/CanChangeOwner.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanChangeOwner { /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeOwner(array $input): array + public function changeOwner(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanChangeStatus.php b/src/Api/Capabilities/CanChangeStatus.php index cde49b79a..2ce1bd9bf 100644 --- a/src/Api/Capabilities/CanChangeStatus.php +++ b/src/Api/Capabilities/CanChangeStatus.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanChangeStatus { /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeStatus(array $input): array + public function changeStatus(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanCheck.php b/src/Api/Capabilities/CanCheck.php index f67d9185d..532ce88c5 100644 --- a/src/Api/Capabilities/CanCheck.php +++ b/src/Api/Capabilities/CanCheck.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanCheck { /** * @param array $input - * @return array + * @return ApiResponse */ - public function check(array $input): array + public function check(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanCheckLogin.php b/src/Api/Capabilities/CanCheckLogin.php index d0239591d..fea272092 100644 --- a/src/Api/Capabilities/CanCheckLogin.php +++ b/src/Api/Capabilities/CanCheckLogin.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanCheckLogin { /** * @param array $input - * @return array + * @return ApiResponse */ - public function checkLogin(array $input): array + public function checkLogin(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanCreate.php b/src/Api/Capabilities/CanCreate.php index bccc3e541..a2861d139 100644 --- a/src/Api/Capabilities/CanCreate.php +++ b/src/Api/Capabilities/CanCreate.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanCreate { /** * @param array $input - * @return array + * @return ApiResponse */ - public function create(array $input): array + public function create(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanCredit.php b/src/Api/Capabilities/CanCredit.php index 85a706680..ecaddc2e0 100644 --- a/src/Api/Capabilities/CanCredit.php +++ b/src/Api/Capabilities/CanCredit.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanCredit { /** * @param array $input - * @return array + * @return ApiResponse */ - public function credit(array $input): array + public function credit(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDecline.php b/src/Api/Capabilities/CanDecline.php index 46b08c51f..083a99657 100644 --- a/src/Api/Capabilities/CanDecline.php +++ b/src/Api/Capabilities/CanDecline.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDecline { /** * @param array $input - * @return array + * @return ApiResponse */ - public function decline(array $input): array + public function decline(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDelete.php b/src/Api/Capabilities/CanDelete.php index 39a32fe03..c348be3b3 100644 --- a/src/Api/Capabilities/CanDelete.php +++ b/src/Api/Capabilities/CanDelete.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDelete { /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array + public function delete(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDeleteAttachment.php b/src/Api/Capabilities/CanDeleteAttachment.php index dd820d5f3..fd9abd476 100644 --- a/src/Api/Capabilities/CanDeleteAttachment.php +++ b/src/Api/Capabilities/CanDeleteAttachment.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDeleteAttachment { /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array + public function attachmentDelete(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDeleteLine.php b/src/Api/Capabilities/CanDeleteLine.php index 7d60a6856..137cdbb75 100644 --- a/src/Api/Capabilities/CanDeleteLine.php +++ b/src/Api/Capabilities/CanDeleteLine.php @@ -2,17 +2,19 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDeleteLine { /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineDelete(array $input): array + public function lineDelete(array $input): ApiResponse { return $this ->sendRequest( - mb_strtolower(self::$name) . 'line', + self::$name . 'line', 'delete', $input ); diff --git a/src/Api/Capabilities/CanDownload.php b/src/Api/Capabilities/CanDownload.php index 3eb38e191..f50328c77 100644 --- a/src/Api/Capabilities/CanDownload.php +++ b/src/Api/Capabilities/CanDownload.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDownload { /** * @param array $input - * @return array + * @return ApiResponse */ - public function download(array $input): array + public function download(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDownloadAccountData.php b/src/Api/Capabilities/CanDownloadAccountData.php index 86a07665c..3d50f6e18 100644 --- a/src/Api/Capabilities/CanDownloadAccountData.php +++ b/src/Api/Capabilities/CanDownloadAccountData.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDownloadAccountData { /** * @param array $input - * @return array + * @return ApiResponse */ - public function downloadAccountData(array $input): array + public function downloadAccountData(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanDownloadAttachment.php b/src/Api/Capabilities/CanDownloadAttachment.php index b4f78b8c4..8de977b77 100644 --- a/src/Api/Capabilities/CanDownloadAttachment.php +++ b/src/Api/Capabilities/CanDownloadAttachment.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanDownloadAttachment { /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array + public function attachmentDownload(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanEdit.php b/src/Api/Capabilities/CanEdit.php index 18dfdadf7..8df60bea4 100644 --- a/src/Api/Capabilities/CanEdit.php +++ b/src/Api/Capabilities/CanEdit.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanEdit { /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array + public function edit(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanEditDnsZone.php b/src/Api/Capabilities/CanEditDnsZone.php index 8235416ea..7154dd73b 100644 --- a/src/Api/Capabilities/CanEditDnsZone.php +++ b/src/Api/Capabilities/CanEditDnsZone.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanEditDnsZone { /** * @param array $input - * @return array + * @return ApiResponse */ - public function editDnsZone(array $input): array + public function editDnsZone(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanEditWhois.php b/src/Api/Capabilities/CanEditWhois.php index 4b9945924..0a82fac2b 100644 --- a/src/Api/Capabilities/CanEditWhois.php +++ b/src/Api/Capabilities/CanEditWhois.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanEditWhois { /** * @param array $input - * @return array + * @return ApiResponse */ - public function editWhois(array $input): array + public function editWhois(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanEmailAccountData.php b/src/Api/Capabilities/CanEmailAccountData.php index 31f54ec9b..f16341561 100644 --- a/src/Api/Capabilities/CanEmailAccountData.php +++ b/src/Api/Capabilities/CanEmailAccountData.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanEmailAccountData { /** * @param array $input - * @return array + * @return ApiResponse */ - public function emailAccountData(array $input): array + public function emailAccountData(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanEmailAccountInfo.php b/src/Api/Capabilities/CanEmailAccountInfo.php index ad12d2636..18ab1488a 100644 --- a/src/Api/Capabilities/CanEmailAccountInfo.php +++ b/src/Api/Capabilities/CanEmailAccountInfo.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanEmailAccountInfo { /** * @param array $input - * @return array + * @return ApiResponse */ - public function emailAccountData(array $input): array + public function emailAccountData(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanGeneratePdf.php b/src/Api/Capabilities/CanGeneratePdf.php index 9b2429cf0..c265a37a9 100644 --- a/src/Api/Capabilities/CanGeneratePdf.php +++ b/src/Api/Capabilities/CanGeneratePdf.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanGeneratePdf { /** * @param array $input - * @return array + * @return ApiResponse */ - public function generatePdf(array $input): array + public function generatePdf(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanGetDnsZone.php b/src/Api/Capabilities/CanGetDnsZone.php index 51c8770b3..62ec26be3 100644 --- a/src/Api/Capabilities/CanGetDnsZone.php +++ b/src/Api/Capabilities/CanGetDnsZone.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanGetDnsZone { /** * @param array $input - * @return array + * @return ApiResponse */ - public function getDnsZone(array $input): array + public function getDnsZone(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanGetDomainList.php b/src/Api/Capabilities/CanGetDomainList.php index a891091d1..eb2563180 100644 --- a/src/Api/Capabilities/CanGetDomainList.php +++ b/src/Api/Capabilities/CanGetDomainList.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanGetDomainList { /** * @param array $input - * @return array + * @return ApiResponse */ - public function getDomainList(array $input): array + public function getDomainList(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanGetStatus.php b/src/Api/Capabilities/CanGetStatus.php index 9b432df98..83bed5e49 100644 --- a/src/Api/Capabilities/CanGetStatus.php +++ b/src/Api/Capabilities/CanGetStatus.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanGetStatus { /** * @param array $input - * @return array + * @return ApiResponse */ - public function getStatus(array $input): array + public function getStatus(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanGetToken.php b/src/Api/Capabilities/CanGetToken.php index d74bfbe17..f392854c6 100644 --- a/src/Api/Capabilities/CanGetToken.php +++ b/src/Api/Capabilities/CanGetToken.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanGetToken { /** * @param array $input - * @return array + * @return ApiResponse */ - public function getToken(array $input): array + public function getToken(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanList.php b/src/Api/Capabilities/CanList.php index 110f92906..5cb706085 100644 --- a/src/Api/Capabilities/CanList.php +++ b/src/Api/Capabilities/CanList.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanList { /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array + public function list(array $input = []): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanListDnsTemplates.php b/src/Api/Capabilities/CanListDnsTemplates.php index 0db1b4176..68543d819 100644 --- a/src/Api/Capabilities/CanListDnsTemplates.php +++ b/src/Api/Capabilities/CanListDnsTemplates.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanListDnsTemplates { /** * @param array $input - * @return array + * @return ApiResponse */ - public function listDnsTemplates(array $input): array + public function listDnsTemplates(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanListDomain.php b/src/Api/Capabilities/CanListDomain.php index 09ba71523..3ab9e16af 100644 --- a/src/Api/Capabilities/CanListDomain.php +++ b/src/Api/Capabilities/CanListDomain.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanListDomain { /** * @param array $input - * @return array + * @return ApiResponse */ - public function listDomain(array $input): array + public function listDomain(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanLock.php b/src/Api/Capabilities/CanLock.php index 5dc5e2d35..bfa108e50 100644 --- a/src/Api/Capabilities/CanLock.php +++ b/src/Api/Capabilities/CanLock.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanLock { /** * @param array $input - * @return array + * @return ApiResponse */ - public function lock(array $input): array + public function lock(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanMarkAsInstalled.php b/src/Api/Capabilities/CanMarkAsInstalled.php index fa39721a2..b124e7d31 100644 --- a/src/Api/Capabilities/CanMarkAsInstalled.php +++ b/src/Api/Capabilities/CanMarkAsInstalled.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanMarkAsInstalled { /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsInstalled(array $input): array + public function markAsInstalled(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanMarkAsPaid.php b/src/Api/Capabilities/CanMarkAsPaid.php index e8921f3ad..78615c4cf 100644 --- a/src/Api/Capabilities/CanMarkAsPaid.php +++ b/src/Api/Capabilities/CanMarkAsPaid.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanMarkAsPaid { /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsPaid(array $input): array + public function markAsPaid(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanMarkAsUninstalled.php b/src/Api/Capabilities/CanMarkAsUninstalled.php index 487e714b7..068247f52 100644 --- a/src/Api/Capabilities/CanMarkAsUninstalled.php +++ b/src/Api/Capabilities/CanMarkAsUninstalled.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanMarkAsUninstalled { /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsUninstalled(array $input): array + public function markAsUninstalled(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanMarkAsUnpaid.php b/src/Api/Capabilities/CanMarkAsUnpaid.php index d68f85bec..78bf1fc19 100644 --- a/src/Api/Capabilities/CanMarkAsUnpaid.php +++ b/src/Api/Capabilities/CanMarkAsUnpaid.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanMarkAsUnpaid { /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsUnpaid(array $input): array + public function markAsUnpaid(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanPause.php b/src/Api/Capabilities/CanPause.php index e11dd8c9b..31853fa96 100644 --- a/src/Api/Capabilities/CanPause.php +++ b/src/Api/Capabilities/CanPause.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanPause { /** * @param array $input - * @return array + * @return ApiResponse */ - public function pause(array $input): array + public function pause(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanPayPartial.php b/src/Api/Capabilities/CanPayPartial.php index 726f521aa..ea8e999d9 100644 --- a/src/Api/Capabilities/CanPayPartial.php +++ b/src/Api/Capabilities/CanPayPartial.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanPayPartial { /** * @param array $input - * @return array + * @return ApiResponse */ - public function partialPayment(array $input): array + public function partialPayment(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanPaymentProcessPause.php b/src/Api/Capabilities/CanPaymentProcessPause.php index 797d26fe2..4b39cf5c5 100644 --- a/src/Api/Capabilities/CanPaymentProcessPause.php +++ b/src/Api/Capabilities/CanPaymentProcessPause.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanPaymentProcessPause { /** * @param array $input - * @return array + * @return ApiResponse */ - public function paymentProcessPause(array $input): array + public function paymentProcessPause(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanPaymentProcessReactivate.php b/src/Api/Capabilities/CanPaymentProcessReactivate.php index 98586a504..c6f1b7731 100644 --- a/src/Api/Capabilities/CanPaymentProcessReactivate.php +++ b/src/Api/Capabilities/CanPaymentProcessReactivate.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanPaymentProcessReactivate { /** * @param array $input - * @return array + * @return ApiResponse */ - public function paymentProcessReactivate(array $input): array + public function paymentProcessReactivate(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanProcess.php b/src/Api/Capabilities/CanProcess.php index 21a12d5a6..bf1ccfcfc 100644 --- a/src/Api/Capabilities/CanProcess.php +++ b/src/Api/Capabilities/CanProcess.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanProcess { /** * @param array $input - * @return array + * @return ApiResponse */ - public function process(array $input): array + public function process(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanRegister.php b/src/Api/Capabilities/CanRegister.php index 3d6302fca..4975788af 100644 --- a/src/Api/Capabilities/CanRegister.php +++ b/src/Api/Capabilities/CanRegister.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRegister { /** * @param array $input - * @return array + * @return ApiResponse */ - public function register(array $input): array + public function register(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanReissue.php b/src/Api/Capabilities/CanReissue.php index fad1fc66d..dbe650d8e 100644 --- a/src/Api/Capabilities/CanReissue.php +++ b/src/Api/Capabilities/CanReissue.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanReissue { /** * @param array $input - * @return array + * @return ApiResponse */ - public function reissue(array $input): array + public function reissue(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanRemoveFromServer.php b/src/Api/Capabilities/CanRemoveFromServer.php index d726701c2..92b6098e2 100644 --- a/src/Api/Capabilities/CanRemoveFromServer.php +++ b/src/Api/Capabilities/CanRemoveFromServer.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRemoveFromServer { /** * @param array $input - * @return array + * @return ApiResponse */ - public function removeFromServer(array $input): array + public function removeFromServer(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanRenew.php b/src/Api/Capabilities/CanRenew.php index e654dbedc..4066c02d3 100644 --- a/src/Api/Capabilities/CanRenew.php +++ b/src/Api/Capabilities/CanRenew.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRenew { /** * @param array $input - * @return array + * @return ApiResponse */ - public function renew(array $input): array + public function renew(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanRequest.php b/src/Api/Capabilities/CanRequest.php index 569b5257a..9cb3970c1 100644 --- a/src/Api/Capabilities/CanRequest.php +++ b/src/Api/Capabilities/CanRequest.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRequest { /** * @param array $input - * @return array + * @return ApiResponse */ - public function request(array $input): array + public function request(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanResendApproverEmail.php b/src/Api/Capabilities/CanResendApproverEmail.php index 882576994..f4d618484 100644 --- a/src/Api/Capabilities/CanResendApproverEmail.php +++ b/src/Api/Capabilities/CanResendApproverEmail.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanResendApproverEmail { /** * @param array $input - * @return array + * @return ApiResponse */ - public function resendApproverEmail(array $input): array + public function resendApproverEmail(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanRestart.php b/src/Api/Capabilities/CanRestart.php index e3c654fcf..4739ab014 100644 --- a/src/Api/Capabilities/CanRestart.php +++ b/src/Api/Capabilities/CanRestart.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRestart { /** * @param array $input - * @return array + * @return ApiResponse */ - public function restart(array $input): array + public function restart(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanRevoke.php b/src/Api/Capabilities/CanRevoke.php index 5611cbe7e..05040a334 100644 --- a/src/Api/Capabilities/CanRevoke.php +++ b/src/Api/Capabilities/CanRevoke.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanRevoke { /** * @param array $input - * @return array + * @return ApiResponse */ - public function revoke(array $input): array + public function revoke(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanSchedule.php b/src/Api/Capabilities/CanSchedule.php index cdaa226c3..5cc051ad4 100644 --- a/src/Api/Capabilities/CanSchedule.php +++ b/src/Api/Capabilities/CanSchedule.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSchedule { /** * @param array $input - * @return array + * @return ApiResponse */ - public function schedule(array $input): array + public function schedule(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanSendByEmail.php b/src/Api/Capabilities/CanSendByEmail.php index 1885a80b7..04201b66b 100644 --- a/src/Api/Capabilities/CanSendByEmail.php +++ b/src/Api/Capabilities/CanSendByEmail.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSendByEmail { /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendByEmail(array $input): array + public function sendByEmail(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanSendEmail.php b/src/Api/Capabilities/CanSendEmail.php index 7fcdf364c..5ae483aab 100644 --- a/src/Api/Capabilities/CanSendEmail.php +++ b/src/Api/Capabilities/CanSendEmail.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSendEmail { /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendEmail(array $input): array + public function sendEmail(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanSendReminderByEmail.php b/src/Api/Capabilities/CanSendReminderByEmail.php index 986f629b0..0ca4a2359 100644 --- a/src/Api/Capabilities/CanSendReminderByEmail.php +++ b/src/Api/Capabilities/CanSendReminderByEmail.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSendReminderByEmail { /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendReminderByEmail(array $input): array + public function sendReminderByEmail(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanSendSummationByEmail.php b/src/Api/Capabilities/CanSendSummationByEmail.php index af0c51e3a..43ec7a85d 100644 --- a/src/Api/Capabilities/CanSendSummationByEmail.php +++ b/src/Api/Capabilities/CanSendSummationByEmail.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSendSummationByEmail { /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendSummationByEmail(array $input): array + public function sendSummationByEmail(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanShow.php b/src/Api/Capabilities/CanShow.php index b7c270a6c..adf14d165 100644 --- a/src/Api/Capabilities/CanShow.php +++ b/src/Api/Capabilities/CanShow.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanShow { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array + public function show(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanStart.php b/src/Api/Capabilities/CanStart.php index cc842ab13..af03f38b3 100644 --- a/src/Api/Capabilities/CanStart.php +++ b/src/Api/Capabilities/CanStart.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanStart { /** * @param array $input - * @return array + * @return ApiResponse */ - public function start(array $input): array + public function start(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanSuspend.php b/src/Api/Capabilities/CanSuspend.php index e4bcfe4c2..cd09157b0 100644 --- a/src/Api/Capabilities/CanSuspend.php +++ b/src/Api/Capabilities/CanSuspend.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSuspend { /** * @param array $input - * @return array + * @return ApiResponse */ - public function suspend(array $input): array + public function suspend(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanSyncWhois.php b/src/Api/Capabilities/CanSyncWhois.php index cc798d27b..b5d80855e 100644 --- a/src/Api/Capabilities/CanSyncWhois.php +++ b/src/Api/Capabilities/CanSyncWhois.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanSyncWhois { /** * @param array $input - * @return array + * @return ApiResponse */ - public function syncWhois(array $input): array + public function syncWhois(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanTerminate.php b/src/Api/Capabilities/CanTerminate.php index 832b1bde7..736ffdef0 100644 --- a/src/Api/Capabilities/CanTerminate.php +++ b/src/Api/Capabilities/CanTerminate.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanTerminate { /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array + public function terminate(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanTransfer.php b/src/Api/Capabilities/CanTransfer.php index 27c6c0b0a..e04b0d0e6 100644 --- a/src/Api/Capabilities/CanTransfer.php +++ b/src/Api/Capabilities/CanTransfer.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanTransfer { /** * @param array $input - * @return array + * @return ApiResponse */ - public function transfer(array $input): array + public function transfer(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanUnblock.php b/src/Api/Capabilities/CanUnblock.php index 62fb74286..e3205b395 100644 --- a/src/Api/Capabilities/CanUnblock.php +++ b/src/Api/Capabilities/CanUnblock.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanUnblock { /** * @param array $input - * @return array + * @return ApiResponse */ - public function unblock(array $input): array + public function unblock(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanUnlock.php b/src/Api/Capabilities/CanUnlock.php index 30082aa69..f477c7fc8 100644 --- a/src/Api/Capabilities/CanUnlock.php +++ b/src/Api/Capabilities/CanUnlock.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanUnlock { /** * @param array $input - * @return array + * @return ApiResponse */ - public function unlock(array $input): array + public function unlock(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanUnsuspend.php b/src/Api/Capabilities/CanUnsuspend.php index ae8afef7e..108222494 100644 --- a/src/Api/Capabilities/CanUnsuspend.php +++ b/src/Api/Capabilities/CanUnsuspend.php @@ -2,13 +2,15 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanUnsuspend { /** * @param array $input - * @return array + * @return ApiResponse */ - public function unsuspend(array $input): array + public function unsuspend(array $input): ApiResponse { return $this ->sendRequest( diff --git a/src/Api/Capabilities/CanUpDowngrade.php b/src/Api/Capabilities/CanUpDowngrade.php index 76bb994b5..50c47c064 100644 --- a/src/Api/Capabilities/CanUpDowngrade.php +++ b/src/Api/Capabilities/CanUpDowngrade.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanUpDowngrade { /** * @param array $input - * @return array + * @return ApiResponse */ - public function upDowngrade(array $input): array + public function upDowngrade(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Capabilities/CanUpdateLoginCredentials.php b/src/Api/Capabilities/CanUpdateLoginCredentials.php index 4e589f374..e55bb775e 100644 --- a/src/Api/Capabilities/CanUpdateLoginCredentials.php +++ b/src/Api/Capabilities/CanUpdateLoginCredentials.php @@ -2,18 +2,20 @@ namespace Hyperized\Hostfact\Api\Capabilities; +use Hyperized\Hostfact\Api\Response\ApiResponse; + trait CanUpdateLoginCredentials { /** * @param array $input - * @return array + * @return ApiResponse */ - public function updateLoginCredentials(array $input): array + public function updateLoginCredentials(array $input): ApiResponse { return $this ->sendRequest( self::$name, - mb_strtolower(__FUNCTION__), + strtolower(__FUNCTION__), $input ); } diff --git a/src/Api/Controllers/CreditInvoice.php b/src/Api/Controllers/CreditInvoice.php index 54c3d3522..8994ecdc8 100644 --- a/src/Api/Controllers/CreditInvoice.php +++ b/src/Api/Controllers/CreditInvoice.php @@ -18,7 +18,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\CreditInvoiceInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class CreditInvoice extends Api implements CreditInvoiceInterface { diff --git a/src/Api/Controllers/Creditor.php b/src/Api/Controllers/Creditor.php index e0865f266..e635a7263 100644 --- a/src/Api/Controllers/Creditor.php +++ b/src/Api/Controllers/Creditor.php @@ -14,7 +14,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\CreditorInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Creditor extends Api implements CreditorInterface { diff --git a/src/Api/Controllers/Debtor.php b/src/Api/Controllers/Debtor.php index f29f1d4df..60c72737e 100644 --- a/src/Api/Controllers/Debtor.php +++ b/src/Api/Controllers/Debtor.php @@ -17,7 +17,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\DebtorInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Debtor extends Api implements DebtorInterface { diff --git a/src/Api/Controllers/Domain.php b/src/Api/Controllers/Domain.php index df5632f2f..7e73d40b7 100644 --- a/src/Api/Controllers/Domain.php +++ b/src/Api/Controllers/Domain.php @@ -25,7 +25,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\DomainInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Domain extends Api implements DomainInterface { diff --git a/src/Api/Controllers/Group.php b/src/Api/Controllers/Group.php index b8bec18ca..0fb3bac64 100644 --- a/src/Api/Controllers/Group.php +++ b/src/Api/Controllers/Group.php @@ -11,7 +11,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\GroupInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Group extends Api implements GroupInterface { diff --git a/src/Api/Controllers/Handle.php b/src/Api/Controllers/Handle.php index ba59a7b41..bdaa825f7 100644 --- a/src/Api/Controllers/Handle.php +++ b/src/Api/Controllers/Handle.php @@ -12,7 +12,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HandleInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Handle extends Api implements HandleInterface { diff --git a/src/Api/Controllers/Hosting.php b/src/Api/Controllers/Hosting.php index 2ce6f8311..6ffa205f6 100644 --- a/src/Api/Controllers/Hosting.php +++ b/src/Api/Controllers/Hosting.php @@ -18,7 +18,7 @@ use Hyperized\Hostfact\Api\Capabilities\CanUpDowngrade; use Hyperized\Hostfact\Interfaces\HostingInterface; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Hosting extends Api implements HostingInterface { diff --git a/src/Api/Controllers/Invoice.php b/src/Api/Controllers/Invoice.php index 9fd3cd63b..4d35aa9e1 100644 --- a/src/Api/Controllers/Invoice.php +++ b/src/Api/Controllers/Invoice.php @@ -30,7 +30,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\InvoiceInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Invoice extends Api implements InvoiceInterface { diff --git a/src/Api/Controllers/Order.php b/src/Api/Controllers/Order.php index e777debf5..adfb266ab 100644 --- a/src/Api/Controllers/Order.php +++ b/src/Api/Controllers/Order.php @@ -14,7 +14,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\OrderInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Order extends Api implements OrderInterface { diff --git a/src/Api/Controllers/PriceQuote.php b/src/Api/Controllers/PriceQuote.php index 6f774d34d..3f2bb2baa 100644 --- a/src/Api/Controllers/PriceQuote.php +++ b/src/Api/Controllers/PriceQuote.php @@ -20,7 +20,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\PriceQuoteInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class PriceQuote extends Api implements PriceQuoteInterface { diff --git a/src/Api/Controllers/Product.php b/src/Api/Controllers/Product.php index 4f7831be2..77e0da5d6 100644 --- a/src/Api/Controllers/Product.php +++ b/src/Api/Controllers/Product.php @@ -11,7 +11,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\ProductInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Product extends Api implements ProductInterface { diff --git a/src/Api/Controllers/Service.php b/src/Api/Controllers/Service.php index 3bb9d22df..ebdc6aa3e 100644 --- a/src/Api/Controllers/Service.php +++ b/src/Api/Controllers/Service.php @@ -11,7 +11,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\ServiceInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Service extends Api implements ServiceInterface { diff --git a/src/Api/Controllers/Ssl.php b/src/Api/Controllers/Ssl.php index 3b84a6a16..67eedba2f 100644 --- a/src/Api/Controllers/Ssl.php +++ b/src/Api/Controllers/Ssl.php @@ -20,7 +20,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\SslInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Ssl extends Api implements SslInterface { diff --git a/src/Api/Controllers/Ticket.php b/src/Api/Controllers/Ticket.php index 634702644..6429a1ceb 100644 --- a/src/Api/Controllers/Ticket.php +++ b/src/Api/Controllers/Ticket.php @@ -16,7 +16,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\TicketInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Ticket extends Api implements TicketInterface { diff --git a/src/Api/Controllers/Vps.php b/src/Api/Controllers/Vps.php index bc88ed837..b805bdceb 100644 --- a/src/Api/Controllers/Vps.php +++ b/src/Api/Controllers/Vps.php @@ -19,7 +19,7 @@ use Hyperized\Hostfact\Http\HttpClient; use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Hyperized\Hostfact\Interfaces\VpsInterface; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; class Vps extends Api implements VpsInterface { diff --git a/src/Exceptions/InvalidArgumentException.php b/src/Exceptions/InvalidArgumentException.php index 22d3c7250..c0526954b 100644 --- a/src/Exceptions/InvalidArgumentException.php +++ b/src/Exceptions/InvalidArgumentException.php @@ -6,11 +6,6 @@ class InvalidArgumentException extends \InvalidArgumentException { - public static function invalidUrl(string $value): InvalidArgumentException - { - return new self('Provided URL is not valid [' . $value . ']'); - } - public static function apiFailed(GuzzleException $exception): InvalidArgumentException { return new self('API call returned an invalid response: ' . $exception->getMessage() . '.'); diff --git a/src/HostfactFacade.php b/src/HostfactFacade.php index 18251a87d..aef865f44 100644 --- a/src/HostfactFacade.php +++ b/src/HostfactFacade.php @@ -6,11 +6,6 @@ class HostfactFacade extends Facade { - /** - * Get the registered name of the component. - * - * @return string - */ protected static function getFacadeAccessor(): string { return 'Hostfact'; diff --git a/src/Http/HttpClient.php b/src/Http/HttpClient.php index 1341fd221..68032aa33 100644 --- a/src/Http/HttpClient.php +++ b/src/Http/HttpClient.php @@ -5,32 +5,31 @@ use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\HandlerStack; use Hyperized\Hostfact\Interfaces\HttpClientInterface; -use Hyperized\ValueObjects\Contracts\Strings\ByteArrayInterface; +use Hyperized\ValueObjects\Contracts\Strings\UrlInterface; final class HttpClient implements HttpClientInterface { - private string $userAgent = 'hyperized/hostfact (https://github.com/hyperized/hostfact)'; - private HandlerStack $stack; - private GuzzleClient $httpClient; + private readonly string $userAgent; + private readonly HandlerStack $stack; + private readonly GuzzleClient $httpClient; - protected function __construct(ByteArrayInterface $url) + protected function __construct(UrlInterface $url) { + $this->userAgent = 'hyperized/hostfact (https://github.com/hyperized/hostfact)'; $this->stack = HandlerStack::create(); - $this->httpClient = (new GuzzleClient( - [ - 'handler' => $this->stack, - 'base_uri' => $url->getValue(), - 'timeout' => config('Hostfact.api_v2_timeout'), - 'headers' => [ - 'User-Agent' => $this->userAgent - ] - ] - )); + $this->httpClient = new GuzzleClient([ + 'handler' => $this->stack, + 'base_uri' => $url->getValue(), + 'timeout' => config('Hostfact.api_v2_timeout'), + 'headers' => [ + 'User-Agent' => $this->userAgent, + ], + ]); } - public static function new(ByteArrayInterface $url): HttpClientInterface + public static function new(UrlInterface $url): HttpClientInterface { - return new HttpClient($url); + return new self($url); } public function getHttpClient(): GuzzleClient diff --git a/src/Interfaces/ApiInterface.php b/src/Interfaces/ApiInterface.php index 53c4dfda0..8ac258dd0 100644 --- a/src/Interfaces/ApiInterface.php +++ b/src/Interfaces/ApiInterface.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -28,10 +29,7 @@ public static function getResponseBody(ResponseInterface $response): string; public function getHttpClient(): HttpClientInterface; /** - * @param string $controller - * @param string $action * @param array $input - * @return array */ - public function sendRequest(string $controller, string $action, array $input): array; + public function sendRequest(string $controller, string $action, array $input): ApiResponse; } diff --git a/src/Interfaces/CreditInvoiceInterface.php b/src/Interfaces/CreditInvoiceInterface.php index 72804a25b..83960f659 100644 --- a/src/Interfaces/CreditInvoiceInterface.php +++ b/src/Interfaces/CreditInvoiceInterface.php @@ -2,77 +2,79 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface CreditInvoiceInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function partialPayment(array $input): array; + public function partialPayment(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsPaid(array $input): array; + public function markAsPaid(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineAdd(array $input): array; + public function lineAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineDelete(array $input): array; + public function lineDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array; + public function attachmentAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array; + public function attachmentDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; } diff --git a/src/Interfaces/CreditorInterface.php b/src/Interfaces/CreditorInterface.php index e47bd28dc..8f6352e1a 100644 --- a/src/Interfaces/CreditorInterface.php +++ b/src/Interfaces/CreditorInterface.php @@ -2,53 +2,55 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface CreditorInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array; + public function attachmentAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array; + public function attachmentDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; } diff --git a/src/Interfaces/DebtorInterface.php b/src/Interfaces/DebtorInterface.php index 582cfa8e0..015f491bd 100644 --- a/src/Interfaces/DebtorInterface.php +++ b/src/Interfaces/DebtorInterface.php @@ -2,71 +2,73 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface DebtorInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function checkLogin(array $input): array; + public function checkLogin(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function updateLoginCredentials(array $input): array; + public function updateLoginCredentials(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function generatePdf(array $input): array; + public function generatePdf(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendEmail(array $input): array; + public function sendEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array; + public function attachmentAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array; + public function attachmentDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; } diff --git a/src/Interfaces/DomainInterface.php b/src/Interfaces/DomainInterface.php index 45f4d5a91..b59d97a07 100644 --- a/src/Interfaces/DomainInterface.php +++ b/src/Interfaces/DomainInterface.php @@ -2,119 +2,121 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface DomainInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array; + public function terminate(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function getToken(array $input): array; + public function getToken(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lock(array $input): array; + public function lock(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function unlock(array $input): array; + public function unlock(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeNameserver(array $input): array; + public function changeNameserver(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function syncWhois(array $input): array; + public function syncWhois(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function editWhois(array $input): array; + public function editWhois(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function check(array $input): array; + public function check(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function transfer(array $input): array; + public function transfer(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function register(array $input): array; + public function register(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function autoRenew(array $input): array; + public function autoRenew(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function listDnsTemplates(array $input): array; + public function listDnsTemplates(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function getDnsZone(array $input): array; + public function getDnsZone(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function editDnsZone(array $input): array; + public function editDnsZone(array $input): ApiResponse; } diff --git a/src/Interfaces/GroupInterface.php b/src/Interfaces/GroupInterface.php index 0386c659d..3383808b3 100644 --- a/src/Interfaces/GroupInterface.php +++ b/src/Interfaces/GroupInterface.php @@ -2,35 +2,37 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface GroupInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; } diff --git a/src/Interfaces/HandleInterface.php b/src/Interfaces/HandleInterface.php index 6614d185e..bb8dc9561 100644 --- a/src/Interfaces/HandleInterface.php +++ b/src/Interfaces/HandleInterface.php @@ -2,41 +2,43 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface HandleInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function listDomain(array $input): array; + public function listDomain(array $input): ApiResponse; } diff --git a/src/Interfaces/HostingInterface.php b/src/Interfaces/HostingInterface.php index 76bbd8211..6a5c1c0fb 100644 --- a/src/Interfaces/HostingInterface.php +++ b/src/Interfaces/HostingInterface.php @@ -2,83 +2,85 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface HostingInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array; + public function terminate(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function suspend(array $input): array; + public function suspend(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function unsuspend(array $input): array; + public function unsuspend(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function create(array $input): array; + public function create(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function removeFromServer(array $input): array; + public function removeFromServer(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function getDomainList(array $input): array; + public function getDomainList(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function emailAccountData(array $input): array; + public function emailAccountData(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function upDowngrade(array $input): array; + public function upDowngrade(array $input): ApiResponse; } diff --git a/src/Interfaces/HttpClientInterface.php b/src/Interfaces/HttpClientInterface.php index b42e9196d..be3f987fa 100644 --- a/src/Interfaces/HttpClientInterface.php +++ b/src/Interfaces/HttpClientInterface.php @@ -3,11 +3,11 @@ namespace Hyperized\Hostfact\Interfaces; use GuzzleHttp\ClientInterface; -use Hyperized\ValueObjects\Contracts\Strings\ByteArrayInterface; +use Hyperized\ValueObjects\Contracts\Strings\UrlInterface; interface HttpClientInterface { - public static function new(ByteArrayInterface $url): HttpClientInterface; + public static function new(UrlInterface $url): HttpClientInterface; public function getHttpClient(): ClientInterface; } diff --git a/src/Interfaces/InvoiceInterface.php b/src/Interfaces/InvoiceInterface.php index 9e236ff09..6cee86a3d 100644 --- a/src/Interfaces/InvoiceInterface.php +++ b/src/Interfaces/InvoiceInterface.php @@ -2,149 +2,151 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface InvoiceInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function credit(array $input): array; + public function credit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function partialPayment(array $input): array; + public function partialPayment(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsPaid(array $input): array; + public function markAsPaid(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsUnpaid(array $input): array; + public function markAsUnpaid(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendByEmail(array $input): array; + public function sendByEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendReminderByEmail(array $input): array; + public function sendReminderByEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendSummationByEmail(array $input): array; + public function sendSummationByEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function download(array $input): array; + public function download(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineAdd(array $input): array; + public function lineAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineDelete(array $input): array; + public function lineDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array; + public function attachmentAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array; + public function attachmentDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function block(array $input): array; + public function block(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function unblock(array $input): array; + public function unblock(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function schedule(array $input): array; + public function schedule(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function cancelSchedule(array $input): array; + public function cancelSchedule(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function paymentProcessPause(array $input): array; + public function paymentProcessPause(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function paymentProcessReactivate(array $input): array; + public function paymentProcessReactivate(array $input): ApiResponse; } diff --git a/src/Interfaces/OrderInterface.php b/src/Interfaces/OrderInterface.php index c91b529ac..48254ab30 100644 --- a/src/Interfaces/OrderInterface.php +++ b/src/Interfaces/OrderInterface.php @@ -2,47 +2,49 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface OrderInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function process(array $input): array; + public function process(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineAdd(array $input): array; + public function lineAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineDelete(array $input): array; + public function lineDelete(array $input): ApiResponse; } diff --git a/src/Interfaces/PriceQuoteInterface.php b/src/Interfaces/PriceQuoteInterface.php index d38463596..005223152 100644 --- a/src/Interfaces/PriceQuoteInterface.php +++ b/src/Interfaces/PriceQuoteInterface.php @@ -2,89 +2,91 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface PriceQuoteInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function sendByEmail(array $input): array; + public function sendByEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function download(array $input): array; + public function download(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function accept(array $input): array; + public function accept(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function decline(array $input): array; + public function decline(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineAdd(array $input): array; + public function lineAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function lineDelete(array $input): array; + public function lineDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentAdd(array $input): array; + public function attachmentAdd(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDelete(array $input): array; + public function attachmentDelete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; } diff --git a/src/Interfaces/ProductInterface.php b/src/Interfaces/ProductInterface.php index 011625aa7..312318cd7 100644 --- a/src/Interfaces/ProductInterface.php +++ b/src/Interfaces/ProductInterface.php @@ -2,35 +2,37 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface ProductInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; } diff --git a/src/Interfaces/ServiceInterface.php b/src/Interfaces/ServiceInterface.php index 479bb57eb..5bd1d7ca0 100644 --- a/src/Interfaces/ServiceInterface.php +++ b/src/Interfaces/ServiceInterface.php @@ -2,35 +2,37 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface ServiceInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array; + public function terminate(array $input): ApiResponse; } diff --git a/src/Interfaces/SslInterface.php b/src/Interfaces/SslInterface.php index 9aba329f1..cc95aa5c7 100644 --- a/src/Interfaces/SslInterface.php +++ b/src/Interfaces/SslInterface.php @@ -2,89 +2,91 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface SslInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array; + public function terminate(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function request(array $input): array; + public function request(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsInstalled(array $input): array; + public function markAsInstalled(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function download(array $input): array; + public function download(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function reissue(array $input): array; + public function reissue(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function renew(array $input): array; + public function renew(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function getStatus(array $input): array; + public function getStatus(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function resendApproverEmail(array $input): array; + public function resendApproverEmail(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function revoke(array $input): array; + public function revoke(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function markAsUninstalled(array $input): array; + public function markAsUninstalled(array $input): ApiResponse; } diff --git a/src/Interfaces/TicketInterface.php b/src/Interfaces/TicketInterface.php index 7b697cae3..4a6f37e61 100644 --- a/src/Interfaces/TicketInterface.php +++ b/src/Interfaces/TicketInterface.php @@ -2,59 +2,61 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface TicketInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function delete(array $input): array; + public function delete(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function addMessage(array $input): array; + public function addMessage(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeStatus(array $input): array; + public function changeStatus(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function changeOwner(array $input): array; + public function changeOwner(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function attachmentDownload(array $input): array; + public function attachmentDownload(array $input): ApiResponse; } diff --git a/src/Interfaces/VpsInterface.php b/src/Interfaces/VpsInterface.php index 505d9565a..5303a1f25 100644 --- a/src/Interfaces/VpsInterface.php +++ b/src/Interfaces/VpsInterface.php @@ -2,83 +2,85 @@ namespace Hyperized\Hostfact\Interfaces; +use Hyperized\Hostfact\Api\Response\ApiResponse; + interface VpsInterface extends ApiInterface { /** * @param array $input - * @return array + * @return ApiResponse */ - public function show(array $input): array; + public function show(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function list(array $input = []): array; + public function list(array $input = []): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function add(array $input): array; + public function add(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function edit(array $input): array; + public function edit(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function terminate(array $input): array; + public function terminate(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function create(array $input): array; + public function create(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function start(array $input): array; + public function start(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function pause(array $input): array; + public function pause(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function restart(array $input): array; + public function restart(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function suspend(array $input): array; + public function suspend(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function unsuspend(array $input): array; + public function unsuspend(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function downloadAccountData(array $input): array; + public function downloadAccountData(array $input): ApiResponse; /** * @param array $input - * @return array + * @return ApiResponse */ - public function emailAccountData(array $input): array; + public function emailAccountData(array $input): ApiResponse; } diff --git a/src/Providers/HostfactServiceProvider.php b/src/Providers/HostfactServiceProvider.php index 45f89c0d6..31b4ccb86 100644 --- a/src/Providers/HostfactServiceProvider.php +++ b/src/Providers/HostfactServiceProvider.php @@ -9,35 +9,22 @@ class HostfactServiceProvider extends ServiceProvider private static string $configPath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR; - /** - * Bootstrap the application services. - * - * @return void - */ public function boot(): void { - // Configuration file $this->publishes( [ - self::$configPath . 'config.php' => config_path('Hostfact.php'), + self::$configPath . 'Hostfact.php' => config_path('Hostfact.php'), ], 'config' ); } - /** - * Register the application services. - * - * @return void - */ public function register(): void { $this->mergeConfigFrom(self::$configPath . 'Hostfact.php', 'Hostfact'); } /** - * Get the services provided by the provider. - * * @return array */ public function provides(): array diff --git a/src/Types/FormParameter.php b/src/Types/FormParameter.php index 99966a30c..842a4aeb7 100644 --- a/src/Types/FormParameter.php +++ b/src/Types/FormParameter.php @@ -4,19 +4,13 @@ use Hyperized\Hostfact\Interfaces\FormParameterInterface; -final class FormParameter implements FormParameterInterface +final readonly class FormParameter implements FormParameterInterface { - /** - * @var array - */ - private array $value; - /** * @param array $value */ - protected function __construct(array $value = []) + protected function __construct(private array $value = []) { - $this->value = $value; } /** diff --git a/src/Types/Url.php b/src/Types/Url.php deleted file mode 100644 index 59065f2c6..000000000 --- a/src/Types/Url.php +++ /dev/null @@ -1,18 +0,0 @@ - Date: Sat, 11 Apr 2026 16:19:15 +0200 Subject: [PATCH 09/30] Add typed entity classes for HostFact API v3.1 --- src/Api/Entity/Creditor.php | 83 ++++++++++++++++++ src/Api/Entity/Debtor.php | 141 ++++++++++++++++++++++++++++++ src/Api/Entity/Domain.php | 78 +++++++++++++++++ src/Api/Entity/Entity.php | 17 ++++ src/Api/Entity/EntityFactory.php | 37 ++++++++ src/Api/Entity/Group.php | 39 +++++++++ src/Api/Entity/GroupItem.php | 27 ++++++ src/Api/Entity/Hosting.php | 56 ++++++++++++ src/Api/Entity/Invoice.php | 140 +++++++++++++++++++++++++++++ src/Api/Entity/InvoiceLine.php | 63 +++++++++++++ src/Api/Entity/Order.php | 107 +++++++++++++++++++++++ src/Api/Entity/OrderLine.php | 55 ++++++++++++ src/Api/Entity/PriceQuote.php | 118 +++++++++++++++++++++++++ src/Api/Entity/PriceQuoteLine.php | 57 ++++++++++++ src/Api/Entity/Product.php | 61 +++++++++++++ src/Api/Entity/Ssl.php | 75 ++++++++++++++++ src/Api/Entity/Subscription.php | 65 ++++++++++++++ src/Api/Entity/Ticket.php | 68 ++++++++++++++ src/Api/Entity/TicketMessage.php | 40 +++++++++ src/Api/Entity/Vps.php | 64 ++++++++++++++ 20 files changed, 1391 insertions(+) create mode 100644 src/Api/Entity/Creditor.php create mode 100644 src/Api/Entity/Debtor.php create mode 100644 src/Api/Entity/Domain.php create mode 100644 src/Api/Entity/Entity.php create mode 100644 src/Api/Entity/EntityFactory.php create mode 100644 src/Api/Entity/Group.php create mode 100644 src/Api/Entity/GroupItem.php create mode 100644 src/Api/Entity/Hosting.php create mode 100644 src/Api/Entity/Invoice.php create mode 100644 src/Api/Entity/InvoiceLine.php create mode 100644 src/Api/Entity/Order.php create mode 100644 src/Api/Entity/OrderLine.php create mode 100644 src/Api/Entity/PriceQuote.php create mode 100644 src/Api/Entity/PriceQuoteLine.php create mode 100644 src/Api/Entity/Product.php create mode 100644 src/Api/Entity/Ssl.php create mode 100644 src/Api/Entity/Subscription.php create mode 100644 src/Api/Entity/Ticket.php create mode 100644 src/Api/Entity/TicketMessage.php create mode 100644 src/Api/Entity/Vps.php diff --git a/src/Api/Entity/Creditor.php b/src/Api/Entity/Creditor.php new file mode 100644 index 000000000..9b100efdc --- /dev/null +++ b/src/Api/Entity/Creditor.php @@ -0,0 +1,83 @@ + $Groups + * @param list $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $CreditorCode, + public ?string $MyCustomerCode, + public ?string $CompanyName, + public ?string $CompanyNumber, + public ?string $TaxNumber, + public ?string $Sex, + public ?string $Initials, + public ?string $SurName, + public ?string $Address, + public ?string $ZipCode, + public ?string $City, + public ?string $Country, + public ?string $EmailAddress, + public ?string $PhoneNumber, + public ?string $MobileNumber, + public ?string $FaxNumber, + public ?string $Comment, + public ?string $Authorisation, + public ?string $AccountNumber, + public ?string $AccountBIC, + public ?string $AccountName, + public ?string $AccountBank, + public ?string $AccountCity, + public ?string $Term, + public ?string $Created, + public ?string $Modified, + public array $Groups, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + CreditorCode: $bag->nullableString('CreditorCode'), + MyCustomerCode: $bag->nullableString('MyCustomerCode'), + CompanyName: $bag->nullableString('CompanyName'), + CompanyNumber: $bag->nullableString('CompanyNumber'), + TaxNumber: $bag->nullableString('TaxNumber'), + Sex: $bag->nullableString('Sex'), + Initials: $bag->nullableString('Initials'), + SurName: $bag->nullableString('SurName'), + Address: $bag->nullableString('Address'), + ZipCode: $bag->nullableString('ZipCode'), + City: $bag->nullableString('City'), + Country: $bag->nullableString('Country'), + EmailAddress: $bag->nullableString('EmailAddress'), + PhoneNumber: $bag->nullableString('PhoneNumber'), + MobileNumber: $bag->nullableString('MobileNumber'), + FaxNumber: $bag->nullableString('FaxNumber'), + Comment: $bag->nullableString('Comment'), + Authorisation: $bag->nullableString('Authorisation'), + AccountNumber: $bag->nullableString('AccountNumber'), + AccountBIC: $bag->nullableString('AccountBIC'), + AccountName: $bag->nullableString('AccountName'), + AccountBank: $bag->nullableString('AccountBank'), + AccountCity: $bag->nullableString('AccountCity'), + Term: $bag->nullableString('Term'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/Debtor.php b/src/Api/Entity/Debtor.php new file mode 100644 index 000000000..18fe9c80f --- /dev/null +++ b/src/Api/Entity/Debtor.php @@ -0,0 +1,141 @@ + $Groups + * @param list $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $DebtorCode, + public ?string $CompanyName, + public ?string $CompanyNumber, + public ?string $LegalForm, + public ?string $TaxNumber, + public ?string $Sex, + public ?string $Initials, + public ?string $SurName, + public ?string $Address, + public ?string $ZipCode, + public ?string $City, + public ?string $Country, + public ?string $EmailAddress, + public ?string $PhoneNumber, + public ?string $MobileNumber, + public ?string $FaxNumber, + public ?string $Website, + public ?string $Comment, + public ?string $InvoiceMethod, + public ?string $InvoiceCompanyName, + public ?string $InvoiceSex, + public ?string $InvoiceInitials, + public ?string $InvoiceSurName, + public ?string $InvoiceAddress, + public ?string $InvoiceZipCode, + public ?string $InvoiceCity, + public ?string $InvoiceCountry, + public ?string $InvoiceEmailAddress, + public ?string $ReminderEmailAddress, + public ?string $InvoiceAuthorisation, + public ?string $MandateID, + public ?string $InvoiceDataForPriceQuote, + public ?string $AccountNumber, + public ?string $AccountBIC, + public ?string $AccountName, + public ?string $AccountBank, + public ?string $AccountCity, + public ?string $ActiveLogin, + public ?string $Username, + public ?string $SecurePassword, + public ?string $Mailing, + public ?string $Taxable, + public ?string $PeriodicInvoiceDays, + public ?string $InvoiceTemplate, + public ?string $PriceQuoteTemplate, + public ?string $ReminderTemplate, + public ?string $SecondReminderTemplate, + public ?string $SummationTemplate, + public ?string $PaymentMail, + public ?string $PaymentMailTemplate, + public ?string $InvoiceCollect, + public ?string $DefaultLanguage, + public ?string $ClientareaProfile, + public ?string $Created, + public ?string $Modified, + public array $Groups, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + DebtorCode: $bag->nullableString('DebtorCode'), + CompanyName: $bag->nullableString('CompanyName'), + CompanyNumber: $bag->nullableString('CompanyNumber'), + LegalForm: $bag->nullableString('LegalForm'), + TaxNumber: $bag->nullableString('TaxNumber'), + Sex: $bag->nullableString('Sex'), + Initials: $bag->nullableString('Initials'), + SurName: $bag->nullableString('SurName'), + Address: $bag->nullableString('Address'), + ZipCode: $bag->nullableString('ZipCode'), + City: $bag->nullableString('City'), + Country: $bag->nullableString('Country'), + EmailAddress: $bag->nullableString('EmailAddress'), + PhoneNumber: $bag->nullableString('PhoneNumber'), + MobileNumber: $bag->nullableString('MobileNumber'), + FaxNumber: $bag->nullableString('FaxNumber'), + Website: $bag->nullableString('Website'), + Comment: $bag->nullableString('Comment'), + InvoiceMethod: $bag->nullableString('InvoiceMethod'), + InvoiceCompanyName: $bag->nullableString('InvoiceCompanyName'), + InvoiceSex: $bag->nullableString('InvoiceSex'), + InvoiceInitials: $bag->nullableString('InvoiceInitials'), + InvoiceSurName: $bag->nullableString('InvoiceSurName'), + InvoiceAddress: $bag->nullableString('InvoiceAddress'), + InvoiceZipCode: $bag->nullableString('InvoiceZipCode'), + InvoiceCity: $bag->nullableString('InvoiceCity'), + InvoiceCountry: $bag->nullableString('InvoiceCountry'), + InvoiceEmailAddress: $bag->nullableString('InvoiceEmailAddress'), + ReminderEmailAddress: $bag->nullableString('ReminderEmailAddress'), + InvoiceAuthorisation: $bag->nullableString('InvoiceAuthorisation'), + MandateID: $bag->nullableString('MandateID'), + InvoiceDataForPriceQuote: $bag->nullableString('InvoiceDataForPriceQuote'), + AccountNumber: $bag->nullableString('AccountNumber'), + AccountBIC: $bag->nullableString('AccountBIC'), + AccountName: $bag->nullableString('AccountName'), + AccountBank: $bag->nullableString('AccountBank'), + AccountCity: $bag->nullableString('AccountCity'), + ActiveLogin: $bag->nullableString('ActiveLogin'), + Username: $bag->nullableString('Username'), + SecurePassword: $bag->nullableString('SecurePassword'), + Mailing: $bag->nullableString('Mailing'), + Taxable: $bag->nullableString('Taxable'), + PeriodicInvoiceDays: $bag->nullableString('PeriodicInvoiceDays'), + InvoiceTemplate: $bag->nullableString('InvoiceTemplate'), + PriceQuoteTemplate: $bag->nullableString('PriceQuoteTemplate'), + ReminderTemplate: $bag->nullableString('ReminderTemplate'), + SecondReminderTemplate: $bag->nullableString('SecondReminderTemplate'), + SummationTemplate: $bag->nullableString('SummationTemplate'), + PaymentMail: $bag->nullableString('PaymentMail'), + PaymentMailTemplate: $bag->nullableString('PaymentMailTemplate'), + InvoiceCollect: $bag->nullableString('InvoiceCollect'), + DefaultLanguage: $bag->nullableString('DefaultLanguage'), + ClientareaProfile: $bag->nullableString('ClientareaProfile'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/Domain.php b/src/Api/Entity/Domain.php new file mode 100644 index 000000000..68c9d0fbe --- /dev/null +++ b/src/Api/Entity/Domain.php @@ -0,0 +1,78 @@ + $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $Domain, + public ?string $Tld, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $HostingID, + public ?string $Status, + public ?string $RegistrationDate, + public ?string $ExpirationDate, + public ?string $Registrar, + public ?string $DNS1, + public ?string $DNS2, + public ?string $DNS3, + public ?string $DNS1IP, + public ?string $DNS2IP, + public ?string $DNS3IP, + public ?string $DNSTemplate, + public ?string $OwnerHandle, + public ?string $AdminHandle, + public ?string $TechHandle, + public ?string $DomainAutoRenew, + public ?string $Comment, + public ?string $Created, + public ?string $Modified, + public ?Subscription $Subscription, + public ?DataBag $RegistrarInfo, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + Domain: $bag->nullableString('Domain'), + Tld: $bag->nullableString('Tld'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + HostingID: $bag->nullableString('HostingID'), + Status: $bag->nullableString('Status'), + RegistrationDate: $bag->nullableString('RegistrationDate'), + ExpirationDate: $bag->nullableString('ExpirationDate'), + Registrar: $bag->nullableString('Registrar'), + DNS1: $bag->nullableString('DNS1'), + DNS2: $bag->nullableString('DNS2'), + DNS3: $bag->nullableString('DNS3'), + DNS1IP: $bag->nullableString('DNS1IP'), + DNS2IP: $bag->nullableString('DNS2IP'), + DNS3IP: $bag->nullableString('DNS3IP'), + DNSTemplate: $bag->nullableString('DNSTemplate'), + OwnerHandle: $bag->nullableString('OwnerHandle'), + AdminHandle: $bag->nullableString('AdminHandle'), + TechHandle: $bag->nullableString('TechHandle'), + DomainAutoRenew: $bag->nullableString('DomainAutoRenew'), + Comment: $bag->nullableString('Comment'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, + RegistrarInfo: $bag->has('RegistrarInfo') ? $bag->bag('RegistrarInfo') : null, + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/Entity.php b/src/Api/Entity/Entity.php new file mode 100644 index 000000000..d1d581cf0 --- /dev/null +++ b/src/Api/Entity/Entity.php @@ -0,0 +1,17 @@ +bag = $bag; + } + + abstract public static function fromBag(DataBag $bag): static; +} diff --git a/src/Api/Entity/EntityFactory.php b/src/Api/Entity/EntityFactory.php new file mode 100644 index 000000000..9d82e3d70 --- /dev/null +++ b/src/Api/Entity/EntityFactory.php @@ -0,0 +1,37 @@ +> + */ + private const ENTITY_MAP = [ + 'product' => Product::class, + 'debtor' => Debtor::class, + 'invoice' => Invoice::class, + 'domain' => Domain::class, + 'hosting' => Hosting::class, + 'ssl' => Ssl::class, + 'vps' => Vps::class, + 'ticket' => Ticket::class, + 'order' => Order::class, + 'pricequote' => PriceQuote::class, + 'creditor' => Creditor::class, + 'group' => Group::class, + ]; + + public static function fromBag(string $controller, DataBag $bag): Entity|DataBag + { + $class = self::ENTITY_MAP[$controller] ?? null; + + if ($class === null) { + return $bag; + } + + return $class::fromBag($bag); + } +} diff --git a/src/Api/Entity/Group.php b/src/Api/Entity/Group.php new file mode 100644 index 000000000..a7ada7b60 --- /dev/null +++ b/src/Api/Entity/Group.php @@ -0,0 +1,39 @@ + $Items + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $GroupName, + public ?string $Type, + public array $Items, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + $items = []; + if ($bag->has('Items')) { + foreach ($bag->bags('Items') as $itemBag) { + $items[] = GroupItem::fromBag($itemBag); + } + } + + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + GroupName: $bag->nullableString('GroupName'), + Type: $bag->nullableString('Type'), + Items: $items, + ); + } +} diff --git a/src/Api/Entity/GroupItem.php b/src/Api/Entity/GroupItem.php new file mode 100644 index 000000000..289d53769 --- /dev/null +++ b/src/Api/Entity/GroupItem.php @@ -0,0 +1,27 @@ +nullableString('Identifier'), + ProductCode: $bag->nullableString('ProductCode'), + ProductName: $bag->nullableString('ProductName'), + ); + } +} diff --git a/src/Api/Entity/Hosting.php b/src/Api/Entity/Hosting.php new file mode 100644 index 000000000..9680e45db --- /dev/null +++ b/src/Api/Entity/Hosting.php @@ -0,0 +1,56 @@ + $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $Username, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $Domain, + public ?string $Server, + public ?string $Package, + public ?string $PackageName, + public ?string $Comment, + public ?string $Status, + public ?string $Created, + public ?string $Modified, + public ?Subscription $Subscription, + public ?DataBag $PackageInfo, + public ?DataBag $ServerInfo, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + Username: $bag->nullableString('Username'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + Domain: $bag->nullableString('Domain'), + Server: $bag->nullableString('Server'), + Package: $bag->nullableString('Package'), + PackageName: $bag->nullableString('PackageName'), + Comment: $bag->nullableString('Comment'), + Status: $bag->nullableString('Status'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, + PackageInfo: $bag->has('PackageInfo') ? $bag->bag('PackageInfo') : null, + ServerInfo: $bag->has('ServerInfo') ? $bag->bag('ServerInfo') : null, + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/Invoice.php b/src/Api/Entity/Invoice.php new file mode 100644 index 000000000..b834beadf --- /dev/null +++ b/src/Api/Entity/Invoice.php @@ -0,0 +1,140 @@ + $InvoiceLines + * @param list $Attachments + * @param list $Translations + * @param list $UsedTaxrates + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $InvoiceCode, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $Status, + public ?string $SubStatus, + public ?string $Date, + public ?string $Term, + public ?string $PayBefore, + public ?string $PaymentURL, + public ?string $AmountExcl, + public ?string $AmountTax, + public ?string $AmountIncl, + public ?string $TaxRate, + public ?string $Compound, + public ?string $AmountPaid, + public ?string $Discount, + public ?string $VatCalcMethod, + public ?string $IgnoreDiscount, + public ?string $Coupon, + public ?string $ReferenceNumber, + public ?string $CompanyName, + public ?string $TaxNumber, + public ?string $Sex, + public ?string $Initials, + public ?string $SurName, + public ?string $Address, + public ?string $ZipCode, + public ?string $City, + public ?string $Country, + public ?string $EmailAddress, + public ?string $InvoiceMethod, + public ?string $Template, + public ?string $SentDate, + public ?string $Sent, + public ?string $Reminders, + public ?string $ReminderDate, + public ?string $Summations, + public ?string $SummationDate, + public ?string $Authorisation, + public ?string $PaymentMethod, + public ?string $PayDate, + public ?string $TransactionID, + public ?string $Description, + public ?string $Comment, + public ?string $Created, + public ?string $Modified, + public ?string $AmountDiscount, + public ?string $AmountDiscountIncl, + public array $InvoiceLines, + public array $Attachments, + public array $Translations, + public array $UsedTaxrates, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + $lines = []; + if ($bag->has('InvoiceLines')) { + foreach ($bag->bags('InvoiceLines') as $lineBag) { + $lines[] = InvoiceLine::fromBag($lineBag); + } + } + + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + InvoiceCode: $bag->nullableString('InvoiceCode'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + Status: $bag->nullableString('Status'), + SubStatus: $bag->nullableString('SubStatus'), + Date: $bag->nullableString('Date'), + Term: $bag->nullableString('Term'), + PayBefore: $bag->nullableString('PayBefore'), + PaymentURL: $bag->nullableString('PaymentURL'), + AmountExcl: $bag->nullableString('AmountExcl'), + AmountTax: $bag->nullableString('AmountTax'), + AmountIncl: $bag->nullableString('AmountIncl'), + TaxRate: $bag->nullableString('TaxRate'), + Compound: $bag->nullableString('Compound'), + AmountPaid: $bag->nullableString('AmountPaid'), + Discount: $bag->nullableString('Discount'), + VatCalcMethod: $bag->nullableString('VatCalcMethod'), + IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + Coupon: $bag->nullableString('Coupon'), + ReferenceNumber: $bag->nullableString('ReferenceNumber'), + CompanyName: $bag->nullableString('CompanyName'), + TaxNumber: $bag->nullableString('TaxNumber'), + Sex: $bag->nullableString('Sex'), + Initials: $bag->nullableString('Initials'), + SurName: $bag->nullableString('SurName'), + Address: $bag->nullableString('Address'), + ZipCode: $bag->nullableString('ZipCode'), + City: $bag->nullableString('City'), + Country: $bag->nullableString('Country'), + EmailAddress: $bag->nullableString('EmailAddress'), + InvoiceMethod: $bag->nullableString('InvoiceMethod'), + Template: $bag->nullableString('Template'), + SentDate: $bag->nullableString('SentDate'), + Sent: $bag->nullableString('Sent'), + Reminders: $bag->nullableString('Reminders'), + ReminderDate: $bag->nullableString('ReminderDate'), + Summations: $bag->nullableString('Summations'), + SummationDate: $bag->nullableString('SummationDate'), + Authorisation: $bag->nullableString('Authorisation'), + PaymentMethod: $bag->nullableString('PaymentMethod'), + PayDate: $bag->nullableString('PayDate'), + TransactionID: $bag->nullableString('TransactionID'), + Description: $bag->nullableString('Description'), + Comment: $bag->nullableString('Comment'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + AmountDiscount: $bag->nullableString('AmountDiscount'), + AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), + InvoiceLines: $lines, + Attachments: $bag->has('Attachments') ? $bag->bags('Attachments') : [], + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + UsedTaxrates: $bag->has('UsedTaxrates') ? $bag->bags('UsedTaxrates') : [], + ); + } +} diff --git a/src/Api/Entity/InvoiceLine.php b/src/Api/Entity/InvoiceLine.php new file mode 100644 index 000000000..ef26b0011 --- /dev/null +++ b/src/Api/Entity/InvoiceLine.php @@ -0,0 +1,63 @@ +nullableString('Identifier'), + Date: $bag->nullableString('Date'), + Number: $bag->nullableString('Number'), + NumberSuffix: $bag->nullableString('NumberSuffix'), + ProductCode: $bag->nullableString('ProductCode'), + Description: $bag->nullableString('Description'), + PriceExcl: $bag->nullableString('PriceExcl'), + DiscountPercentage: $bag->nullableString('DiscountPercentage'), + DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), + TaxPercentage: $bag->nullableString('TaxPercentage'), + PeriodicID: $bag->nullableString('PeriodicID'), + Periods: $bag->nullableString('Periods'), + Periodic: $bag->nullableString('Periodic'), + StartPeriod: $bag->nullableString('StartPeriod'), + EndPeriod: $bag->nullableString('EndPeriod'), + ProductType: $bag->nullableString('ProductType'), + Reference: $bag->nullableString('Reference'), + NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), + NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), + DiscountAmountIncl: $bag->nullableString('DiscountAmountIncl'), + DiscountAmountExcl: $bag->nullableString('DiscountAmountExcl'), + ); + } +} diff --git a/src/Api/Entity/Order.php b/src/Api/Entity/Order.php new file mode 100644 index 000000000..ee0c9de74 --- /dev/null +++ b/src/Api/Entity/Order.php @@ -0,0 +1,107 @@ + $OrderLines + * @param list $Translations + * @param list $UsedTaxrates + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $OrderCode, + public ?string $Debtor, + public ?string $Date, + public ?string $Term, + public ?string $AmountExcl, + public ?string $AmountTax, + public ?string $AmountIncl, + public ?string $Discount, + public ?string $VatCalcMethod, + public ?string $IgnoreDiscount, + public ?string $Coupon, + public ?string $CompanyName, + public ?string $Sex, + public ?string $Initials, + public ?string $SurName, + public ?string $Address, + public ?string $ZipCode, + public ?string $City, + public ?string $Country, + public ?string $EmailAddress, + public ?string $InvoiceMethod, + public ?string $Template, + public ?string $Authorisation, + public ?string $PaymentMethod, + public ?string $Paid, + public ?string $TransactionID, + public ?string $IPAddress, + public ?string $Comment, + public ?string $Status, + public ?string $Created, + public ?string $Modified, + public ?string $AmountDiscount, + public ?string $AmountDiscountIncl, + public array $OrderLines, + public array $Translations, + public array $UsedTaxrates, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + $lines = []; + if ($bag->has('OrderLines')) { + foreach ($bag->bags('OrderLines') as $lineBag) { + $lines[] = OrderLine::fromBag($lineBag); + } + } + + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + OrderCode: $bag->nullableString('OrderCode'), + Debtor: $bag->nullableString('Debtor'), + Date: $bag->nullableString('Date'), + Term: $bag->nullableString('Term'), + AmountExcl: $bag->nullableString('AmountExcl'), + AmountTax: $bag->nullableString('AmountTax'), + AmountIncl: $bag->nullableString('AmountIncl'), + Discount: $bag->nullableString('Discount'), + VatCalcMethod: $bag->nullableString('VatCalcMethod'), + IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + Coupon: $bag->nullableString('Coupon'), + CompanyName: $bag->nullableString('CompanyName'), + Sex: $bag->nullableString('Sex'), + Initials: $bag->nullableString('Initials'), + SurName: $bag->nullableString('SurName'), + Address: $bag->nullableString('Address'), + ZipCode: $bag->nullableString('ZipCode'), + City: $bag->nullableString('City'), + Country: $bag->nullableString('Country'), + EmailAddress: $bag->nullableString('EmailAddress'), + InvoiceMethod: $bag->nullableString('InvoiceMethod'), + Template: $bag->nullableString('Template'), + Authorisation: $bag->nullableString('Authorisation'), + PaymentMethod: $bag->nullableString('PaymentMethod'), + Paid: $bag->nullableString('Paid'), + TransactionID: $bag->nullableString('TransactionID'), + IPAddress: $bag->nullableString('IPAddress'), + Comment: $bag->nullableString('Comment'), + Status: $bag->nullableString('Status'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + AmountDiscount: $bag->nullableString('AmountDiscount'), + AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), + OrderLines: $lines, + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + UsedTaxrates: $bag->has('UsedTaxrates') ? $bag->bags('UsedTaxrates') : [], + ); + } +} diff --git a/src/Api/Entity/OrderLine.php b/src/Api/Entity/OrderLine.php new file mode 100644 index 000000000..1ddcc93f6 --- /dev/null +++ b/src/Api/Entity/OrderLine.php @@ -0,0 +1,55 @@ +nullableString('Identifier'), + Date: $bag->nullableString('Date'), + Number: $bag->nullableString('Number'), + ProductCode: $bag->nullableString('ProductCode'), + Description: $bag->nullableString('Description'), + PriceExcl: $bag->nullableString('PriceExcl'), + TaxPercentage: $bag->nullableString('TaxPercentage'), + DiscountPercentage: $bag->nullableString('DiscountPercentage'), + DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), + Periods: $bag->nullableString('Periods'), + Periodic: $bag->nullableString('Periodic'), + ProductType: $bag->nullableString('ProductType'), + Reference: $bag->nullableString('Reference'), + NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), + NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), + DiscountAmountIncl: $bag->nullableString('DiscountAmountIncl'), + DiscountAmountExcl: $bag->nullableString('DiscountAmountExcl'), + ); + } +} diff --git a/src/Api/Entity/PriceQuote.php b/src/Api/Entity/PriceQuote.php new file mode 100644 index 000000000..5928904b7 --- /dev/null +++ b/src/Api/Entity/PriceQuote.php @@ -0,0 +1,118 @@ + $PriceQuoteLines + * @param list $Attachments + * @param list $Translations + * @param list $UsedTaxrates + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $PriceQuoteCode, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $Status, + public ?string $Date, + public ?string $Term, + public ?string $ExpirationDate, + public ?string $AmountExcl, + public ?string $AmountTax, + public ?string $AmountIncl, + public ?string $TaxRate, + public ?string $Compound, + public ?string $Discount, + public ?string $VatCalcMethod, + public ?string $IgnoreDiscount, + public ?string $Coupon, + public ?string $ReferenceNumber, + public ?string $CompanyName, + public ?string $Sex, + public ?string $Initials, + public ?string $SurName, + public ?string $Address, + public ?string $ZipCode, + public ?string $City, + public ?string $Country, + public ?string $EmailAddress, + public ?string $PriceQuoteMethod, + public ?string $Template, + public ?string $SentDate, + public ?string $Sent, + public ?string $Description, + public ?string $Comment, + public ?string $Created, + public ?string $Modified, + public ?string $AcceptURL, + public ?string $AmountDiscount, + public ?string $AmountDiscountIncl, + public array $PriceQuoteLines, + public array $Attachments, + public array $Translations, + public array $UsedTaxrates, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + $lines = []; + if ($bag->has('PriceQuoteLines')) { + foreach ($bag->bags('PriceQuoteLines') as $lineBag) { + $lines[] = PriceQuoteLine::fromBag($lineBag); + } + } + + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + PriceQuoteCode: $bag->nullableString('PriceQuoteCode'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + Status: $bag->nullableString('Status'), + Date: $bag->nullableString('Date'), + Term: $bag->nullableString('Term'), + ExpirationDate: $bag->nullableString('ExpirationDate'), + AmountExcl: $bag->nullableString('AmountExcl'), + AmountTax: $bag->nullableString('AmountTax'), + AmountIncl: $bag->nullableString('AmountIncl'), + TaxRate: $bag->nullableString('TaxRate'), + Compound: $bag->nullableString('Compound'), + Discount: $bag->nullableString('Discount'), + VatCalcMethod: $bag->nullableString('VatCalcMethod'), + IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + Coupon: $bag->nullableString('Coupon'), + ReferenceNumber: $bag->nullableString('ReferenceNumber'), + CompanyName: $bag->nullableString('CompanyName'), + Sex: $bag->nullableString('Sex'), + Initials: $bag->nullableString('Initials'), + SurName: $bag->nullableString('SurName'), + Address: $bag->nullableString('Address'), + ZipCode: $bag->nullableString('ZipCode'), + City: $bag->nullableString('City'), + Country: $bag->nullableString('Country'), + EmailAddress: $bag->nullableString('EmailAddress'), + PriceQuoteMethod: $bag->nullableString('PriceQuoteMethod'), + Template: $bag->nullableString('Template'), + SentDate: $bag->nullableString('SentDate'), + Sent: $bag->nullableString('Sent'), + Description: $bag->nullableString('Description'), + Comment: $bag->nullableString('Comment'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + AcceptURL: $bag->nullableString('AcceptURL'), + AmountDiscount: $bag->nullableString('AmountDiscount'), + AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), + PriceQuoteLines: $lines, + Attachments: $bag->has('Attachments') ? $bag->bags('Attachments') : [], + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + UsedTaxrates: $bag->has('UsedTaxrates') ? $bag->bags('UsedTaxrates') : [], + ); + } +} diff --git a/src/Api/Entity/PriceQuoteLine.php b/src/Api/Entity/PriceQuoteLine.php new file mode 100644 index 000000000..4e96da522 --- /dev/null +++ b/src/Api/Entity/PriceQuoteLine.php @@ -0,0 +1,57 @@ +nullableString('Identifier'), + Date: $bag->nullableString('Date'), + Number: $bag->nullableString('Number'), + NumberSuffix: $bag->nullableString('NumberSuffix'), + ProductCode: $bag->nullableString('ProductCode'), + Description: $bag->nullableString('Description'), + PriceExcl: $bag->nullableString('PriceExcl'), + DiscountPercentage: $bag->nullableString('DiscountPercentage'), + DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), + TaxPercentage: $bag->nullableString('TaxPercentage'), + Periods: $bag->nullableString('Periods'), + Periodic: $bag->nullableString('Periodic'), + StartPeriod: $bag->nullableString('StartPeriod'), + EndPeriod: $bag->nullableString('EndPeriod'), + NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), + NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), + DiscountAmountIncl: $bag->nullableString('DiscountAmountIncl'), + DiscountAmountExcl: $bag->nullableString('DiscountAmountExcl'), + ); + } +} diff --git a/src/Api/Entity/Product.php b/src/Api/Entity/Product.php new file mode 100644 index 000000000..13ecc9f24 --- /dev/null +++ b/src/Api/Entity/Product.php @@ -0,0 +1,61 @@ + $Groups + * @param list $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $ProductCode, + public ?string $ProductName, + public ?string $ProductKeyPhrase, + public ?string $ProductDescription, + public ?string $NumberSuffix, + public ?string $PriceExcl, + public ?string $PricePeriod, + public ?string $TaxPercentage, + public ?string $Cost, + public ?string $ProductType, + public ?string $ProductTld, + public ?string $PackageID, + public ?string $HasCustomPrice, + public ?string $Created, + public ?string $Modified, + public array $Groups, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + ProductCode: $bag->nullableString('ProductCode'), + ProductName: $bag->nullableString('ProductName'), + ProductKeyPhrase: $bag->nullableString('ProductKeyPhrase'), + ProductDescription: $bag->nullableString('ProductDescription'), + NumberSuffix: $bag->nullableString('NumberSuffix'), + PriceExcl: $bag->nullableString('PriceExcl'), + PricePeriod: $bag->nullableString('PricePeriod'), + TaxPercentage: $bag->nullableString('TaxPercentage'), + Cost: $bag->nullableString('Cost'), + ProductType: $bag->nullableString('ProductType'), + ProductTld: $bag->nullableString('ProductTld'), + PackageID: $bag->nullableString('PackageID'), + HasCustomPrice: $bag->nullableString('HasCustomPrice'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/Ssl.php b/src/Api/Entity/Ssl.php new file mode 100644 index 000000000..4f7057652 --- /dev/null +++ b/src/Api/Entity/Ssl.php @@ -0,0 +1,75 @@ +nullableString('Identifier'), + CommonName: $bag->nullableString('CommonName'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + Registrar: $bag->nullableString('Registrar'), + SSLTypeID: $bag->nullableString('SSLTypeID'), + OwnerHandle: $bag->nullableString('OwnerHandle'), + AdminHandle: $bag->nullableString('AdminHandle'), + TechHandle: $bag->nullableString('TechHandle'), + Type: $bag->nullableString('Type'), + Wildcard: $bag->nullableString('Wildcard'), + MultiDomain: $bag->nullableString('MultiDomain'), + MultiDomainRecords: $bag->nullableString('MultiDomainRecords'), + ApproverEmail: $bag->nullableString('ApproverEmail'), + CSR: $bag->nullableString('CSR'), + ServerSoftware: $bag->nullableString('ServerSoftware'), + Period: $bag->nullableString('Period'), + RequestDate: $bag->nullableString('RequestDate'), + RenewDate: $bag->nullableString('RenewDate'), + RegistrarReference: $bag->nullableString('RegistrarReference'), + Comment: $bag->nullableString('Comment'), + Status: $bag->nullableString('Status'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, + SSLProductInfo: $bag->has('SSLProductInfo') ? $bag->bag('SSLProductInfo') : null, + RegistrarInfo: $bag->has('RegistrarInfo') ? $bag->bag('RegistrarInfo') : null, + ); + } +} diff --git a/src/Api/Entity/Subscription.php b/src/Api/Entity/Subscription.php new file mode 100644 index 000000000..181cd808d --- /dev/null +++ b/src/Api/Entity/Subscription.php @@ -0,0 +1,65 @@ +nullableString('Number'), + NumberSuffix: $bag->nullableString('NumberSuffix'), + ProductCode: $bag->nullableString('ProductCode'), + Description: $bag->nullableString('Description'), + PriceExcl: $bag->nullableString('PriceExcl'), + PriceIncl: $bag->nullableString('PriceIncl'), + TaxPercentage: $bag->nullableString('TaxPercentage'), + DiscountPercentage: $bag->nullableString('DiscountPercentage'), + Periods: $bag->nullableString('Periods'), + Periodic: $bag->nullableString('Periodic'), + StartPeriod: $bag->nullableString('StartPeriod'), + EndPeriod: $bag->nullableString('EndPeriod'), + NextDate: $bag->nullableString('NextDate'), + ContractPeriods: $bag->nullableString('ContractPeriods'), + ContractPeriodic: $bag->nullableString('ContractPeriodic'), + StartContract: $bag->nullableString('StartContract'), + EndContract: $bag->nullableString('EndContract'), + TerminationDate: $bag->nullableString('TerminationDate'), + Reminder: $bag->nullableString('Reminder'), + InvoiceAuthorisation: $bag->nullableString('InvoiceAuthorisation'), + AmountExcl: $bag->nullableString('AmountExcl'), + AmountIncl: $bag->nullableString('AmountIncl'), + ); + } +} diff --git a/src/Api/Entity/Ticket.php b/src/Api/Entity/Ticket.php new file mode 100644 index 000000000..223ea7af5 --- /dev/null +++ b/src/Api/Entity/Ticket.php @@ -0,0 +1,68 @@ + $TicketMessages + * @param list $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $TicketID, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $EmailAddress, + public ?string $CC, + public ?string $Type, + public ?string $Date, + public ?string $Subject, + public ?string $Owner, + public ?string $Priority, + public ?string $Status, + public ?string $Comment, + public ?string $Number, + public ?string $LastDate, + public ?string $LastName, + public array $TicketMessages, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + $messages = []; + if ($bag->has('TicketMessages')) { + foreach ($bag->bags('TicketMessages') as $msgBag) { + $messages[] = TicketMessage::fromBag($msgBag); + } + } + + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + TicketID: $bag->nullableString('TicketID'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + EmailAddress: $bag->nullableString('EmailAddress'), + CC: $bag->nullableString('CC'), + Type: $bag->nullableString('Type'), + Date: $bag->nullableString('Date'), + Subject: $bag->nullableString('Subject'), + Owner: $bag->nullableString('Owner'), + Priority: $bag->nullableString('Priority'), + Status: $bag->nullableString('Status'), + Comment: $bag->nullableString('Comment'), + Number: $bag->nullableString('Number'), + LastDate: $bag->nullableString('LastDate'), + LastName: $bag->nullableString('LastName'), + TicketMessages: $messages, + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} diff --git a/src/Api/Entity/TicketMessage.php b/src/Api/Entity/TicketMessage.php new file mode 100644 index 000000000..6ac04d5a3 --- /dev/null +++ b/src/Api/Entity/TicketMessage.php @@ -0,0 +1,40 @@ + $Attachments + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $Date, + public ?string $Subject, + public ?string $Base64Message, + public ?string $SenderID, + public ?string $SenderName, + public ?string $SenderEmail, + public array $Attachments, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + Date: $bag->nullableString('Date'), + Subject: $bag->nullableString('Subject'), + Base64Message: $bag->nullableString('Base64Message'), + SenderID: $bag->nullableString('SenderID'), + SenderName: $bag->nullableString('SenderName'), + SenderEmail: $bag->nullableString('SenderEmail'), + Attachments: $bag->has('Attachments') ? $bag->bags('Attachments') : [], + ); + } +} diff --git a/src/Api/Entity/Vps.php b/src/Api/Entity/Vps.php new file mode 100644 index 000000000..6cae0d617 --- /dev/null +++ b/src/Api/Entity/Vps.php @@ -0,0 +1,64 @@ + $Translations + */ + public function __construct( + DataBag $bag, + public ?string $Identifier, + public ?string $Hostname, + public ?string $Debtor, + public ?string $DebtorCode, + public ?string $IPAddress, + public ?string $Package, + public ?string $Node, + public ?string $ServerID, + public ?string $Image, + public ?string $MemoryMB, + public ?string $DiskSpaceGB, + public ?string $BandWidthGB, + public ?string $CPUCores, + public ?string $Comment, + public ?string $Status, + public ?string $Created, + public ?string $Modified, + public ?Subscription $Subscription, + public ?DataBag $NodeInfo, + public array $Translations, + ) { + parent::__construct($bag); + } + + public static function fromBag(DataBag $bag): static + { + return new self( + bag: $bag, + Identifier: $bag->nullableString('Identifier'), + Hostname: $bag->nullableString('Hostname'), + Debtor: $bag->nullableString('Debtor'), + DebtorCode: $bag->nullableString('DebtorCode'), + IPAddress: $bag->nullableString('IPAddress'), + Package: $bag->nullableString('Package'), + Node: $bag->nullableString('Node'), + ServerID: $bag->nullableString('ServerID'), + Image: $bag->nullableString('Image'), + MemoryMB: $bag->nullableString('MemoryMB'), + DiskSpaceGB: $bag->nullableString('DiskSpaceGB'), + BandWidthGB: $bag->nullableString('BandWidthGB'), + CPUCores: $bag->nullableString('CPUCores'), + Comment: $bag->nullableString('Comment'), + Status: $bag->nullableString('Status'), + Created: $bag->nullableString('Created'), + Modified: $bag->nullableString('Modified'), + Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, + NodeInfo: $bag->has('NodeInfo') ? $bag->bag('NodeInfo') : null, + Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], + ); + } +} From dfed547d5603ee98fc32ce01af706f30adb1d652 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:19:23 +0200 Subject: [PATCH 10/30] Add tests, examples, and updated documentation --- README.md | 166 +++++--- examples/customer-onboarding.php | 156 ++++++++ examples/debtors.php | 48 +++ examples/domains.php | 61 +++ examples/error-handling.php | 50 +++ examples/hosting-and-ssl.php | 66 ++++ examples/invoices.php | 67 ++++ tests/Feature/ApiIntegrationTest.php | 256 +++++++++++++ tests/Feature/ControllerTest.php | 75 +++- tests/Feature/ServiceProviderTest.php | 98 +++++ tests/Unit/ApiTest.php | 131 +++++++ tests/Unit/ControllerActionMappingTest.php | 302 +++++++++++++++ tests/Unit/Entity/EntityFactoryTest.php | 92 +++++ tests/Unit/Entity/InvoiceEntityTest.php | 89 +++++ tests/Unit/Entity/ProductEntityTest.php | 88 +++++ tests/Unit/Entity/SubscriptionEntityTest.php | 81 ++++ tests/Unit/FormParameterTest.php | 31 ++ tests/Unit/HostfactApiClientTest.php | 47 ++- tests/Unit/InvalidArgumentExceptionTest.php | 55 +++ tests/Unit/Response/DataBagTest.php | 322 ++++++++++++++++ tests/Unit/Response/PaginationTest.php | 57 +++ tests/Unit/Response/ResponseFactoryTest.php | 377 +++++++++++++++++++ tests/Unit/UrlTest.php | 38 ++ 23 files changed, 2663 insertions(+), 90 deletions(-) create mode 100644 examples/customer-onboarding.php create mode 100644 examples/debtors.php create mode 100644 examples/domains.php create mode 100644 examples/error-handling.php create mode 100644 examples/hosting-and-ssl.php create mode 100644 examples/invoices.php create mode 100644 tests/Feature/ApiIntegrationTest.php create mode 100644 tests/Feature/ServiceProviderTest.php create mode 100644 tests/Unit/ApiTest.php create mode 100644 tests/Unit/ControllerActionMappingTest.php create mode 100644 tests/Unit/Entity/EntityFactoryTest.php create mode 100644 tests/Unit/Entity/InvoiceEntityTest.php create mode 100644 tests/Unit/Entity/ProductEntityTest.php create mode 100644 tests/Unit/Entity/SubscriptionEntityTest.php create mode 100644 tests/Unit/FormParameterTest.php create mode 100644 tests/Unit/InvalidArgumentExceptionTest.php create mode 100644 tests/Unit/Response/DataBagTest.php create mode 100644 tests/Unit/Response/PaginationTest.php create mode 100644 tests/Unit/Response/ResponseFactoryTest.php create mode 100644 tests/Unit/UrlTest.php diff --git a/README.md b/README.md index 19e518c5f..adc4bcb36 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,151 @@ -# Hostfact API 3.0 for Laravel +# Hostfact API v3.1 for Laravel -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fhyperized%2Fhostfact.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fhyperized%2Fhostfact?ref=badge_shield) +[![Run tests](https://github.com/hyperized/hostfact/actions/workflows/main.yml/badge.svg)](https://github.com/hyperized/hostfact/actions/workflows/main.yml) -Official documentation: ------------------------ +Unofficial Laravel package for the [HostFact API v2](https://www.hostfact.nl/developer/api/). -* [Hostfact API documentation](https://www.hostfact.nl/developer/api/) +## Requirements -Installation ------------- +- PHP 8.3+ +- Laravel 13 and above (auto-discovery supported) -Install using composer: +## Installation ```bash composer require hyperized/hostfact ``` -This package supports Package Auto-Discovery (Laravel 5.5+) so it doesn't require you to manually add the -ServiceProvider and alias. +Publish the configuration: -If you are using a lower version of Laravel or not using Auto-Discovery you can add the Hostfact Service Provider to -the `config/app.php` file - -```php -Hyperized\Hostfact\HostfactServiceProvider::class, +```bash +php artisan vendor:publish --provider="Hyperized\Hostfact\Providers\HostfactServiceProvider" --tag="config" ``` -Register an alias for Hostfact, also in `config/app.php`: +## Configuration -```php -'Hostfact' => Hyperized\Hostfact\HostfactServiceProvider::class, +Add these to your `.env` file: + +```env +HOSTFACT_URL=https://yoursite.tld/Pro/apiv2/api.php +HOSTFACT_KEY=your-api-token +HOSTFACT_TIMEOUT=20 ``` -Now publish the Hostfact package into your installation: +Or edit `config/Hostfact.php` directly: -```bash -php artisan vendor:publish --provider="Hyperized\Hostfact\HostfactServiceProvider" --tag="config" +```php +return [ + 'api_v2_url' => env('HOSTFACT_URL', 'https://yoursite.tld/Pro/apiv2/api.php'), + 'api_v2_key' => env('HOSTFACT_KEY', 'token'), + 'api_v2_timeout' => env('HOSTFACT_TIMEOUT', 20), +]; ``` -This should give you a message -like: `Copied File [/vendor/hyperized/hostfact/config/Hostfact.php] To [/config/Hostfact.php]` +## Usage -It's possible to edit your configuration variables in the `config/Hostfact.php` file or you can use the `HOSTFACT_URL` -and `HOSTFACT_KEY` environment variables to store sensitive information in the `.env` file +Every controller provides a static `new()` factory that reads configuration from Laravel automatically: ```php -// config/Hostfact.php -'api_v2_url' => env('HOSTFACT_URL', 'https://yoursite.tld/Pro/apiv2/api.php'), -'api_v2_key' => env('HOSTFACT_KEY', 'token'), -'api_v2_timeout' => env('HOSTFACT_TIMEOUT', 20), +use Hyperized\Hostfact\Api\Controllers\Product; +use Hyperized\Hostfact\Api\Response\ListResponse; -// .env/.env.example -HOSTFACT_URL=https://yoursite.tld/Pro/apiv2/api.php -HOSTFACT_KEY=token -HOSTFACT_TIMEOUT=20 +$response = Product::new()->list(['searchfor' => 'hosting']); + +if ($response instanceof ListResponse) { + echo $response->pagination->totalResults . ' results'; + + foreach ($response->items as $product) { + echo $product->string('ProductName'); + echo $product->float('PriceExcl'); + } +} ``` -Functionality ---------- +For dependency injection or testing, use `fromHttpClient()`: -When writing code for this Hostfact package, consider that this package has been written as a basic interface. +```php +use Hyperized\Hostfact\Api\Controllers\Invoice; + +$invoice = Invoice::fromHttpClient($httpClient); +$result = $invoice->show(['Identifier' => 'F0001']); +``` -This package _will_ do the following: +See the [examples/](examples/) directory for more complete usage patterns. -* Provide an easy way to communicate with Hostfact API controllers; -* Document the available API controller endpoints with methods; -* Transport layer (HTTP/HTTPS) error catching; -* Basic error parsing; +## Typed Responses -This package _will not_: +All API methods return an `ApiResponse` subclass: -* Parameter / input validation; -* Output validation; +| Response Type | When | Properties | +|---|---|---| +| `ShowResponse` | Single entity returned | `data` (DataBag) | +| `ListResponse` | Multiple entities returned | `items` (list of DataBag), `pagination` | +| `ActionResponse` | Action with no entity data (e.g. markAsPaid) | — | +| `ErrorResponse` | API returned an error | `errors` (list of strings) | -You will need to consult the [Hostfact API documentation](https://www.hostfact.nl/developer/api/) to understand the -acceptable input and output for each of the API controllers. +All responses share: `controller`, `action`, `status`, `date`, `isSuccess()`, `isError()`, `toArray()`. -Examples --------- +### DataBag -Example code: +Entity data is accessed through typed methods on `DataBag`: ```php -use \Hyperized\Hostfact\Api\Controllers\Product; +$bag->string('ProductCode') // string +$bag->int('Identifier') // int +$bag->float('PriceExcl') // float +$bag->bool('AutoRenew') // bool (handles "yes"/"no", 1/0) +$bag->nullableString('Comment') // ?string +$bag->nullableInt('PackageID') // ?int +$bag->array('Groups') // array +$bag->bag('Subscription') // nested DataBag +$bag->bags('InvoiceLines') // list +$bag->has('SomeField') // bool +$bag['ProductCode'] // mixed (ArrayAccess) +``` + +## Available Controllers + +| Controller | Actions | +|---|---| +| `CreditInvoice` | show, list, add, edit, delete, partialPayment, markAsPaid, lineAdd, lineDelete, attachmentAdd, attachmentDelete, attachmentDownload | +| `Creditor` | show, list, add, edit, delete, attachmentAdd, attachmentDelete, attachmentDownload | +| `Debtor` | show, list, add, edit, checkLogin, updateLoginCredentials, generatePdf, sendEmail, attachmentAdd, attachmentDelete, attachmentDownload | +| `Domain` | show, list, add, edit, terminate, delete, getToken, lock, unlock, changeNameserver, syncWhois, editWhois, check, transfer, register, autoRenew, listDnsTemplates, getDnsZone, editDnsZone | +| `Group` | show, list, add, edit, delete | +| `Handle` | show, list, add, edit, delete, listDomain | +| `Hosting` | show, list, add, edit, terminate, delete, suspend, unsuspend, create, removeFromServer, getDomainList, emailAccountData, upDowngrade | +| `Invoice` | show, list, add, edit, delete, credit, partialPayment, markAsPaid, markAsUnpaid, sendByEmail, sendReminderByEmail, sendSummationByEmail, download, lineAdd, lineDelete, attachmentAdd, attachmentDelete, attachmentDownload, block, unblock, schedule, cancelSchedule, paymentProcessPause, paymentProcessReactivate | +| `Order` | show, list, add, edit, process, lineAdd, lineDelete | +| `PriceQuote` | show, list, add, edit, delete, sendByEmail, download, accept, decline, lineAdd, lineDelete, attachmentAdd, attachmentDelete, attachmentDownload | +| `Product` | show, list, add, edit, delete | +| `Service` | show, list, add, edit, terminate | +| `Ssl` | show, list, add, edit, terminate, request, markAsInstalled, download, reissue, renew, getStatus, resendApproverEmail, revoke, markAsUninstalled | +| `Ticket` | show, list, add, edit, delete, addMessage, changeStatus, changeOwner, attachmentDownload | +| `Vps` | show, list, add, edit, terminate, create, start, pause, restart, suspend, unsuspend, downloadAccountData, emailAccountData | + +## Design + +This package provides a thin wrapper around the HostFact API. It does **not** validate input parameters. Consult the [HostFact API documentation](https://www.hostfact.nl/developer/api/) for accepted parameters. + +Architecture: +- **Controllers** extend the abstract `Api` class and compose capability **traits** (e.g., `CanShow`, `CanList`, `CanAdd`) +- Each controller implements a corresponding **interface** +- All API methods accept `array` and return typed `ApiResponse` subclasses +- HTTP transport is handled by Guzzle 7.x + +## Testing + +```bash +# Full test suite (PHPMD, PHPStan, PHPCS, phpmnd, PHPUnit, Infection) +composer test + +# PHPUnit only +composer phpunit -- --configuration phpunit.xml.dist -$products = Product::new() - ->list([ - 'searchfor' => 'invoice' - ]); +# Static analysis +composer phpstan -- analyse ``` ## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fhyperized%2Fhostfact.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fhyperized%2Fhostfact?ref=badge_large) \ No newline at end of file +MIT - see [LICENSE](LICENSE) for details. diff --git a/examples/customer-onboarding.php b/examples/customer-onboarding.php new file mode 100644 index 000000000..2d235415c --- /dev/null +++ b/examples/customer-onboarding.php @@ -0,0 +1,156 @@ +add([ + 'CompanyName' => 'Webshop BV', + 'Sex' => 'm', + 'Initials' => 'J.', + 'SurName' => 'de Vries', + 'EmailAddress' => 'jan@webshop-bv.test', + 'Street' => 'Keizersgracht', + 'HouseNumber' => '100', + 'ZipCode' => '1015AA', + 'City' => 'Amsterdam', + 'Country' => 'NL', + 'TaxNumber' => 'NL123456789B01', +]); + +if ($debtorResponse instanceof ErrorResponse) { + echo 'Failed to create customer: ' . implode(', ', $debtorResponse->errors); + exit(1); +} + +assert($debtorResponse instanceof ShowResponse); +$debtorCode = $debtorResponse->data->string('DebtorCode'); +echo "Customer created: {$debtorCode}\n"; + +// --------------------------------------------------------------------------- +// 2. Register a domain for the customer +// --------------------------------------------------------------------------- + +// First check if the domain is available +$checkResponse = Domain::new()->check([ + 'Domain' => 'webshop-bv.nl', +]); + +$domainResponse = Domain::new()->register([ + 'Domain' => 'webshop-bv.nl', + 'DebtorCode' => $debtorCode, +]); + +if ($domainResponse instanceof ErrorResponse) { + echo 'Domain registration failed: ' . implode(', ', $domainResponse->errors); + // Continue anyway - the hosting setup doesn't depend on the domain +} + +// --------------------------------------------------------------------------- +// 3. Set up hosting for the customer +// --------------------------------------------------------------------------- + +$hostingResponse = Hosting::new()->add([ + 'DebtorCode' => $debtorCode, + 'HostingName' => 'webshop-bv.nl', + 'ProductCode' => 'P0001', +]); + +if ($hostingResponse instanceof ErrorResponse) { + echo 'Failed to create hosting: ' . implode(', ', $hostingResponse->errors); + exit(1); +} + +assert($hostingResponse instanceof ShowResponse); +$hostingCode = $hostingResponse->data->string('HostingCode'); +echo "Hosting created: {$hostingCode}\n"; + +// Provision the account on the server +$createResponse = Hosting::new()->create([ + 'HostingCode' => $hostingCode, +]); + +if ($createResponse->isError()) { + echo "Warning: could not provision hosting on server\n"; +} + +// Send the login credentials to the customer +Hosting::new()->emailAccountData([ + 'HostingCode' => $hostingCode, +]); + +// --------------------------------------------------------------------------- +// 4. Create an invoice for the setup +// --------------------------------------------------------------------------- + +$invoiceResponse = Invoice::new()->add([ + 'DebtorCode' => $debtorCode, +]); + +if ($invoiceResponse instanceof ErrorResponse) { + echo 'Failed to create invoice: ' . implode(', ', $invoiceResponse->errors); + exit(1); +} + +assert($invoiceResponse instanceof ShowResponse); +$invoiceCode = $invoiceResponse->data->string('InvoiceCode'); + +// Add the hosting line +Invoice::new()->lineAdd([ + 'InvoiceCode' => $invoiceCode, + 'Description' => 'Webhosting - webshop-bv.nl (1 year)', + 'PriceExcl' => '99.00', + 'TaxPercentage' => '21', +]); + +// Add the domain registration line +Invoice::new()->lineAdd([ + 'InvoiceCode' => $invoiceCode, + 'Description' => 'Domain registration - webshop-bv.nl (1 year)', + 'PriceExcl' => '9.95', + 'TaxPercentage' => '21', +]); + +echo "Invoice created: {$invoiceCode}\n"; + +// --------------------------------------------------------------------------- +// 5. Send the invoice to the customer +// --------------------------------------------------------------------------- + +$sendResponse = Invoice::new()->sendByEmail([ + 'InvoiceCode' => $invoiceCode, +]); + +if ($sendResponse->isSuccess()) { + echo "Invoice {$invoiceCode} sent to jan@webshop-bv.test\n"; +} + +// --------------------------------------------------------------------------- +// 6. Later: mark the invoice as paid when payment arrives +// --------------------------------------------------------------------------- + +$paidResponse = Invoice::new()->markAsPaid([ + 'InvoiceCode' => $invoiceCode, +]); + +if ($paidResponse->isSuccess()) { + echo "Invoice {$invoiceCode} marked as paid\n"; +} diff --git a/examples/debtors.php b/examples/debtors.php new file mode 100644 index 000000000..b0aa6ed09 --- /dev/null +++ b/examples/debtors.php @@ -0,0 +1,48 @@ +list([]); + +// Search for a debtor by company name +$results = Debtor::new()->list([ + 'searchat' => 'CompanyName', + 'searchfor' => 'Acme', +]); + +// Show a specific debtor +$debtor = Debtor::new()->show([ + 'DebtorCode' => 'DB0001', +]); + +// Add a new debtor +$newDebtor = Debtor::new()->add([ + 'CompanyName' => 'Acme Corp', + 'Sex' => 'm', + 'Initials' => 'J.', + 'SurName' => 'Doe', + 'EmailAddress' => 'john@acme.test', + 'Street' => 'Main Street', + 'HouseNumber' => '42', + 'ZipCode' => '1234AB', + 'City' => 'Amsterdam', + 'Country' => 'NL', +]); + +// Edit an existing debtor +$updated = Debtor::new()->edit([ + 'Identifier' => '1', + 'City' => 'Rotterdam', +]); + +// Delete a debtor +$deleted = Debtor::new()->delete([ + 'Identifier' => '1', +]); diff --git a/examples/domains.php b/examples/domains.php new file mode 100644 index 000000000..b2aa92ca2 --- /dev/null +++ b/examples/domains.php @@ -0,0 +1,61 @@ +list([]); + +// Show domain details +$domain = Domain::new()->show([ + 'DomainCode' => 'DM0001', +]); + +// Register a new domain +$registered = Domain::new()->register([ + 'Domain' => 'example.nl', + 'DebtorCode' => 'DB0001', + 'HandleCode' => 'HN0001', +]); + +// Transfer a domain +$transferred = Domain::new()->transfer([ + 'Domain' => 'example.nl', + 'DebtorCode' => 'DB0001', + 'AuthCode' => 'abc123', +]); + +// Edit nameservers +$ns = Domain::new()->changeNameserver([ + 'DomainCode' => 'DM0001', + 'Nameserver1' => 'ns1.example.nl', + 'Nameserver2' => 'ns2.example.nl', +]); + +// Get DNS zone +$dns = Domain::new()->getDnsZone([ + 'DomainCode' => 'DM0001', +]); + +// Edit DNS zone +$updated = Domain::new()->editDnsZone([ + 'DomainCode' => 'DM0001', + 'DNSZone' => [ + ['Name' => '@', 'Type' => 'A', 'Content' => '1.2.3.4', 'TTL' => '3600'], + ], +]); + +// Lock a domain +$locked = Domain::new()->lock([ + 'DomainCode' => 'DM0001', +]); + +// Check domain availability +$available = Domain::new()->check([ + 'Domain' => 'example.nl', +]); diff --git a/examples/error-handling.php b/examples/error-handling.php new file mode 100644 index 000000000..a8eca9534 --- /dev/null +++ b/examples/error-handling.php @@ -0,0 +1,50 @@ +show(['Identifier' => '1']); +} catch (InvalidArgumentException $e) { + // Connection refused, timeout, DNS failure, etc. + echo 'API call failed: ' . $e->getMessage(); +} + +// Check for API-level errors in the response +$response = Product::new()->list(['searchfor' => 'nonexistent']); + +if ($response instanceof ErrorResponse) { + // HostFact returned an error response + foreach ($response->errors as $error) { + echo 'Error: ' . $error; + } +} + +if ($response instanceof ListResponse) { + // Process the results + echo 'Found ' . count($response->items) . ' products'; + + foreach ($response->items as $product) { + echo $product->string('ProductName'); + } +} + +// You can also use the convenience methods +if ($response->isSuccess()) { + echo 'Request succeeded'; +} + +if ($response->isError()) { + echo 'Request failed'; +} diff --git a/examples/hosting-and-ssl.php b/examples/hosting-and-ssl.php new file mode 100644 index 000000000..4557baa23 --- /dev/null +++ b/examples/hosting-and-ssl.php @@ -0,0 +1,66 @@ +list([]); + +// Create a hosting account on the server +$created = Hosting::new()->create([ + 'HostingCode' => 'HO0001', +]); + +// Suspend a hosting account +$suspended = Hosting::new()->suspend([ + 'HostingCode' => 'HO0001', +]); + +// Unsuspend a hosting account +$unsuspended = Hosting::new()->unsuspend([ + 'HostingCode' => 'HO0001', +]); + +// Get domains linked to this hosting +$domains = Hosting::new()->getDomainList([ + 'HostingCode' => 'HO0001', +]); + +// Send account info to customer +$emailed = Hosting::new()->emailAccountData([ + 'HostingCode' => 'HO0001', +]); + +// --- SSL --- + +// List SSL certificates +$certificates = Ssl::new()->list([]); + +// Request a new SSL certificate +$requested = Ssl::new()->request([ + 'SSLCode' => 'SSL0001', +]); + +// Reissue an SSL certificate +$reissued = Ssl::new()->reissue([ + 'SSLCode' => 'SSL0001', +]); + +// Resend approval email +$resent = Ssl::new()->resendApproverEmail([ + 'SSLCode' => 'SSL0001', +]); + +// Revoke a certificate +$revoked = Ssl::new()->revoke([ + 'SSLCode' => 'SSL0001', +]); diff --git a/examples/invoices.php b/examples/invoices.php new file mode 100644 index 000000000..cb00fe1df --- /dev/null +++ b/examples/invoices.php @@ -0,0 +1,67 @@ +list([]); + +// List invoices for a specific debtor +$invoices = Invoice::new()->list([ + 'searchat' => 'DebtorCode', + 'searchfor' => 'DB0001', +]); + +// Show a specific invoice +$invoice = Invoice::new()->show([ + 'InvoiceCode' => 'F0001', +]); + +// Create a new invoice for a debtor +$newInvoice = Invoice::new()->add([ + 'DebtorCode' => 'DB0001', +]); + +// Add a line to an invoice +$line = Invoice::new()->lineAdd([ + 'InvoiceCode' => 'F0001', + 'Description' => 'Web hosting - 1 year', + 'PriceExcl' => '49.99', +]); + +// Send invoice by email +$sent = Invoice::new()->sendByEmail([ + 'InvoiceCode' => 'F0001', +]); + +// Download invoice PDF +$pdf = Invoice::new()->download([ + 'InvoiceCode' => 'F0001', +]); + +// Mark as paid +$paid = Invoice::new()->markAsPaid([ + 'InvoiceCode' => 'F0001', +]); + +// Credit an invoice +$credited = Invoice::new()->credit([ + 'InvoiceCode' => 'F0001', +]); + +// Add an attachment +$attachment = Invoice::new()->attachmentAdd([ + 'InvoiceCode' => 'F0001', + 'Filename' => 'contract.pdf', + 'Base64' => base64_encode(file_get_contents('/path/to/contract.pdf')), +]); + +// Schedule invoice +$scheduled = Invoice::new()->schedule([ + 'InvoiceCode' => 'F0001', +]); diff --git a/tests/Feature/ApiIntegrationTest.php b/tests/Feature/ApiIntegrationTest.php new file mode 100644 index 000000000..cce0253ec --- /dev/null +++ b/tests/Feature/ApiIntegrationTest.php @@ -0,0 +1,256 @@ +set('Hostfact.api_v2_url', 'https://test.hostfact.tld/Pro/apiv2/api.php'); + $app['config']->set('Hostfact.api_v2_key', 'test-api-key-12345'); + $app['config']->set('Hostfact.api_v2_timeout', 10); + } + + private function createController(string $controllerClass, string $responseBody, array &$history): object + { + $mock = new MockHandler([ + new Response(200, [], $responseBody), + ]); + $stack = HandlerStack::create($mock); + $stack->push(Middleware::history($history)); + + $guzzle = new GuzzleClient(['handler' => $stack]); + + $stubClient = $this->createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient')->willReturn($guzzle); + + return $controllerClass::fromHttpClient($stubClient); + } + + /** + * @return array + */ + private function capturedFormParams(array $history): array + { + $body = (string) $history[0]['request']->getBody(); + parse_str($body, $params); + + return $params; + } + + public function testProductListReturnsListResponse(): void + { + $history = []; + $responseBody = json_encode([ + 'controller' => 'product', + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'totalresults' => 2, + 'currentresults' => 2, + 'offset' => 0, + 'products' => [ + ['Identifier' => '1', 'ProductCode' => 'P0001', 'ProductName' => 'Hosting Basic'], + ['Identifier' => '2', 'ProductCode' => 'P0002', 'ProductName' => 'Hosting Pro'], + ], + ]); + + $product = $this->createController(Product::class, $responseBody, $history); + $result = $product->list(['searchfor' => 'Hosting']); + + self::assertInstanceOf(ListResponse::class, $result); + self::assertTrue($result->isSuccess()); + self::assertSame('product', $result->controller); + self::assertSame('list', $result->action); + self::assertCount(2, $result->items); + self::assertSame('Hosting Basic', $result->items[0]->string('ProductName')); + + $params = $this->capturedFormParams($history); + self::assertSame('test-api-key-12345', $params['api_key']); + self::assertSame('product', $params['controller']); + self::assertSame('list', $params['action']); + self::assertSame('Hosting', $params['searchfor']); + } + + public function testDebtorShowReturnsShowResponse(): void + { + $history = []; + $responseBody = json_encode([ + 'controller' => 'debtor', + 'action' => 'show', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'debtor' => [ + 'Identifier' => '42', + 'DebtorCode' => 'DB0001', + 'CompanyName' => 'Acme Corp', + ], + ]); + + $debtor = $this->createController(Debtor::class, $responseBody, $history); + $result = $debtor->show(['DebtorCode' => 'DB0001']); + + self::assertInstanceOf(ShowResponse::class, $result); + self::assertTrue($result->isSuccess()); + self::assertSame('Acme Corp', $result->data->string('CompanyName')); + + $params = $this->capturedFormParams($history); + self::assertSame('debtor', $params['controller']); + self::assertSame('show', $params['action']); + self::assertSame('DB0001', $params['DebtorCode']); + } + + public function testInvoiceAddLineSendsCorrectController(): void + { + $history = []; + $responseBody = json_encode([ + 'controller' => 'invoiceline', + 'action' => 'add', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + $invoice = $this->createController(Invoice::class, $responseBody, $history); + $result = $invoice->lineAdd([ + 'InvoiceCode' => 'F0001', + 'Description' => 'Web hosting', + 'PriceExcl' => '49.99', + ]); + + self::assertInstanceOf(ActionResponse::class, $result); + self::assertTrue($result->isSuccess()); + + $params = $this->capturedFormParams($history); + self::assertSame('invoiceline', $params['controller']); + self::assertSame('add', $params['action']); + self::assertSame('F0001', $params['InvoiceCode']); + self::assertSame('49.99', $params['PriceExcl']); + } + + public function testApiKeyFromConfigIsIncludedInEveryRequest(): void + { + $history = []; + $product = $this->createController(Product::class, json_encode(['status' => 'success']), $history); + + $product->list([]); + + $params = $this->capturedFormParams($history); + self::assertSame('test-api-key-12345', $params['api_key']); + } + + public function testUserInputIsPassedThroughAsFormParams(): void + { + $history = []; + $product = $this->createController(Product::class, json_encode(['status' => 'success']), $history); + + $product->add([ + 'ProductName' => 'New Product', + 'ProductCode' => 'NP001', + 'TaxPercentage' => '21', + ]); + + $params = $this->capturedFormParams($history); + self::assertSame('New Product', $params['ProductName']); + self::assertSame('NP001', $params['ProductCode']); + self::assertSame('21', $params['TaxPercentage']); + self::assertSame('product', $params['controller']); + self::assertSame('add', $params['action']); + } + + public function testErrorResponseIsReturned(): void + { + $history = []; + $responseBody = json_encode([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => ['Product not found'], + ]); + + $product = $this->createController(Product::class, $responseBody, $history); + $result = $product->show(['Identifier' => '999']); + + self::assertInstanceOf(ErrorResponse::class, $result); + self::assertTrue($result->isError()); + self::assertSame(Status::Error, $result->status); + self::assertSame('Product not found', $result->errors[0]); + } + + public function testInvalidJsonResponseReturnsErrorResponse(): void + { + $history = []; + $product = $this->createController(Product::class, 'Server Error', $history); + + $result = $product->list([]); + + self::assertInstanceOf(ErrorResponse::class, $result); + self::assertTrue($result->isError()); + self::assertSame('invalid', $result->controller); + self::assertSame('invalid', $result->action); + self::assertNotEmpty($result->errors); + } + + public function testConnectionFailureThrowsException(): void + { + $mock = new MockHandler([ + new \GuzzleHttp\Exception\ConnectException( + 'cURL error 7: Failed to connect', + new \GuzzleHttp\Psr7\Request('POST', 'https://test.hostfact.tld') + ), + ]); + $stack = HandlerStack::create($mock); + + $stubClient = $this->createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient') + ->willReturn(new GuzzleClient(['handler' => $stack])); + + $product = Product::fromHttpClient($stubClient); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('cURL error 7'); + $product->list([]); + } + + public function testControllerNewUsesLaravelConfig(): void + { + $product = Product::new(); + + $baseUri = (string) $product->getHttpClient()->getHttpClient()->getConfig('base_uri'); + self::assertSame('https://test.hostfact.tld/Pro/apiv2/api.php', $baseUri); + } + + public function testRequestMethodIsPost(): void + { + $history = []; + $product = $this->createController(Product::class, json_encode(['status' => 'success']), $history); + + $product->list([]); + + self::assertSame('POST', $history[0]['request']->getMethod()); + } +} diff --git a/tests/Feature/ControllerTest.php b/tests/Feature/ControllerTest.php index a0e676282..501709312 100644 --- a/tests/Feature/ControllerTest.php +++ b/tests/Feature/ControllerTest.php @@ -3,38 +3,73 @@ namespace Hyperized\Hostfact\Tests\Feature; use Hyperized\Hostfact\Api\Controllers\CreditInvoice; +use Hyperized\Hostfact\Api\Controllers\Creditor; +use Hyperized\Hostfact\Api\Controllers\Debtor; +use Hyperized\Hostfact\Api\Controllers\Domain; +use Hyperized\Hostfact\Api\Controllers\Group; +use Hyperized\Hostfact\Api\Controllers\Handle; +use Hyperized\Hostfact\Api\Controllers\Hosting; +use Hyperized\Hostfact\Api\Controllers\Invoice; +use Hyperized\Hostfact\Api\Controllers\Order; +use Hyperized\Hostfact\Api\Controllers\PriceQuote; +use Hyperized\Hostfact\Api\Controllers\Product; +use Hyperized\Hostfact\Api\Controllers\Service; +use Hyperized\Hostfact\Api\Controllers\Ssl; +use Hyperized\Hostfact\Api\Controllers\Ticket; +use Hyperized\Hostfact\Api\Controllers\Vps; +use Hyperized\Hostfact\Interfaces\HttpClientInterface; use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; class ControllerTest extends TestCase { - protected function setUp(): void + protected function getPackageProviders($app): array { - parent::setUp(); + return [ + 'Hyperized\Hostfact\Providers\HostfactServiceProvider', + ]; } - protected function getPackageProviders($app): array + /** + * @return array + */ + public static function controllerProvider(): array { return [ - 'Hyperized\Hostfact\Providers\HostfactServiceProvider', + 'CreditInvoice' => [CreditInvoice::class], + 'Creditor' => [Creditor::class], + 'Debtor' => [Debtor::class], + 'Domain' => [Domain::class], + 'Group' => [Group::class], + 'Handle' => [Handle::class], + 'Hosting' => [Hosting::class], + 'Invoice' => [Invoice::class], + 'Order' => [Order::class], + 'PriceQuote' => [PriceQuote::class], + 'Product' => [Product::class], + 'Service' => [Service::class], + 'Ssl' => [Ssl::class], + 'Ticket' => [Ticket::class], + 'Vps' => [Vps::class], ]; } - public function testInstantiation(): void + /** + * @param class-string $controllerClass + */ + #[DataProvider('controllerProvider')] + public function testControllerInstantiationViaNew(string $controllerClass): void + { + self::assertIsObject($controllerClass::new()); + } + + /** + * @param class-string $controllerClass + */ + #[DataProvider('controllerProvider')] + public function testControllerInstantiationViaFromHttpClient(string $controllerClass): void { - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); - self::assertIsObject(CreditInvoice::new()); + $mockClient = $this->createStub(HttpClientInterface::class); + self::assertIsObject($controllerClass::fromHttpClient($mockClient)); } } diff --git a/tests/Feature/ServiceProviderTest.php b/tests/Feature/ServiceProviderTest.php new file mode 100644 index 000000000..89b94fc1f --- /dev/null +++ b/tests/Feature/ServiceProviderTest.php @@ -0,0 +1,98 @@ + null]); + + $this->expectException(InvalidArgumentException::class); + + \Hyperized\Hostfact\Api\Controllers\Product::getUrlFromConfig(); + } + + public function testGetUrlFromConfigReturnsString(): void + { + config(['Hostfact.api_v2_url' => 'https://example.com/api.php']); + + $url = \Hyperized\Hostfact\Api\Controllers\Product::getUrlFromConfig(); + + self::assertSame('https://example.com/api.php', $url); + } + + public function testPublishesConfigFile(): void + { + $publishes = ServiceProvider::$publishes[HostfactServiceProvider::class] ?? []; + + self::assertNotEmpty($publishes, 'ServiceProvider should publish config files'); + + $sourceFile = array_key_first($publishes); + self::assertIsString($sourceFile); + self::assertFileExists($sourceFile, 'Published config source file must exist'); + self::assertStringEndsWith('Hostfact.php', $sourceFile); + } + + public function testPublishedConfigSourceContainsExpectedKeys(): void + { + $publishes = ServiceProvider::$publishes[HostfactServiceProvider::class] ?? []; + $sourceFile = array_key_first($publishes); + + self::assertIsString($sourceFile); + + $config = require $sourceFile; + + self::assertIsArray($config); + self::assertArrayHasKey('api_v2_url', $config); + self::assertArrayHasKey('api_v2_key', $config); + self::assertArrayHasKey('api_v2_timeout', $config); + } + + public function testPublishesUnderConfigTag(): void + { + $groups = ServiceProvider::$publishGroups ?? []; + + self::assertArrayHasKey('config', $groups, 'Config should be publishable under "config" tag'); + self::assertNotEmpty($groups['config']); + } + + public function testPublishTargetIsConfigPath(): void + { + $publishes = ServiceProvider::$publishes[HostfactServiceProvider::class] ?? []; + + $target = array_values($publishes)[0] ?? null; + self::assertIsString($target); + self::assertStringEndsWith('Hostfact.php', $target); + } +} diff --git a/tests/Unit/ApiTest.php b/tests/Unit/ApiTest.php new file mode 100644 index 000000000..15e8caa9b --- /dev/null +++ b/tests/Unit/ApiTest.php @@ -0,0 +1,131 @@ +createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient') + ->willReturn(new GuzzleClient(['handler' => $stack])); + + return Product::fromHttpClient($stubClient); + } + + public function testSendRequestParsesJsonResponse(): void + { + $responseBody = json_encode([ + 'controller' => 'product', + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'totalresults' => 1, + 'currentresults' => 1, + 'offset' => 0, + 'products' => [['name' => 'Test']], + ]); + + $controller = $this->createControllerWithMockResponse($responseBody); + $result = $controller->list(); + + self::assertInstanceOf(ListResponse::class, $result); + self::assertSame('product', $result->controller); + self::assertSame('list', $result->action); + self::assertSame(Status::Success, $result->status); + self::assertCount(1, $result->items); + } + + public function testSendRequestHandlesInvalidJsonResponse(): void + { + $controller = $this->createControllerWithMockResponse('not valid json'); + $result = $controller->list(); + + self::assertInstanceOf(ErrorResponse::class, $result); + self::assertSame('invalid', $result->controller); + self::assertSame('invalid', $result->action); + self::assertSame(Status::Error, $result->status); + self::assertNotEmpty($result->errors); + self::assertIsString($result->errors[0]); + } + + public function testSendRequestIncludesApiKeyInFormParams(): void + { + $history = []; + + $mock = new MockHandler([ + new Response(200, [], json_encode(['status' => 'success'])), + ]); + $stack = HandlerStack::create($mock); + $stack->push(Middleware::history($history)); + + $guzzle = new GuzzleClient(['handler' => $stack]); + + $stubClient = $this->createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient')->willReturn($guzzle); + + $controller = Product::fromHttpClient($stubClient); + $controller->show(['Identifier' => '123']); + + $body = (string) $history[0]['request']->getBody(); + parse_str($body, $captured); + + self::assertArrayHasKey('api_key', $captured); + self::assertArrayHasKey('controller', $captured); + self::assertArrayHasKey('action', $captured); + self::assertSame('123', $captured['Identifier']); + } + + public function testSendRequestWrapsGuzzleException(): void + { + $mock = new MockHandler([ + new \GuzzleHttp\Exception\RequestException( + 'Connection refused', + new \GuzzleHttp\Psr7\Request('POST', 'https://example.com') + ), + ]); + $stack = HandlerStack::create($mock); + + $stubClient = $this->createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient') + ->willReturn(new GuzzleClient(['handler' => $stack])); + + $controller = Product::fromHttpClient($stubClient); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Connection refused'); + $controller->show(['Identifier' => '1']); + } + + public function testGetRequestReturnsPOSTMethod(): void + { + $request = Product::getRequest(); + + self::assertSame('POST', $request->getMethod()); + } +} diff --git a/tests/Unit/ControllerActionMappingTest.php b/tests/Unit/ControllerActionMappingTest.php new file mode 100644 index 000000000..46973c88d --- /dev/null +++ b/tests/Unit/ControllerActionMappingTest.php @@ -0,0 +1,302 @@ +} + */ + private function callAndCapture(string $controllerClass, string $method): array + { + $history = []; + + $mock = new MockHandler([ + new Response(200, [], json_encode([ + 'controller' => 'test', + 'action' => 'test', + 'status' => 'success', + ])), + ]); + + $stack = HandlerStack::create($mock); + $stack->push(Middleware::history($history)); + + $guzzle = new GuzzleClient(['handler' => $stack]); + + $stubClient = $this->createStub(HttpClientInterface::class); + $stubClient->method('getHttpClient')->willReturn($guzzle); + + $controller = $controllerClass::fromHttpClient($stubClient); + $controller->$method([]); + + $body = (string) $history[0]['request']->getBody(); + parse_str($body, $params); + + return $params; + } + + /** + * @return array + */ + public static function controllerActionProvider(): array + { + return [ + // Domain + 'Domain::show' => [Domain::class, 'show', 'domain', 'show'], + 'Domain::list' => [Domain::class, 'list', 'domain', 'list'], + 'Domain::add' => [Domain::class, 'add', 'domain', 'add'], + 'Domain::edit' => [Domain::class, 'edit', 'domain', 'edit'], + 'Domain::terminate' => [Domain::class, 'terminate', 'domain', 'terminate'], + 'Domain::delete' => [Domain::class, 'delete', 'domain', 'delete'], + 'Domain::getToken' => [Domain::class, 'getToken', 'domain', 'gettoken'], + 'Domain::lock' => [Domain::class, 'lock', 'domain', 'lock'], + 'Domain::unlock' => [Domain::class, 'unlock', 'domain', 'unlock'], + 'Domain::changeNameserver' => [Domain::class, 'changeNameserver', 'domain', 'changenameserver'], + 'Domain::syncWhois' => [Domain::class, 'syncWhois', 'domain', 'syncwhois'], + 'Domain::editWhois' => [Domain::class, 'editWhois', 'domain', 'editwhois'], + 'Domain::check' => [Domain::class, 'check', 'domain', 'check'], + 'Domain::transfer' => [Domain::class, 'transfer', 'domain', 'transfer'], + 'Domain::register' => [Domain::class, 'register', 'domain', 'register'], + 'Domain::autoRenew' => [Domain::class, 'autoRenew', 'domain', 'autorenew'], + 'Domain::listDnsTemplates' => [Domain::class, 'listDnsTemplates', 'domain', 'listdnstemplates'], + 'Domain::getDnsZone' => [Domain::class, 'getDnsZone', 'domain', 'getdnszone'], + 'Domain::editDnsZone' => [Domain::class, 'editDnsZone', 'domain', 'editdnszone'], + + // Hosting + 'Hosting::show' => [Hosting::class, 'show', 'hosting', 'show'], + 'Hosting::list' => [Hosting::class, 'list', 'hosting', 'list'], + 'Hosting::add' => [Hosting::class, 'add', 'hosting', 'add'], + 'Hosting::edit' => [Hosting::class, 'edit', 'hosting', 'edit'], + 'Hosting::terminate' => [Hosting::class, 'terminate', 'hosting', 'terminate'], + 'Hosting::delete' => [Hosting::class, 'delete', 'hosting', 'delete'], + 'Hosting::suspend' => [Hosting::class, 'suspend', 'hosting', 'suspend'], + 'Hosting::unsuspend' => [Hosting::class, 'unsuspend', 'hosting', 'unsuspend'], + 'Hosting::create' => [Hosting::class, 'create', 'hosting', 'create'], + 'Hosting::removeFromServer' => [Hosting::class, 'removeFromServer', 'hosting', 'removefromserver'], + 'Hosting::getDomainList' => [Hosting::class, 'getDomainList', 'hosting', 'getdomainlist'], + 'Hosting::emailAccountData' => [Hosting::class, 'emailAccountData', 'hosting', 'sendaccountinfobyemail'], + 'Hosting::upDowngrade' => [Hosting::class, 'upDowngrade', 'hosting', 'updowngrade'], + + // Invoice + 'Invoice::show' => [Invoice::class, 'show', 'invoice', 'show'], + 'Invoice::list' => [Invoice::class, 'list', 'invoice', 'list'], + 'Invoice::add' => [Invoice::class, 'add', 'invoice', 'add'], + 'Invoice::edit' => [Invoice::class, 'edit', 'invoice', 'edit'], + 'Invoice::delete' => [Invoice::class, 'delete', 'invoice', 'delete'], + 'Invoice::credit' => [Invoice::class, 'credit', 'invoice', 'credit'], + 'Invoice::partialPayment' => [Invoice::class, 'partialPayment', 'invoice', 'partpayment'], + 'Invoice::markAsPaid' => [Invoice::class, 'markAsPaid', 'invoice', 'markaspaid'], + 'Invoice::markAsUnpaid' => [Invoice::class, 'markAsUnpaid', 'invoice', 'markasunpaid'], + 'Invoice::sendByEmail' => [Invoice::class, 'sendByEmail', 'invoice', 'sendbyemail'], + 'Invoice::sendReminderByEmail' => [Invoice::class, 'sendReminderByEmail', 'invoice', 'sendreminderbyemail'], + 'Invoice::sendSummationByEmail' => [Invoice::class, 'sendSummationByEmail', 'invoice', 'sendsummationbyemail'], + 'Invoice::download' => [Invoice::class, 'download', 'invoice', 'download'], + 'Invoice::lineAdd' => [Invoice::class, 'lineAdd', 'invoiceline', 'add'], + 'Invoice::lineDelete' => [Invoice::class, 'lineDelete', 'invoiceline', 'delete'], + 'Invoice::attachmentAdd' => [Invoice::class, 'attachmentAdd', 'attachment', 'add'], + 'Invoice::attachmentDelete' => [Invoice::class, 'attachmentDelete', 'attachment', 'delete'], + 'Invoice::attachmentDownload' => [Invoice::class, 'attachmentDownload', 'attachment', 'download'], + 'Invoice::block' => [Invoice::class, 'block', 'invoice', 'block'], + 'Invoice::unblock' => [Invoice::class, 'unblock', 'invoice', 'unblock'], + 'Invoice::schedule' => [Invoice::class, 'schedule', 'invoice', 'schedule'], + 'Invoice::cancelSchedule' => [Invoice::class, 'cancelSchedule', 'invoice', 'cancelschedule'], + 'Invoice::paymentProcessPause' => [Invoice::class, 'paymentProcessPause', 'invoice', 'paymentprocesspause'], + 'Invoice::paymentProcessReactivate' => [Invoice::class, 'paymentProcessReactivate', 'invoice', 'paymentprocessreactivate'], + + // Product + 'Product::show' => [Product::class, 'show', 'product', 'show'], + 'Product::list' => [Product::class, 'list', 'product', 'list'], + 'Product::add' => [Product::class, 'add', 'product', 'add'], + 'Product::edit' => [Product::class, 'edit', 'product', 'edit'], + 'Product::delete' => [Product::class, 'delete', 'product', 'delete'], + + // Ticket + 'Ticket::show' => [Ticket::class, 'show', 'ticket', 'show'], + 'Ticket::list' => [Ticket::class, 'list', 'ticket', 'list'], + 'Ticket::add' => [Ticket::class, 'add', 'ticket', 'add'], + 'Ticket::edit' => [Ticket::class, 'edit', 'ticket', 'edit'], + 'Ticket::delete' => [Ticket::class, 'delete', 'ticket', 'delete'], + 'Ticket::addMessage' => [Ticket::class, 'addMessage', 'ticket', 'addmessage'], + 'Ticket::changeStatus' => [Ticket::class, 'changeStatus', 'ticket', 'changestatus'], + 'Ticket::changeOwner' => [Ticket::class, 'changeOwner', 'ticket', 'changeowner'], + 'Ticket::attachmentDownload' => [Ticket::class, 'attachmentDownload', 'attachment', 'download'], + + // Debtor + 'Debtor::show' => [Debtor::class, 'show', 'debtor', 'show'], + 'Debtor::list' => [Debtor::class, 'list', 'debtor', 'list'], + 'Debtor::add' => [Debtor::class, 'add', 'debtor', 'add'], + 'Debtor::edit' => [Debtor::class, 'edit', 'debtor', 'edit'], + 'Debtor::checkLogin' => [Debtor::class, 'checkLogin', 'debtor', 'checklogin'], + 'Debtor::updateLoginCredentials' => [Debtor::class, 'updateLoginCredentials', 'debtor', 'updatelogincredentials'], + 'Debtor::generatePdf' => [Debtor::class, 'generatePdf', 'debtor', 'generatepdf'], + 'Debtor::sendEmail' => [Debtor::class, 'sendEmail', 'debtor', 'sendemail'], + 'Debtor::attachmentAdd' => [Debtor::class, 'attachmentAdd', 'attachment', 'add'], + 'Debtor::attachmentDelete' => [Debtor::class, 'attachmentDelete', 'attachment', 'delete'], + 'Debtor::attachmentDownload' => [Debtor::class, 'attachmentDownload', 'attachment', 'download'], + + // Service + 'Service::show' => [Service::class, 'show', 'service', 'show'], + 'Service::list' => [Service::class, 'list', 'service', 'list'], + 'Service::add' => [Service::class, 'add', 'service', 'add'], + 'Service::edit' => [Service::class, 'edit', 'service', 'edit'], + 'Service::terminate' => [Service::class, 'terminate', 'service', 'terminate'], + + // Order + 'Order::show' => [Order::class, 'show', 'order', 'show'], + 'Order::list' => [Order::class, 'list', 'order', 'list'], + 'Order::add' => [Order::class, 'add', 'order', 'add'], + 'Order::edit' => [Order::class, 'edit', 'order', 'edit'], + 'Order::delete' => [Order::class, 'delete', 'order', 'delete'], + 'Order::process' => [Order::class, 'process', 'order', 'process'], + 'Order::lineAdd' => [Order::class, 'lineAdd', 'orderline', 'add'], + 'Order::lineDelete' => [Order::class, 'lineDelete', 'orderline', 'delete'], + + // SSL + 'Ssl::show' => [Ssl::class, 'show', 'ssl', 'show'], + 'Ssl::list' => [Ssl::class, 'list', 'ssl', 'list'], + 'Ssl::add' => [Ssl::class, 'add', 'ssl', 'add'], + 'Ssl::edit' => [Ssl::class, 'edit', 'ssl', 'edit'], + 'Ssl::terminate' => [Ssl::class, 'terminate', 'ssl', 'terminate'], + 'Ssl::request' => [Ssl::class, 'request', 'ssl', 'request'], + 'Ssl::markAsInstalled' => [Ssl::class, 'markAsInstalled', 'ssl', 'installed'], + 'Ssl::download' => [Ssl::class, 'download', 'ssl', 'download'], + 'Ssl::reissue' => [Ssl::class, 'reissue', 'ssl', 'reissue'], + 'Ssl::renew' => [Ssl::class, 'renew', 'ssl', 'renew'], + 'Ssl::getStatus' => [Ssl::class, 'getStatus', 'ssl', 'getstatus'], + 'Ssl::resendApproverEmail' => [Ssl::class, 'resendApproverEmail', 'ssl', 'resendapprovermail'], + 'Ssl::revoke' => [Ssl::class, 'revoke', 'ssl', 'revoke'], + 'Ssl::markAsUninstalled' => [Ssl::class, 'markAsUninstalled', 'ssl', 'uninstalled'], + + // VPS + 'Vps::show' => [Vps::class, 'show', 'vps', 'show'], + 'Vps::list' => [Vps::class, 'list', 'vps', 'list'], + 'Vps::add' => [Vps::class, 'add', 'vps', 'add'], + 'Vps::edit' => [Vps::class, 'edit', 'vps', 'edit'], + 'Vps::terminate' => [Vps::class, 'terminate', 'vps', 'terminate'], + 'Vps::create' => [Vps::class, 'create', 'vps', 'create'], + 'Vps::start' => [Vps::class, 'start', 'vps', 'start'], + 'Vps::pause' => [Vps::class, 'pause', 'vps', 'pause'], + 'Vps::restart' => [Vps::class, 'restart', 'vps', 'restart'], + 'Vps::suspend' => [Vps::class, 'suspend', 'vps', 'suspend'], + 'Vps::unsuspend' => [Vps::class, 'unsuspend', 'vps', 'unsuspend'], + 'Vps::downloadAccountData' => [Vps::class, 'downloadAccountData', 'vps', 'downloadaccountdata'], + 'Vps::emailAccountData' => [Vps::class, 'emailAccountData', 'vps', 'sendaccountdatabyemail'], + + // Handle + 'Handle::show' => [Handle::class, 'show', 'handle', 'show'], + 'Handle::list' => [Handle::class, 'list', 'handle', 'list'], + 'Handle::add' => [Handle::class, 'add', 'handle', 'add'], + 'Handle::edit' => [Handle::class, 'edit', 'handle', 'edit'], + 'Handle::delete' => [Handle::class, 'delete', 'handle', 'delete'], + 'Handle::listDomain' => [Handle::class, 'listDomain', 'handle', 'listdomain'], + + // Group + 'Group::show' => [Group::class, 'show', 'group', 'show'], + 'Group::list' => [Group::class, 'list', 'group', 'list'], + 'Group::add' => [Group::class, 'add', 'group', 'add'], + 'Group::edit' => [Group::class, 'edit', 'group', 'edit'], + 'Group::delete' => [Group::class, 'delete', 'group', 'delete'], + + // CreditInvoice + 'CreditInvoice::show' => [CreditInvoice::class, 'show', 'creditinvoice', 'show'], + 'CreditInvoice::list' => [CreditInvoice::class, 'list', 'creditinvoice', 'list'], + 'CreditInvoice::add' => [CreditInvoice::class, 'add', 'creditinvoice', 'add'], + 'CreditInvoice::edit' => [CreditInvoice::class, 'edit', 'creditinvoice', 'edit'], + 'CreditInvoice::delete' => [CreditInvoice::class, 'delete', 'creditinvoice', 'delete'], + 'CreditInvoice::partialPayment' => [CreditInvoice::class, 'partialPayment', 'creditinvoice', 'partpayment'], + 'CreditInvoice::markAsPaid' => [CreditInvoice::class, 'markAsPaid', 'creditinvoice', 'markaspaid'], + 'CreditInvoice::lineAdd' => [CreditInvoice::class, 'lineAdd', 'creditinvoiceline', 'add'], + 'CreditInvoice::lineDelete' => [CreditInvoice::class, 'lineDelete', 'creditinvoiceline', 'delete'], + 'CreditInvoice::attachmentAdd' => [CreditInvoice::class, 'attachmentAdd', 'attachment', 'add'], + 'CreditInvoice::attachmentDelete' => [CreditInvoice::class, 'attachmentDelete', 'attachment', 'delete'], + 'CreditInvoice::attachmentDownload' => [CreditInvoice::class, 'attachmentDownload', 'attachment', 'download'], + + // Creditor + 'Creditor::show' => [Creditor::class, 'show', 'creditor', 'show'], + 'Creditor::list' => [Creditor::class, 'list', 'creditor', 'list'], + 'Creditor::add' => [Creditor::class, 'add', 'creditor', 'add'], + 'Creditor::edit' => [Creditor::class, 'edit', 'creditor', 'edit'], + 'Creditor::delete' => [Creditor::class, 'delete', 'creditor', 'delete'], + 'Creditor::attachmentAdd' => [Creditor::class, 'attachmentAdd', 'attachment', 'add'], + 'Creditor::attachmentDelete' => [Creditor::class, 'attachmentDelete', 'attachment', 'delete'], + 'Creditor::attachmentDownload' => [Creditor::class, 'attachmentDownload', 'attachment', 'download'], + + // PriceQuote + 'PriceQuote::show' => [PriceQuote::class, 'show', 'pricequote', 'show'], + 'PriceQuote::list' => [PriceQuote::class, 'list', 'pricequote', 'list'], + 'PriceQuote::add' => [PriceQuote::class, 'add', 'pricequote', 'add'], + 'PriceQuote::edit' => [PriceQuote::class, 'edit', 'pricequote', 'edit'], + 'PriceQuote::delete' => [PriceQuote::class, 'delete', 'pricequote', 'delete'], + 'PriceQuote::sendByEmail' => [PriceQuote::class, 'sendByEmail', 'pricequote', 'sendbyemail'], + 'PriceQuote::download' => [PriceQuote::class, 'download', 'pricequote', 'download'], + 'PriceQuote::accept' => [PriceQuote::class, 'accept', 'pricequote', 'accept'], + 'PriceQuote::decline' => [PriceQuote::class, 'decline', 'pricequote', 'decline'], + 'PriceQuote::lineAdd' => [PriceQuote::class, 'lineAdd', 'pricequoteline', 'add'], + 'PriceQuote::lineDelete' => [PriceQuote::class, 'lineDelete', 'pricequoteline', 'delete'], + 'PriceQuote::attachmentAdd' => [PriceQuote::class, 'attachmentAdd', 'attachment', 'add'], + 'PriceQuote::attachmentDelete' => [PriceQuote::class, 'attachmentDelete', 'attachment', 'delete'], + 'PriceQuote::attachmentDownload' => [PriceQuote::class, 'attachmentDownload', 'attachment', 'download'], + ]; + } + + /** + * @param class-string $controllerClass + */ + #[DataProvider('controllerActionProvider')] + public function testControllerSendsCorrectAction( + string $controllerClass, + string $method, + string $expectedController, + string $expectedAction + ): void { + $params = $this->callAndCapture($controllerClass, $method); + + self::assertSame( + $expectedController, + $params['controller'], + "Controller name mismatch for {$controllerClass}::{$method}" + ); + self::assertSame( + $expectedAction, + $params['action'], + "Action name mismatch for {$controllerClass}::{$method}" + ); + } +} diff --git a/tests/Unit/Entity/EntityFactoryTest.php b/tests/Unit/Entity/EntityFactoryTest.php new file mode 100644 index 000000000..1429f34d6 --- /dev/null +++ b/tests/Unit/Entity/EntityFactoryTest.php @@ -0,0 +1,92 @@ + + */ + public static function controllerEntityProvider(): array + { + return [ + 'product' => ['product', Product::class], + 'debtor' => ['debtor', Debtor::class], + 'invoice' => ['invoice', Invoice::class], + 'domain' => ['domain', Domain::class], + 'hosting' => ['hosting', Hosting::class], + 'ssl' => ['ssl', Ssl::class], + 'vps' => ['vps', Vps::class], + 'ticket' => ['ticket', Ticket::class], + 'order' => ['order', Order::class], + 'pricequote' => ['pricequote', PriceQuote::class], + 'creditor' => ['creditor', Creditor::class], + 'group' => ['group', Group::class], + ]; + } + + /** + * @param class-string $expectedClass + */ + #[DataProvider('controllerEntityProvider')] + public function testFactoryReturnsCorrectEntityType(string $controller, string $expectedClass): void + { + $bag = new DataBag(['Identifier' => '1']); + $entity = EntityFactory::fromBag($controller, $bag); + + self::assertInstanceOf($expectedClass, $entity); + } + + #[DataProvider('controllerEntityProvider')] + public function testEntityBagIsAccessible(string $controller, string $expectedClass): void + { + $bag = new DataBag(['Identifier' => '42']); + $entity = EntityFactory::fromBag($controller, $bag); + + self::assertInstanceOf(Entity::class, $entity); + self::assertSame('42', $entity->bag->string('Identifier')); + } + + public function testUnknownControllerReturnsBag(): void + { + $bag = new DataBag(['Identifier' => '1']); + $result = EntityFactory::fromBag('creditinvoice', $bag); + + self::assertInstanceOf(DataBag::class, $result); + self::assertSame($bag, $result); + } + + public function testServiceControllerReturnsBag(): void + { + $bag = new DataBag(['Identifier' => '1']); + $result = EntityFactory::fromBag('service', $bag); + + self::assertInstanceOf(DataBag::class, $result); + } + + public function testHandleControllerReturnsBag(): void + { + $bag = new DataBag(['Identifier' => '1']); + $result = EntityFactory::fromBag('handle', $bag); + + self::assertInstanceOf(DataBag::class, $result); + } +} diff --git a/tests/Unit/Entity/InvoiceEntityTest.php b/tests/Unit/Entity/InvoiceEntityTest.php new file mode 100644 index 000000000..25a0fde2f --- /dev/null +++ b/tests/Unit/Entity/InvoiceEntityTest.php @@ -0,0 +1,89 @@ + '10', + 'InvoiceCode' => 'F0001', + 'DebtorCode' => 'DB0001', + 'Status' => '2', + 'AmountExcl' => '100.00', + 'AmountIncl' => '121.00', + ]); + + $invoice = Invoice::fromBag($bag); + + self::assertSame('10', $invoice->Identifier); + self::assertSame('F0001', $invoice->InvoiceCode); + self::assertSame('DB0001', $invoice->DebtorCode); + self::assertSame('100.00', $invoice->AmountExcl); + self::assertEmpty($invoice->InvoiceLines); + } + + public function testFromBagHydratesInvoiceLines(): void + { + $bag = new DataBag([ + 'Identifier' => '10', + 'InvoiceLines' => [ + [ + 'Identifier' => '1', + 'Description' => 'Web hosting', + 'PriceExcl' => '49.99', + 'TaxPercentage' => '21', + 'ProductCode' => 'P001', + ], + [ + 'Identifier' => '2', + 'Description' => 'Domain .nl', + 'PriceExcl' => '9.95', + 'TaxPercentage' => '21', + ], + ], + ]); + + $invoice = Invoice::fromBag($bag); + + self::assertCount(2, $invoice->InvoiceLines); + self::assertInstanceOf(InvoiceLine::class, $invoice->InvoiceLines[0]); + self::assertSame('Web hosting', $invoice->InvoiceLines[0]->Description); + self::assertSame('49.99', $invoice->InvoiceLines[0]->PriceExcl); + self::assertSame('P001', $invoice->InvoiceLines[0]->ProductCode); + self::assertSame('Domain .nl', $invoice->InvoiceLines[1]->Description); + } + + public function testInvoiceLineAccessesUndocumentedFields(): void + { + $bag = new DataBag([ + 'InvoiceLines' => [ + [ + 'Identifier' => '1', + 'CustomField' => 'extra', + ], + ], + ]); + + $invoice = Invoice::fromBag($bag); + $line = $invoice->InvoiceLines[0]; + + self::assertSame('extra', $line->bag->string('CustomField')); + } + + public function testMissingNestedArraysDefaultToEmpty(): void + { + $invoice = Invoice::fromBag(new DataBag([])); + + self::assertEmpty($invoice->InvoiceLines); + self::assertEmpty($invoice->Attachments); + self::assertEmpty($invoice->Translations); + self::assertEmpty($invoice->UsedTaxrates); + } +} diff --git a/tests/Unit/Entity/ProductEntityTest.php b/tests/Unit/Entity/ProductEntityTest.php new file mode 100644 index 000000000..af7790abf --- /dev/null +++ b/tests/Unit/Entity/ProductEntityTest.php @@ -0,0 +1,88 @@ + '3', + 'ProductCode' => 'P001', + 'ProductName' => 'Hosting Basic', + 'ProductKeyPhrase' => 'Basic hosting', + 'ProductDescription' => 'A basic plan', + 'NumberSuffix' => '', + 'PriceExcl' => '250', + 'PricePeriod' => 'm', + 'TaxPercentage' => '21', + 'Cost' => '0', + 'ProductType' => 'hosting', + 'ProductTld' => '', + 'PackageID' => '1', + 'HasCustomPrice' => 'no', + 'Created' => '2022-11-24 11:00:00', + 'Modified' => '2022-11-24 11:00:00', + 'Groups' => [], + 'Translations' => [ + ['ProductType' => 'Hosting', 'PricePeriod' => 'per maand'], + ], + ]); + + $product = Product::fromBag($bag); + + self::assertSame('3', $product->Identifier); + self::assertSame('P001', $product->ProductCode); + self::assertSame('Hosting Basic', $product->ProductName); + self::assertSame('Basic hosting', $product->ProductKeyPhrase); + self::assertSame('250', $product->PriceExcl); + self::assertSame('21', $product->TaxPercentage); + self::assertSame('hosting', $product->ProductType); + self::assertSame('no', $product->HasCustomPrice); + self::assertSame('2022-11-24 11:00:00', $product->Created); + self::assertEmpty($product->Groups); + self::assertCount(1, $product->Translations); + } + + public function testMissingFieldsReturnNull(): void + { + $bag = new DataBag(['Identifier' => '1']); + + $product = Product::fromBag($bag); + + self::assertSame('1', $product->Identifier); + self::assertNull($product->ProductCode); + self::assertNull($product->ProductName); + self::assertNull($product->PriceExcl); + self::assertNull($product->TaxPercentage); + self::assertNull($product->Created); + self::assertEmpty($product->Groups); + self::assertEmpty($product->Translations); + } + + public function testBagPropertyProvidesRawAccess(): void + { + $bag = new DataBag([ + 'Identifier' => '1', + 'UndocumentedField' => 'secret', + ]); + + $product = Product::fromBag($bag); + + self::assertSame('secret', $product->bag->string('UndocumentedField')); + } + + public function testEmptyBagProducesAllNulls(): void + { + $product = Product::fromBag(new DataBag([])); + + self::assertNull($product->Identifier); + self::assertNull($product->ProductCode); + self::assertNull($product->ProductName); + self::assertEmpty($product->Groups); + } +} diff --git a/tests/Unit/Entity/SubscriptionEntityTest.php b/tests/Unit/Entity/SubscriptionEntityTest.php new file mode 100644 index 000000000..783b0f1e4 --- /dev/null +++ b/tests/Unit/Entity/SubscriptionEntityTest.php @@ -0,0 +1,81 @@ + '1', + 'ProductCode' => 'P002', + 'Description' => 'Hosting small', + 'PriceExcl' => '25', + 'PriceIncl' => '30.25', + 'TaxPercentage' => '21', + 'Periods' => '1', + 'Periodic' => 'm', + 'StartPeriod' => '2018-03-14', + 'EndPeriod' => '2018-04-14', + 'InvoiceAuthorisation' => 'yes', + ]); + + $sub = Subscription::fromBag($bag); + + self::assertSame('1', $sub->Number); + self::assertSame('P002', $sub->ProductCode); + self::assertSame('25', $sub->PriceExcl); + self::assertSame('30.25', $sub->PriceIncl); + self::assertSame('m', $sub->Periodic); + self::assertSame('yes', $sub->InvoiceAuthorisation); + } + + public function testMissingFieldsReturnNull(): void + { + $sub = Subscription::fromBag(new DataBag([])); + + self::assertNull($sub->Number); + self::assertNull($sub->ProductCode); + self::assertNull($sub->PriceExcl); + self::assertNull($sub->Periodic); + } + + public function testBagIsAccessible(): void + { + $bag = new DataBag(['Number' => '1', 'Extra' => 'val']); + $sub = Subscription::fromBag($bag); + + self::assertSame('val', $sub->bag->string('Extra')); + } + + public function testHostingEntityHydratesSubscription(): void + { + $bag = new DataBag([ + 'Identifier' => '2', + 'DebtorCode' => 'DB0001', + 'Subscription' => [ + 'ProductCode' => 'P002', + 'PriceExcl' => '25', + 'Periodic' => 'm', + ], + ]); + + $hosting = Hosting::fromBag($bag); + + self::assertInstanceOf(Subscription::class, $hosting->Subscription); + self::assertSame('P002', $hosting->Subscription->ProductCode); + self::assertSame('25', $hosting->Subscription->PriceExcl); + } + + public function testHostingWithoutSubscriptionIsNull(): void + { + $hosting = Hosting::fromBag(new DataBag(['Identifier' => '1'])); + + self::assertNull($hosting->Subscription); + } +} diff --git a/tests/Unit/FormParameterTest.php b/tests/Unit/FormParameterTest.php new file mode 100644 index 000000000..17417d6de --- /dev/null +++ b/tests/Unit/FormParameterTest.php @@ -0,0 +1,31 @@ + 'value', 'nested' => ['a' => 1]]; + $param = FormParameter::fromArray($data); + + self::assertSame($data, $param->toArray()); + } + + public function testFromArrayWithEmptyArray(): void + { + $param = FormParameter::fromArray(); + + self::assertSame([], $param->toArray()); + } + + public function testFromArrayWithExplicitEmptyArray(): void + { + $param = FormParameter::fromArray([]); + + self::assertSame([], $param->toArray()); + } +} diff --git a/tests/Unit/HostfactApiClientTest.php b/tests/Unit/HostfactApiClientTest.php index 80d41ac37..167a674cd 100644 --- a/tests/Unit/HostfactApiClientTest.php +++ b/tests/Unit/HostfactApiClientTest.php @@ -2,11 +2,12 @@ namespace Hyperized\Hostfact\Tests\Unit; -use GuzzleHttp\Exception\GuzzleException; +use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Exception\RequestException; -use Hyperized\Hostfact\Exceptions\InvalidArgumentException; +use GuzzleHttp\HandlerStack; use Hyperized\Hostfact\Http\HttpClient; -use Hyperized\Hostfact\Types\Url; +use Hyperized\ValueObjects\Concretes\Strings\Url; +use Hyperized\ValueObjects\Exceptions\StringException; use Orchestra\Testbench\TestCase; class HostfactApiClientTest extends TestCase @@ -17,13 +18,10 @@ protected function setUp(): void { parent::setUp(); $this->instance = HttpClient::new( - Url::fromString('test://hostfact.tld/Pro/apiv2/api.php') + Url::fromString('https://example.com/api.php') ); } - /** - * @throws GuzzleException - */ public function testDoFakeRequest(): void { $this->expectException(RequestException::class); @@ -32,21 +30,40 @@ public function testDoFakeRequest(): void public function testInvalidUrl(): void { - $this->expectException(InvalidArgumentException::class); + $this->expectException(StringException::class); Url::fromString('!?Invalid'); } - public function testHttpClient(): void + public function testHttpClientReturnsGuzzleClient(): void { - self::assertIsObject( - $this->instance->getHttpClient() - ); + self::assertInstanceOf(GuzzleClient::class, $this->instance->getHttpClient()); } public function testCanGetStack(): void { - self::assertIsObject( - $this->instance->getStack() - ); + self::assertInstanceOf(HandlerStack::class, $this->instance->getStack()); + } + + public function testHttpClientHasConfiguredBaseUri(): void + { + $baseUri = (string) $this->instance->getHttpClient()->getConfig('base_uri'); + + self::assertSame('https://example.com/api.php', $baseUri); + } + + public function testHttpClientHasConfiguredUserAgent(): void + { + $headers = $this->instance->getHttpClient()->getConfig('headers'); + + self::assertArrayHasKey('User-Agent', $headers); + self::assertStringContainsString('hyperized/hostfact', $headers['User-Agent']); + } + + public function testHttpClientHasHandlerStack(): void + { + $handler = $this->instance->getHttpClient()->getConfig('handler'); + + self::assertInstanceOf(HandlerStack::class, $handler); + self::assertSame($this->instance->getStack(), $handler); } } diff --git a/tests/Unit/InvalidArgumentExceptionTest.php b/tests/Unit/InvalidArgumentExceptionTest.php new file mode 100644 index 000000000..769763c3d --- /dev/null +++ b/tests/Unit/InvalidArgumentExceptionTest.php @@ -0,0 +1,55 @@ +getMessage() + ); + } + + public function testApiFailedPreservesExceptionMessage(): void + { + $guzzleException = new RequestException( + 'Timeout exceeded', + new Request('POST', 'https://example.com') + ); + + $exception = InvalidArgumentException::apiFailed($guzzleException); + + self::assertStringStartsWith('API call returned an invalid response: ', $exception->getMessage()); + self::assertStringEndsWith('.', $exception->getMessage()); + self::assertStringContainsString('Timeout exceeded', $exception->getMessage()); + } + + public function testConfigVariableNotAString(): void + { + $exception = InvalidArgumentException::configVariableNotAString(); + + self::assertStringContainsString('not a string', $exception->getMessage()); + } + + public function testAllExceptionsExtendInvalidArgumentException(): void + { + self::assertInstanceOf( + \InvalidArgumentException::class, + InvalidArgumentException::configVariableNotAString() + ); + } +} diff --git a/tests/Unit/Response/DataBagTest.php b/tests/Unit/Response/DataBagTest.php new file mode 100644 index 000000000..ed5f1f3ee --- /dev/null +++ b/tests/Unit/Response/DataBagTest.php @@ -0,0 +1,322 @@ + 'Test']); + self::assertSame('Test', $bag->string('Name')); + } + + public function testStringCastsIntToString(): void + { + $bag = new DataBag(['Code' => 123]); + self::assertSame('123', $bag->string('Code')); + } + + public function testStringThrowsOnMissingKey(): void + { + $bag = new DataBag([]); + + try { + $bag->string('Name'); + self::fail('Expected InvalidArgumentException was not thrown'); + } catch (\InvalidArgumentException $e) { + self::assertSame("Required field 'Name' is missing", $e->getMessage()); + } + } + + public function testStringThrowsOnNonScalar(): void + { + $bag = new DataBag(['Name' => ['array']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Name' cannot be cast to string"); + $bag->string('Name'); + } + + public function testIntThrowsOnNonScalar(): void + { + $bag = new DataBag(['Id' => ['array']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Id' cannot be cast to int"); + $bag->int('Id'); + } + + public function testFloatThrowsOnNonScalar(): void + { + $bag = new DataBag(['Price' => ['array']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Price' cannot be cast to float"); + $bag->float('Price'); + } + + public function testBoolThrowsOnNonScalar(): void + { + $bag = new DataBag(['Flag' => ['array']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("cannot be cast to bool"); + $bag->bool('Flag'); + } + + public function testIntReturnsValue(): void + { + $bag = new DataBag(['Identifier' => 42]); + self::assertSame(42, $bag->int('Identifier')); + } + + public function testIntCastsStringToInt(): void + { + $bag = new DataBag(['Identifier' => '42']); + self::assertSame(42, $bag->int('Identifier')); + } + + public function testFloatReturnsValue(): void + { + $bag = new DataBag(['PriceExcl' => 49.99]); + self::assertSame(49.99, $bag->float('PriceExcl')); + } + + public function testFloatCastsStringToFloat(): void + { + $bag = new DataBag(['PriceExcl' => '49.99']); + self::assertSame(49.99, $bag->float('PriceExcl')); + } + + public function testBoolHandlesYesNo(): void + { + $bag = new DataBag(['AutoRenew' => 'yes', 'Blocked' => 'no']); + self::assertTrue($bag->bool('AutoRenew')); + self::assertFalse($bag->bool('Blocked')); + } + + public function testBoolHandlesTrueFalse(): void + { + $bag = new DataBag(['Active' => true, 'Deleted' => false]); + self::assertTrue($bag->bool('Active')); + self::assertFalse($bag->bool('Deleted')); + } + + public function testBoolHandlesOneZero(): void + { + $bag = new DataBag(['Flag' => 1, 'Off' => 0]); + self::assertTrue($bag->bool('Flag')); + self::assertFalse($bag->bool('Off')); + } + + public function testBoolHandlesStringOneZero(): void + { + $bag = new DataBag(['Flag' => '1', 'Off' => '0']); + self::assertTrue($bag->bool('Flag')); + self::assertFalse($bag->bool('Off')); + } + + public function testBoolThrowsOnUnexpectedValue(): void + { + $bag = new DataBag(['Status' => 'maybe']); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Status' cannot be cast to bool, got: 'maybe'"); + $bag->bool('Status'); + } + + public function testNullableStringReturnsValue(): void + { + $bag = new DataBag(['Comment' => 'hello']); + self::assertSame('hello', $bag->nullableString('Comment')); + } + + public function testNullableStringReturnsNullForMissing(): void + { + $bag = new DataBag([]); + self::assertNull($bag->nullableString('Comment')); + } + + public function testNullableStringReturnsNullForNull(): void + { + $bag = new DataBag(['Comment' => null]); + self::assertNull($bag->nullableString('Comment')); + } + + public function testNullableStringCastsIntToString(): void + { + $bag = new DataBag(['Code' => 123]); + self::assertSame('123', $bag->nullableString('Code')); + } + + public function testNullableStringThrowsOnNonScalar(): void + { + $bag = new DataBag(['Data' => ['nested']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Data' cannot be cast to string"); + $bag->nullableString('Data'); + } + + public function testNullableIntReturnsValue(): void + { + $bag = new DataBag(['PackageID' => 5]); + self::assertSame(5, $bag->nullableInt('PackageID')); + } + + public function testNullableIntReturnsNullForMissing(): void + { + $bag = new DataBag([]); + self::assertNull($bag->nullableInt('PackageID')); + } + + public function testNullableIntReturnsNullForNull(): void + { + $bag = new DataBag(['PackageID' => null]); + self::assertNull($bag->nullableInt('PackageID')); + } + + public function testNullableIntCastsStringToInt(): void + { + $bag = new DataBag(['PackageID' => '42']); + self::assertSame(42, $bag->nullableInt('PackageID')); + } + + public function testNullableIntThrowsOnNonScalar(): void + { + $bag = new DataBag(['Data' => ['nested']]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Data' cannot be cast to int"); + $bag->nullableInt('Data'); + } + + public function testArrayReturnsValue(): void + { + $bag = new DataBag(['Groups' => ['A', 'B']]); + self::assertSame(['A', 'B'], $bag->array('Groups')); + } + + public function testArrayThrowsOnNonArray(): void + { + $bag = new DataBag(['Groups' => 'notarray']); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('not an array'); + $bag->array('Groups'); + } + + public function testBagReturnsNestedDataBag(): void + { + $bag = new DataBag(['Subscription' => ['ProductCode' => 'P001', 'PriceExcl' => 10.0]]); + $sub = $bag->bag('Subscription'); + + self::assertInstanceOf(DataBag::class, $sub); + self::assertSame('P001', $sub->string('ProductCode')); + self::assertSame(10.0, $sub->float('PriceExcl')); + } + + public function testBagsReturnsListOfDataBags(): void + { + $bag = new DataBag([ + 'Lines' => [ + ['Description' => 'Line 1'], + ['Description' => 'Line 2'], + ], + ]); + + $lines = $bag->bags('Lines'); + self::assertCount(2, $lines); + self::assertSame('Line 1', $lines[0]->string('Description')); + self::assertSame('Line 2', $lines[1]->string('Description')); + } + + public function testBagsWithStringKeysReindexesNumerically(): void + { + $bag = new DataBag([ + 'Lines' => [ + 'first' => ['Description' => 'A'], + 'second' => ['Description' => 'B'], + ], + ]); + + $lines = $bag->bags('Lines'); + self::assertCount(2, $lines); + self::assertSame('A', $lines[0]->string('Description')); + self::assertSame('B', $lines[1]->string('Description')); + } + + public function testBagsSkipsNonArrayItems(): void + { + $bag = new DataBag([ + 'Lines' => [ + ['Description' => 'Valid'], + 'not an array', + 42, + ], + ]); + + $lines = $bag->bags('Lines'); + self::assertCount(1, $lines); + self::assertSame('Valid', $lines[0]->string('Description')); + } + + public function testHasReturnsTrueForExistingKey(): void + { + $bag = new DataBag(['Name' => 'Test']); + self::assertTrue($bag->has('Name')); + } + + public function testHasReturnsFalseForMissingKey(): void + { + $bag = new DataBag([]); + self::assertFalse($bag->has('Name')); + } + + public function testToArrayReturnsRawData(): void + { + $data = ['Identifier' => 1, 'Name' => 'Test']; + $bag = new DataBag($data); + self::assertSame($data, $bag->toArray()); + } + + public function testArrayAccessOffsetExists(): void + { + $bag = new DataBag(['Name' => 'Test']); + self::assertTrue(isset($bag['Name'])); + self::assertFalse(isset($bag['Missing'])); + } + + public function testArrayAccessOffsetGet(): void + { + $bag = new DataBag(['Name' => 'Test']); + self::assertSame('Test', $bag['Name']); + } + + public function testArrayAccessOffsetGetReturnsNullForMissing(): void + { + $bag = new DataBag([]); + self::assertNull($bag['Missing']); + } + + public function testArrayAccessOffsetSetThrows(): void + { + $bag = new DataBag([]); + $this->expectException(\LogicException::class); + $bag['Name'] = 'Test'; + } + + public function testArrayAccessOffsetUnsetThrows(): void + { + $bag = new DataBag(['Name' => 'Test']); + $this->expectException(\LogicException::class); + unset($bag['Name']); + } + + public function testCountReturnsFieldCount(): void + { + $bag = new DataBag(['A' => 1, 'B' => 2, 'C' => 3]); + self::assertCount(3, $bag); + } + + public function testCountReturnsZeroForEmpty(): void + { + $bag = new DataBag([]); + self::assertCount(0, $bag); + } +} diff --git a/tests/Unit/Response/PaginationTest.php b/tests/Unit/Response/PaginationTest.php new file mode 100644 index 000000000..6bace339b --- /dev/null +++ b/tests/Unit/Response/PaginationTest.php @@ -0,0 +1,57 @@ + 50, + 'currentresults' => 10, + 'offset' => 20, + ]); + + self::assertSame(50, $pagination->totalResults); + self::assertSame(10, $pagination->currentResults); + self::assertSame(20, $pagination->offset); + } + + public function testFromArrayDefaultsToZero(): void + { + $pagination = Pagination::fromArray([]); + + self::assertSame(0, $pagination->totalResults); + self::assertSame(0, $pagination->currentResults); + self::assertSame(0, $pagination->offset); + } + + public function testFromArrayCastsStringsToInt(): void + { + $pagination = Pagination::fromArray([ + 'totalresults' => '25', + 'currentresults' => '10', + 'offset' => '5', + ]); + + self::assertSame(25, $pagination->totalResults); + self::assertSame(10, $pagination->currentResults); + self::assertSame(5, $pagination->offset); + } + + public function testFromArrayFallsBackToZeroForNonScalar(): void + { + $pagination = Pagination::fromArray([ + 'totalresults' => ['not', 'scalar'], + 'currentresults' => ['not', 'scalar'], + 'offset' => ['not', 'scalar'], + ]); + + self::assertSame(0, $pagination->totalResults); + self::assertSame(0, $pagination->currentResults); + self::assertSame(0, $pagination->offset); + } +} diff --git a/tests/Unit/Response/ResponseFactoryTest.php b/tests/Unit/Response/ResponseFactoryTest.php new file mode 100644 index 000000000..45617dd32 --- /dev/null +++ b/tests/Unit/Response/ResponseFactoryTest.php @@ -0,0 +1,377 @@ + 'product', + 'action' => 'show', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => ['Product not found'], + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertTrue($response->isError()); + self::assertFalse($response->isSuccess()); + self::assertSame(Status::Error, $response->status); + self::assertSame('product', $response->controller); + self::assertSame('show', $response->action); + self::assertSame(['Product not found'], $response->errors); + } + + public function testShowResponseIsCreatedForSingularEntityKey(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'product' => [ + 'Identifier' => 1, + 'ProductCode' => 'P001', + 'ProductName' => 'Hosting Basic', + ], + ]); + + self::assertInstanceOf(ShowResponse::class, $response); + self::assertTrue($response->isSuccess()); + self::assertSame('P001', $response->data->string('ProductCode')); + self::assertSame(1, $response->data->int('Identifier')); + self::assertInstanceOf(Product::class, $response->entity); + self::assertSame('P001', $response->entity->ProductCode); + } + + public function testListResponseIsCreatedForPluralEntityKey(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'totalresults' => 2, + 'currentresults' => 2, + 'offset' => 0, + 'products' => [ + ['Identifier' => 1, 'ProductName' => 'Basic'], + ['Identifier' => 2, 'ProductName' => 'Pro'], + ], + ]); + + self::assertInstanceOf(ListResponse::class, $response); + self::assertTrue($response->isSuccess()); + self::assertSame(2, $response->pagination->totalResults); + self::assertSame(2, $response->pagination->currentResults); + self::assertSame(0, $response->pagination->offset); + self::assertCount(2, $response->items); + self::assertSame('Basic', $response->items[0]->string('ProductName')); + self::assertSame('Pro', $response->items[1]->string('ProductName')); + self::assertCount(2, $response->entities); + self::assertInstanceOf(Product::class, $response->entities[0]); + self::assertSame('Basic', $response->entities[0]->ProductName); + } + + public function testActionResponseIsCreatedWhenNoEntityData(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'invoice', + 'action' => 'markaspaid', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertInstanceOf(ActionResponse::class, $response); + self::assertTrue($response->isSuccess()); + self::assertSame('invoice', $response->controller); + self::assertSame('markaspaid', $response->action); + } + + public function testShowResponseForAddAction(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'debtor', + 'action' => 'add', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'debtor' => [ + 'Identifier' => 42, + 'DebtorCode' => 'DB0001', + 'CompanyName' => 'Acme', + ], + ]); + + self::assertInstanceOf(ShowResponse::class, $response); + self::assertSame('Acme', $response->data->string('CompanyName')); + self::assertInstanceOf(Debtor::class, $response->entity); + self::assertSame('Acme', $response->entity->CompanyName); + } + + public function testDateIsParsedAsDateTimeImmutable(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'success', + 'date' => '2024-06-15T14:30:00+02:00', + 'product' => ['Identifier' => 1], + ]); + + self::assertSame('2024-06-15', $response->date->format('Y-m-d')); + } + + public function testToArrayReturnsRawData(): void + { + $raw = [ + 'controller' => 'product', + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'products' => [], + 'totalresults' => 0, + 'currentresults' => 0, + 'offset' => 0, + ]; + + $response = ResponseFactory::fromArray($raw); + self::assertSame($raw, $response->toArray()); + } + + public function testUnknownControllerReturnsActionResponse(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'unknown', + 'action' => 'test', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertInstanceOf(ActionResponse::class, $response); + } + + public function testAllControllersProduceShowResponse(): void + { + $controllers = [ + 'product', 'invoice', 'debtor', 'domain', 'hosting', + 'service', 'ssl', 'vps', 'ticket', 'order', + 'pricequote', 'creditor', 'creditinvoice', 'group', 'handle', + ]; + + foreach ($controllers as $name) { + $response = ResponseFactory::fromArray([ + 'controller' => $name, + 'action' => 'show', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + $name => ['Identifier' => 1], + ]); + + self::assertInstanceOf(ShowResponse::class, $response, "Failed for controller: {$name}"); + } + } + + public function testAllControllersProduceListResponse(): void + { + $mapping = [ + 'product' => 'products', + 'invoice' => 'invoices', + 'debtor' => 'debtors', + 'domain' => 'domains', + 'hosting' => 'hostings', + 'service' => 'services', + 'ssl' => 'ssls', + 'vps' => 'vpses', + 'ticket' => 'tickets', + 'order' => 'orders', + 'pricequote' => 'pricequotes', + 'creditor' => 'creditors', + 'creditinvoice' => 'creditinvoices', + 'group' => 'groups', + 'handle' => 'handles', + ]; + + foreach ($mapping as $controller => $pluralKey) { + $response = ResponseFactory::fromArray([ + 'controller' => $controller, + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'totalresults' => 1, + 'currentresults' => 1, + 'offset' => 0, + $pluralKey => [['Identifier' => 1]], + ]); + + self::assertInstanceOf(ListResponse::class, $response, "Failed for controller: {$controller}"); + self::assertCount(1, $response->items); + } + } + + public function testErrorResponseWithMultipleErrors(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'debtor', + 'action' => 'add', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => ['Field required: SurName', 'Field required: EmailAddress'], + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertCount(2, $response->errors); + self::assertSame('Field required: SurName', $response->errors[0]); + } + + public function testInvalidJsonFallbackResponse(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'invalid', + 'action' => 'invalid', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => ['Syntax error'], + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertSame('invalid', $response->controller); + } + + public function testErrorResponseWithNonStringStatus(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 123, + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertSame(Status::Error, $response->status); + } + + public function testErrorResponseWithNonArrayErrors(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => 'not an array', + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertEmpty($response->errors); + } + + public function testErrorResponseCastsNonStringErrors(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + 'errors' => [42, 'string error'], + ]); + + self::assertInstanceOf(ErrorResponse::class, $response); + self::assertSame('42', $response->errors[0]); + self::assertSame('string error', $response->errors[1]); + } + + public function testMissingControllerDefaultsToUnknown(): void + { + $response = ResponseFactory::fromArray([ + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertSame('unknown', $response->controller); + self::assertSame('unknown', $response->action); + } + + public function testMissingDateDefaultsToNow(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'success', + ]); + + self::assertSame(date('Y-m-d'), $response->date->format('Y-m-d')); + } + + public function testNonStringControllerDefaultsToUnknown(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 123, + 'action' => 'show', + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertSame('unknown', $response->controller); + } + + public function testNonStringActionDefaultsToUnknown(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => ['invalid'], + 'status' => 'error', + 'date' => '2024-01-01T00:00:00+00:00', + ]); + + self::assertSame('unknown', $response->action); + } + + public function testNonStringDateDefaultsToNow(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'success', + 'date' => 12345, + 'product' => ['Identifier' => '1'], + ]); + + self::assertSame(date('Y-m-d'), $response->date->format('Y-m-d')); + } + + public function testPluralKeyAsNonArrayFallsThrough(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'list', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'products' => 'not-an-array', + ]); + + self::assertInstanceOf(ActionResponse::class, $response); + } + + public function testSingularKeyAsNonArrayFallsThrough(): void + { + $response = ResponseFactory::fromArray([ + 'controller' => 'product', + 'action' => 'show', + 'status' => 'success', + 'date' => '2024-01-01T00:00:00+00:00', + 'product' => 'not-an-array', + ]); + + self::assertInstanceOf(ActionResponse::class, $response); + } +} diff --git a/tests/Unit/UrlTest.php b/tests/Unit/UrlTest.php new file mode 100644 index 000000000..3ef99b216 --- /dev/null +++ b/tests/Unit/UrlTest.php @@ -0,0 +1,38 @@ +getValue()); + } + + public function testValidHttpUrl(): void + { + $url = Url::fromString('http://localhost/api.php'); + + self::assertSame('http://localhost/api.php', $url->getValue()); + } + + public function testInvalidUrlThrowsException(): void + { + $this->expectException(StringException::class); + + Url::fromString('not-a-valid-url'); + } + + public function testEmptyStringThrowsException(): void + { + $this->expectException(StringException::class); + + Url::fromString(''); + } +} From f38569a3e12bb9ce979b6f060c2d8e79883b66d0 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:47:53 +0200 Subject: [PATCH 11/30] Add backed enums for HostFact API value sets 18 enums: Sex, Periodic, ProductType, InvoiceMethod, VatCalcMethod, DiscountPercentageType, GroupType, TicketType, TicketPriority, InvoiceStatus, InvoiceSubStatus, OrderStatus, PriceQuoteStatus, DomainStatus, HostingStatus, SslStatus, VpsStatus, TicketStatus. --- src/Api/Entity/Enum/DiscountPercentageType.php | 9 +++++++++ src/Api/Entity/Enum/DomainStatus.php | 11 +++++++++++ src/Api/Entity/Enum/GroupType.php | 10 ++++++++++ src/Api/Entity/Enum/HostingStatus.php | 10 ++++++++++ src/Api/Entity/Enum/InvoiceMethod.php | 10 ++++++++++ src/Api/Entity/Enum/InvoiceStatus.php | 14 ++++++++++++++ src/Api/Entity/Enum/InvoiceSubStatus.php | 11 +++++++++++ src/Api/Entity/Enum/OrderStatus.php | 11 +++++++++++ src/Api/Entity/Enum/Periodic.php | 15 +++++++++++++++ src/Api/Entity/Enum/PriceQuoteStatus.php | 12 ++++++++++++ src/Api/Entity/Enum/ProductType.php | 13 +++++++++++++ src/Api/Entity/Enum/Sex.php | 9 +++++++++ src/Api/Entity/Enum/SslStatus.php | 11 +++++++++++ src/Api/Entity/Enum/TicketPriority.php | 10 ++++++++++ src/Api/Entity/Enum/TicketStatus.php | 11 +++++++++++ src/Api/Entity/Enum/TicketType.php | 11 +++++++++++ src/Api/Entity/Enum/VatCalcMethod.php | 9 +++++++++ src/Api/Entity/Enum/VpsStatus.php | 10 ++++++++++ 18 files changed, 197 insertions(+) create mode 100644 src/Api/Entity/Enum/DiscountPercentageType.php create mode 100644 src/Api/Entity/Enum/DomainStatus.php create mode 100644 src/Api/Entity/Enum/GroupType.php create mode 100644 src/Api/Entity/Enum/HostingStatus.php create mode 100644 src/Api/Entity/Enum/InvoiceMethod.php create mode 100644 src/Api/Entity/Enum/InvoiceStatus.php create mode 100644 src/Api/Entity/Enum/InvoiceSubStatus.php create mode 100644 src/Api/Entity/Enum/OrderStatus.php create mode 100644 src/Api/Entity/Enum/Periodic.php create mode 100644 src/Api/Entity/Enum/PriceQuoteStatus.php create mode 100644 src/Api/Entity/Enum/ProductType.php create mode 100644 src/Api/Entity/Enum/Sex.php create mode 100644 src/Api/Entity/Enum/SslStatus.php create mode 100644 src/Api/Entity/Enum/TicketPriority.php create mode 100644 src/Api/Entity/Enum/TicketStatus.php create mode 100644 src/Api/Entity/Enum/TicketType.php create mode 100644 src/Api/Entity/Enum/VatCalcMethod.php create mode 100644 src/Api/Entity/Enum/VpsStatus.php diff --git a/src/Api/Entity/Enum/DiscountPercentageType.php b/src/Api/Entity/Enum/DiscountPercentageType.php new file mode 100644 index 000000000..f8d87695e --- /dev/null +++ b/src/Api/Entity/Enum/DiscountPercentageType.php @@ -0,0 +1,9 @@ + Date: Sat, 11 Apr 2026 16:48:01 +0200 Subject: [PATCH 12/30] Add nullableBool, nullableDateTime, and nullableEnum helpers DataBag gains nullableBool() (yes/no/1/0/true/false) and nullableDateTime() methods. Entity base class gains nullableEnum() using ReflectionEnum for int/string backing detection. --- src/Api/Entity/Entity.php | 22 ++++++ src/Api/Response/DataBag.php | 39 ++++++++++ tests/Unit/Response/DataBagTest.php | 110 ++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) diff --git a/src/Api/Entity/Entity.php b/src/Api/Entity/Entity.php index d1d581cf0..41a343cdc 100644 --- a/src/Api/Entity/Entity.php +++ b/src/Api/Entity/Entity.php @@ -14,4 +14,26 @@ protected function __construct(DataBag $bag) } abstract public static function fromBag(DataBag $bag): static; + + /** + * @template T of \BackedEnum + * @param class-string $enumClass + * @return T|null + */ + protected static function nullableEnum(DataBag $bag, string $key, string $enumClass): ?\BackedEnum + { + $value = $bag->nullableString($key); + + if ($value === null) { + return null; + } + + $backing = (new \ReflectionEnum($enumClass))->getBackingType(); + + if ($backing !== null && (string) $backing === 'int') { + return $enumClass::tryFrom((int) $value); + } + + return $enumClass::tryFrom($value); + } } diff --git a/src/Api/Response/DataBag.php b/src/Api/Response/DataBag.php index 512a09d7e..5f9e235c4 100644 --- a/src/Api/Response/DataBag.php +++ b/src/Api/Response/DataBag.php @@ -92,6 +92,45 @@ public function nullableInt(string $key): ?int return (int) $value; } + public function nullableBool(string $key): ?bool + { + $value = $this->data[$key] ?? null; + + if ($value === null) { + return null; + } + + return match ($value) { + 'yes', true, 1, '1' => true, + 'no', false, 0, '0' => false, + default => throw new \InvalidArgumentException( + "Field '{$key}' cannot be cast to bool, got: " . var_export($value, true) + ), + }; + } + + public function nullableDateTime(string $key): ?\DateTimeImmutable + { + $value = $this->data[$key] ?? null; + + if ($value === null || $value === '') { + return null; + } + + if (!is_string($value)) { + throw new \InvalidArgumentException("Field '{$key}' is not a valid date string"); + } + + try { + return new \DateTimeImmutable($value); + } catch (\Exception $e) { + throw new \InvalidArgumentException( + "Field '{$key}' cannot be parsed as date: {$value}", + previous: $e, + ); + } + } + /** * @return array */ diff --git a/tests/Unit/Response/DataBagTest.php b/tests/Unit/Response/DataBagTest.php index ed5f1f3ee..15d1532fe 100644 --- a/tests/Unit/Response/DataBagTest.php +++ b/tests/Unit/Response/DataBagTest.php @@ -187,6 +187,116 @@ public function testNullableIntThrowsOnNonScalar(): void $bag->nullableInt('Data'); } + public function testNullableBoolReturnsTrueForYes(): void + { + $bag = new DataBag(['Flag' => 'yes']); + self::assertTrue($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsFalseForNo(): void + { + $bag = new DataBag(['Flag' => 'no']); + self::assertFalse($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsTrueForOne(): void + { + $bag = new DataBag(['Flag' => 1]); + self::assertTrue($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsFalseForZero(): void + { + $bag = new DataBag(['Flag' => 0]); + self::assertFalse($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsTrueForStringOne(): void + { + $bag = new DataBag(['Flag' => '1']); + self::assertTrue($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsFalseForStringZero(): void + { + $bag = new DataBag(['Flag' => '0']); + self::assertFalse($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsTrueForTrue(): void + { + $bag = new DataBag(['Flag' => true]); + self::assertTrue($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsFalseForFalse(): void + { + $bag = new DataBag(['Flag' => false]); + self::assertFalse($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsNullForMissing(): void + { + $bag = new DataBag([]); + self::assertNull($bag->nullableBool('Flag')); + } + + public function testNullableBoolReturnsNullForNull(): void + { + $bag = new DataBag(['Flag' => null]); + self::assertNull($bag->nullableBool('Flag')); + } + + public function testNullableBoolThrowsOnUnexpectedValue(): void + { + $bag = new DataBag(['Flag' => 'maybe']); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Flag' cannot be cast to bool, got: 'maybe'"); + $bag->nullableBool('Flag'); + } + + public function testNullableDateTimeReturnsDateTimeImmutable(): void + { + $bag = new DataBag(['Created' => '2022-11-24 11:00:00']); + $dt = $bag->nullableDateTime('Created'); + self::assertInstanceOf(\DateTimeImmutable::class, $dt); + self::assertSame('2022-11-24 11:00:00', $dt->format('Y-m-d H:i:s')); + } + + public function testNullableDateTimeReturnsNullForMissing(): void + { + $bag = new DataBag([]); + self::assertNull($bag->nullableDateTime('Created')); + } + + public function testNullableDateTimeReturnsNullForNull(): void + { + $bag = new DataBag(['Created' => null]); + self::assertNull($bag->nullableDateTime('Created')); + } + + public function testNullableDateTimeReturnsNullForEmptyString(): void + { + $bag = new DataBag(['Created' => '']); + self::assertNull($bag->nullableDateTime('Created')); + } + + public function testNullableDateTimeThrowsOnInvalidDate(): void + { + $bag = new DataBag(['Created' => 'not-a-date']); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Created' cannot be parsed as date"); + $bag->nullableDateTime('Created'); + } + + public function testNullableDateTimeThrowsOnNonString(): void + { + $bag = new DataBag(['Created' => 12345]); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Field 'Created' is not a valid date string"); + $bag->nullableDateTime('Created'); + } + public function testArrayReturnsValue(): void { $bag = new DataBag(['Groups' => ['A', 'B']]); From fbaf6149d4b7f7a89acc0bd4b4d020285f201a5e Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:48:10 +0200 Subject: [PATCH 13/30] Replace string properties with strict types in all entity classes Identifiers become ?int, dates become ?DateTimeImmutable, booleans become ?bool, finite value sets become enums. Prices stay ?string for bcmath precision. Update test assertions to match. --- src/Api/Entity/Creditor.php | 25 +++--- src/Api/Entity/Debtor.php | 58 ++++++------ src/Api/Entity/Domain.php | 37 ++++---- src/Api/Entity/Group.php | 9 +- src/Api/Entity/GroupItem.php | 4 +- src/Api/Entity/Hosting.php | 21 ++--- src/Api/Entity/Invoice.php | 93 +++++++++++--------- src/Api/Entity/InvoiceLine.php | 43 ++++----- src/Api/Entity/Order.php | 56 ++++++------ src/Api/Entity/OrderLine.php | 31 ++++--- src/Api/Entity/PriceQuote.php | 64 +++++++------- src/Api/Entity/PriceQuoteLine.php | 34 +++---- src/Api/Entity/Product.php | 30 ++++--- src/Api/Entity/Ssl.php | 49 ++++++----- src/Api/Entity/Subscription.php | 53 +++++------ src/Api/Entity/Ticket.php | 35 ++++---- src/Api/Entity/TicketMessage.php | 12 +-- src/Api/Entity/Vps.php | 41 ++++----- tests/Unit/Entity/InvoiceEntityTest.php | 4 +- tests/Unit/Entity/ProductEntityTest.php | 13 +-- tests/Unit/Entity/SubscriptionEntityTest.php | 7 +- 21 files changed, 380 insertions(+), 339 deletions(-) diff --git a/src/Api/Entity/Creditor.php b/src/Api/Entity/Creditor.php index 9b100efdc..141889b5c 100644 --- a/src/Api/Entity/Creditor.php +++ b/src/Api/Entity/Creditor.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\Sex; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Creditor extends Entity @@ -12,13 +13,13 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $CreditorCode, public ?string $MyCustomerCode, public ?string $CompanyName, public ?string $CompanyNumber, public ?string $TaxNumber, - public ?string $Sex, + public ?Sex $Sex, public ?string $Initials, public ?string $SurName, public ?string $Address, @@ -30,15 +31,15 @@ public function __construct( public ?string $MobileNumber, public ?string $FaxNumber, public ?string $Comment, - public ?string $Authorisation, + public ?bool $Authorisation, public ?string $AccountNumber, public ?string $AccountBIC, public ?string $AccountName, public ?string $AccountBank, public ?string $AccountCity, - public ?string $Term, - public ?string $Created, - public ?string $Modified, + public ?int $Term, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public array $Groups, public array $Translations, ) { @@ -49,13 +50,13 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), CreditorCode: $bag->nullableString('CreditorCode'), MyCustomerCode: $bag->nullableString('MyCustomerCode'), CompanyName: $bag->nullableString('CompanyName'), CompanyNumber: $bag->nullableString('CompanyNumber'), TaxNumber: $bag->nullableString('TaxNumber'), - Sex: $bag->nullableString('Sex'), + Sex: self::nullableEnum($bag, 'Sex', Sex::class), Initials: $bag->nullableString('Initials'), SurName: $bag->nullableString('SurName'), Address: $bag->nullableString('Address'), @@ -67,15 +68,15 @@ public static function fromBag(DataBag $bag): static MobileNumber: $bag->nullableString('MobileNumber'), FaxNumber: $bag->nullableString('FaxNumber'), Comment: $bag->nullableString('Comment'), - Authorisation: $bag->nullableString('Authorisation'), + Authorisation: $bag->nullableBool('Authorisation'), AccountNumber: $bag->nullableString('AccountNumber'), AccountBIC: $bag->nullableString('AccountBIC'), AccountName: $bag->nullableString('AccountName'), AccountBank: $bag->nullableString('AccountBank'), AccountCity: $bag->nullableString('AccountCity'), - Term: $bag->nullableString('Term'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Term: $bag->nullableInt('Term'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], ); diff --git a/src/Api/Entity/Debtor.php b/src/Api/Entity/Debtor.php index 18fe9c80f..968530e65 100644 --- a/src/Api/Entity/Debtor.php +++ b/src/Api/Entity/Debtor.php @@ -2,6 +2,8 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceMethod; +use Hyperized\Hostfact\Api\Entity\Enum\Sex; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Debtor extends Entity @@ -12,13 +14,13 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $DebtorCode, public ?string $CompanyName, public ?string $CompanyNumber, public ?string $LegalForm, public ?string $TaxNumber, - public ?string $Sex, + public ?Sex $Sex, public ?string $Initials, public ?string $SurName, public ?string $Address, @@ -31,9 +33,9 @@ public function __construct( public ?string $FaxNumber, public ?string $Website, public ?string $Comment, - public ?string $InvoiceMethod, + public ?InvoiceMethod $InvoiceMethod, public ?string $InvoiceCompanyName, - public ?string $InvoiceSex, + public ?Sex $InvoiceSex, public ?string $InvoiceInitials, public ?string $InvoiceSurName, public ?string $InvoiceAddress, @@ -42,32 +44,32 @@ public function __construct( public ?string $InvoiceCountry, public ?string $InvoiceEmailAddress, public ?string $ReminderEmailAddress, - public ?string $InvoiceAuthorisation, + public ?bool $InvoiceAuthorisation, public ?string $MandateID, - public ?string $InvoiceDataForPriceQuote, + public ?bool $InvoiceDataForPriceQuote, public ?string $AccountNumber, public ?string $AccountBIC, public ?string $AccountName, public ?string $AccountBank, public ?string $AccountCity, - public ?string $ActiveLogin, + public ?bool $ActiveLogin, public ?string $Username, public ?string $SecurePassword, - public ?string $Mailing, - public ?string $Taxable, - public ?string $PeriodicInvoiceDays, + public ?bool $Mailing, + public ?bool $Taxable, + public ?int $PeriodicInvoiceDays, public ?string $InvoiceTemplate, public ?string $PriceQuoteTemplate, public ?string $ReminderTemplate, public ?string $SecondReminderTemplate, public ?string $SummationTemplate, - public ?string $PaymentMail, + public ?bool $PaymentMail, public ?string $PaymentMailTemplate, - public ?string $InvoiceCollect, + public ?bool $InvoiceCollect, public ?string $DefaultLanguage, public ?string $ClientareaProfile, - public ?string $Created, - public ?string $Modified, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public array $Groups, public array $Translations, ) { @@ -78,13 +80,13 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), DebtorCode: $bag->nullableString('DebtorCode'), CompanyName: $bag->nullableString('CompanyName'), CompanyNumber: $bag->nullableString('CompanyNumber'), LegalForm: $bag->nullableString('LegalForm'), TaxNumber: $bag->nullableString('TaxNumber'), - Sex: $bag->nullableString('Sex'), + Sex: self::nullableEnum($bag, 'Sex', Sex::class), Initials: $bag->nullableString('Initials'), SurName: $bag->nullableString('SurName'), Address: $bag->nullableString('Address'), @@ -97,9 +99,9 @@ public static function fromBag(DataBag $bag): static FaxNumber: $bag->nullableString('FaxNumber'), Website: $bag->nullableString('Website'), Comment: $bag->nullableString('Comment'), - InvoiceMethod: $bag->nullableString('InvoiceMethod'), + InvoiceMethod: self::nullableEnum($bag, 'InvoiceMethod', InvoiceMethod::class), InvoiceCompanyName: $bag->nullableString('InvoiceCompanyName'), - InvoiceSex: $bag->nullableString('InvoiceSex'), + InvoiceSex: self::nullableEnum($bag, 'InvoiceSex', Sex::class), InvoiceInitials: $bag->nullableString('InvoiceInitials'), InvoiceSurName: $bag->nullableString('InvoiceSurName'), InvoiceAddress: $bag->nullableString('InvoiceAddress'), @@ -108,32 +110,32 @@ public static function fromBag(DataBag $bag): static InvoiceCountry: $bag->nullableString('InvoiceCountry'), InvoiceEmailAddress: $bag->nullableString('InvoiceEmailAddress'), ReminderEmailAddress: $bag->nullableString('ReminderEmailAddress'), - InvoiceAuthorisation: $bag->nullableString('InvoiceAuthorisation'), + InvoiceAuthorisation: $bag->nullableBool('InvoiceAuthorisation'), MandateID: $bag->nullableString('MandateID'), - InvoiceDataForPriceQuote: $bag->nullableString('InvoiceDataForPriceQuote'), + InvoiceDataForPriceQuote: $bag->nullableBool('InvoiceDataForPriceQuote'), AccountNumber: $bag->nullableString('AccountNumber'), AccountBIC: $bag->nullableString('AccountBIC'), AccountName: $bag->nullableString('AccountName'), AccountBank: $bag->nullableString('AccountBank'), AccountCity: $bag->nullableString('AccountCity'), - ActiveLogin: $bag->nullableString('ActiveLogin'), + ActiveLogin: $bag->nullableBool('ActiveLogin'), Username: $bag->nullableString('Username'), SecurePassword: $bag->nullableString('SecurePassword'), - Mailing: $bag->nullableString('Mailing'), - Taxable: $bag->nullableString('Taxable'), - PeriodicInvoiceDays: $bag->nullableString('PeriodicInvoiceDays'), + Mailing: $bag->nullableBool('Mailing'), + Taxable: $bag->nullableBool('Taxable'), + PeriodicInvoiceDays: $bag->nullableInt('PeriodicInvoiceDays'), InvoiceTemplate: $bag->nullableString('InvoiceTemplate'), PriceQuoteTemplate: $bag->nullableString('PriceQuoteTemplate'), ReminderTemplate: $bag->nullableString('ReminderTemplate'), SecondReminderTemplate: $bag->nullableString('SecondReminderTemplate'), SummationTemplate: $bag->nullableString('SummationTemplate'), - PaymentMail: $bag->nullableString('PaymentMail'), + PaymentMail: $bag->nullableBool('PaymentMail'), PaymentMailTemplate: $bag->nullableString('PaymentMailTemplate'), - InvoiceCollect: $bag->nullableString('InvoiceCollect'), + InvoiceCollect: $bag->nullableBool('InvoiceCollect'), DefaultLanguage: $bag->nullableString('DefaultLanguage'), ClientareaProfile: $bag->nullableString('ClientareaProfile'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], ); diff --git a/src/Api/Entity/Domain.php b/src/Api/Entity/Domain.php index 68c9d0fbe..765923bba 100644 --- a/src/Api/Entity/Domain.php +++ b/src/Api/Entity/Domain.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\DomainStatus; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Domain extends Entity @@ -11,15 +12,15 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $Domain, public ?string $Tld, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, - public ?string $HostingID, - public ?string $Status, - public ?string $RegistrationDate, - public ?string $ExpirationDate, + public ?int $HostingID, + public ?DomainStatus $Status, + public ?\DateTimeImmutable $RegistrationDate, + public ?\DateTimeImmutable $ExpirationDate, public ?string $Registrar, public ?string $DNS1, public ?string $DNS2, @@ -31,10 +32,10 @@ public function __construct( public ?string $OwnerHandle, public ?string $AdminHandle, public ?string $TechHandle, - public ?string $DomainAutoRenew, + public ?bool $DomainAutoRenew, public ?string $Comment, - public ?string $Created, - public ?string $Modified, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?Subscription $Subscription, public ?DataBag $RegistrarInfo, public array $Translations, @@ -46,15 +47,15 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), Domain: $bag->nullableString('Domain'), Tld: $bag->nullableString('Tld'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), - HostingID: $bag->nullableString('HostingID'), - Status: $bag->nullableString('Status'), - RegistrationDate: $bag->nullableString('RegistrationDate'), - ExpirationDate: $bag->nullableString('ExpirationDate'), + HostingID: $bag->nullableInt('HostingID'), + Status: self::nullableEnum($bag, 'Status', DomainStatus::class), + RegistrationDate: $bag->nullableDateTime('RegistrationDate'), + ExpirationDate: $bag->nullableDateTime('ExpirationDate'), Registrar: $bag->nullableString('Registrar'), DNS1: $bag->nullableString('DNS1'), DNS2: $bag->nullableString('DNS2'), @@ -66,10 +67,10 @@ public static function fromBag(DataBag $bag): static OwnerHandle: $bag->nullableString('OwnerHandle'), AdminHandle: $bag->nullableString('AdminHandle'), TechHandle: $bag->nullableString('TechHandle'), - DomainAutoRenew: $bag->nullableString('DomainAutoRenew'), + DomainAutoRenew: $bag->nullableBool('DomainAutoRenew'), Comment: $bag->nullableString('Comment'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, RegistrarInfo: $bag->has('RegistrarInfo') ? $bag->bag('RegistrarInfo') : null, Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], diff --git a/src/Api/Entity/Group.php b/src/Api/Entity/Group.php index a7ada7b60..0a29997ce 100644 --- a/src/Api/Entity/Group.php +++ b/src/Api/Entity/Group.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\GroupType; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Group extends Entity @@ -11,9 +12,9 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $GroupName, - public ?string $Type, + public ?GroupType $Type, public array $Items, ) { parent::__construct($bag); @@ -30,9 +31,9 @@ public static function fromBag(DataBag $bag): static return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), GroupName: $bag->nullableString('GroupName'), - Type: $bag->nullableString('Type'), + Type: self::nullableEnum($bag, 'Type', GroupType::class), Items: $items, ); } diff --git a/src/Api/Entity/GroupItem.php b/src/Api/Entity/GroupItem.php index 289d53769..adc4d278f 100644 --- a/src/Api/Entity/GroupItem.php +++ b/src/Api/Entity/GroupItem.php @@ -8,7 +8,7 @@ { public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $ProductCode, public ?string $ProductName, ) { @@ -19,7 +19,7 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), ProductCode: $bag->nullableString('ProductCode'), ProductName: $bag->nullableString('ProductName'), ); diff --git a/src/Api/Entity/Hosting.php b/src/Api/Entity/Hosting.php index 9680e45db..bedbae13d 100644 --- a/src/Api/Entity/Hosting.php +++ b/src/Api/Entity/Hosting.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\HostingStatus; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Hosting extends Entity @@ -11,18 +12,18 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $Username, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, public ?string $Domain, public ?string $Server, public ?string $Package, public ?string $PackageName, public ?string $Comment, - public ?string $Status, - public ?string $Created, - public ?string $Modified, + public ?HostingStatus $Status, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?Subscription $Subscription, public ?DataBag $PackageInfo, public ?DataBag $ServerInfo, @@ -35,18 +36,18 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), Username: $bag->nullableString('Username'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), Domain: $bag->nullableString('Domain'), Server: $bag->nullableString('Server'), Package: $bag->nullableString('Package'), PackageName: $bag->nullableString('PackageName'), Comment: $bag->nullableString('Comment'), - Status: $bag->nullableString('Status'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Status: self::nullableEnum($bag, 'Status', HostingStatus::class), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, PackageInfo: $bag->has('PackageInfo') ? $bag->bag('PackageInfo') : null, ServerInfo: $bag->has('ServerInfo') ? $bag->bag('ServerInfo') : null, diff --git a/src/Api/Entity/Invoice.php b/src/Api/Entity/Invoice.php index b834beadf..2337100e9 100644 --- a/src/Api/Entity/Invoice.php +++ b/src/Api/Entity/Invoice.php @@ -2,6 +2,11 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceMethod; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceStatus; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceSubStatus; +use Hyperized\Hostfact\Api\Entity\Enum\Sex; +use Hyperized\Hostfact\Api\Entity\Enum\VatCalcMethod; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Invoice extends Entity @@ -14,30 +19,30 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $InvoiceCode, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, - public ?string $Status, - public ?string $SubStatus, - public ?string $Date, - public ?string $Term, - public ?string $PayBefore, + public ?InvoiceStatus $Status, + public ?InvoiceSubStatus $SubStatus, + public ?\DateTimeImmutable $Date, + public ?int $Term, + public ?\DateTimeImmutable $PayBefore, public ?string $PaymentURL, public ?string $AmountExcl, public ?string $AmountTax, public ?string $AmountIncl, public ?string $TaxRate, - public ?string $Compound, + public ?bool $Compound, public ?string $AmountPaid, public ?string $Discount, - public ?string $VatCalcMethod, - public ?string $IgnoreDiscount, + public ?VatCalcMethod $VatCalcMethod, + public ?bool $IgnoreDiscount, public ?string $Coupon, public ?string $ReferenceNumber, public ?string $CompanyName, public ?string $TaxNumber, - public ?string $Sex, + public ?Sex $Sex, public ?string $Initials, public ?string $SurName, public ?string $Address, @@ -45,22 +50,22 @@ public function __construct( public ?string $City, public ?string $Country, public ?string $EmailAddress, - public ?string $InvoiceMethod, + public ?InvoiceMethod $InvoiceMethod, public ?string $Template, - public ?string $SentDate, - public ?string $Sent, - public ?string $Reminders, - public ?string $ReminderDate, - public ?string $Summations, - public ?string $SummationDate, - public ?string $Authorisation, + public ?\DateTimeImmutable $SentDate, + public ?bool $Sent, + public ?int $Reminders, + public ?\DateTimeImmutable $ReminderDate, + public ?int $Summations, + public ?\DateTimeImmutable $SummationDate, + public ?bool $Authorisation, public ?string $PaymentMethod, - public ?string $PayDate, + public ?\DateTimeImmutable $PayDate, public ?string $TransactionID, public ?string $Description, public ?string $Comment, - public ?string $Created, - public ?string $Modified, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?string $AmountDiscount, public ?string $AmountDiscountIncl, public array $InvoiceLines, @@ -82,30 +87,30 @@ public static function fromBag(DataBag $bag): static return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), InvoiceCode: $bag->nullableString('InvoiceCode'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), - Status: $bag->nullableString('Status'), - SubStatus: $bag->nullableString('SubStatus'), - Date: $bag->nullableString('Date'), - Term: $bag->nullableString('Term'), - PayBefore: $bag->nullableString('PayBefore'), + Status: self::nullableEnum($bag, 'Status', InvoiceStatus::class), + SubStatus: self::nullableEnum($bag, 'SubStatus', InvoiceSubStatus::class), + Date: $bag->nullableDateTime('Date'), + Term: $bag->nullableInt('Term'), + PayBefore: $bag->nullableDateTime('PayBefore'), PaymentURL: $bag->nullableString('PaymentURL'), AmountExcl: $bag->nullableString('AmountExcl'), AmountTax: $bag->nullableString('AmountTax'), AmountIncl: $bag->nullableString('AmountIncl'), TaxRate: $bag->nullableString('TaxRate'), - Compound: $bag->nullableString('Compound'), + Compound: $bag->nullableBool('Compound'), AmountPaid: $bag->nullableString('AmountPaid'), Discount: $bag->nullableString('Discount'), - VatCalcMethod: $bag->nullableString('VatCalcMethod'), - IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + VatCalcMethod: self::nullableEnum($bag, 'VatCalcMethod', VatCalcMethod::class), + IgnoreDiscount: $bag->nullableBool('IgnoreDiscount'), Coupon: $bag->nullableString('Coupon'), ReferenceNumber: $bag->nullableString('ReferenceNumber'), CompanyName: $bag->nullableString('CompanyName'), TaxNumber: $bag->nullableString('TaxNumber'), - Sex: $bag->nullableString('Sex'), + Sex: self::nullableEnum($bag, 'Sex', Sex::class), Initials: $bag->nullableString('Initials'), SurName: $bag->nullableString('SurName'), Address: $bag->nullableString('Address'), @@ -113,22 +118,22 @@ public static function fromBag(DataBag $bag): static City: $bag->nullableString('City'), Country: $bag->nullableString('Country'), EmailAddress: $bag->nullableString('EmailAddress'), - InvoiceMethod: $bag->nullableString('InvoiceMethod'), + InvoiceMethod: self::nullableEnum($bag, 'InvoiceMethod', InvoiceMethod::class), Template: $bag->nullableString('Template'), - SentDate: $bag->nullableString('SentDate'), - Sent: $bag->nullableString('Sent'), - Reminders: $bag->nullableString('Reminders'), - ReminderDate: $bag->nullableString('ReminderDate'), - Summations: $bag->nullableString('Summations'), - SummationDate: $bag->nullableString('SummationDate'), - Authorisation: $bag->nullableString('Authorisation'), + SentDate: $bag->nullableDateTime('SentDate'), + Sent: $bag->nullableBool('Sent'), + Reminders: $bag->nullableInt('Reminders'), + ReminderDate: $bag->nullableDateTime('ReminderDate'), + Summations: $bag->nullableInt('Summations'), + SummationDate: $bag->nullableDateTime('SummationDate'), + Authorisation: $bag->nullableBool('Authorisation'), PaymentMethod: $bag->nullableString('PaymentMethod'), - PayDate: $bag->nullableString('PayDate'), + PayDate: $bag->nullableDateTime('PayDate'), TransactionID: $bag->nullableString('TransactionID'), Description: $bag->nullableString('Description'), Comment: $bag->nullableString('Comment'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), AmountDiscount: $bag->nullableString('AmountDiscount'), AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), InvoiceLines: $lines, diff --git a/src/Api/Entity/InvoiceLine.php b/src/Api/Entity/InvoiceLine.php index ef26b0011..27f7a56fd 100644 --- a/src/Api/Entity/InvoiceLine.php +++ b/src/Api/Entity/InvoiceLine.php @@ -2,28 +2,31 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\DiscountPercentageType; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; +use Hyperized\Hostfact\Api\Entity\Enum\ProductType; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class InvoiceLine extends Entity { public function __construct( DataBag $bag, - public ?string $Identifier, - public ?string $Date, - public ?string $Number, + public ?int $Identifier, + public ?\DateTimeImmutable $Date, + public ?int $Number, public ?string $NumberSuffix, public ?string $ProductCode, public ?string $Description, public ?string $PriceExcl, public ?string $DiscountPercentage, - public ?string $DiscountPercentageType, + public ?DiscountPercentageType $DiscountPercentageType, public ?string $TaxPercentage, - public ?string $PeriodicID, - public ?string $Periods, - public ?string $Periodic, - public ?string $StartPeriod, - public ?string $EndPeriod, - public ?string $ProductType, + public ?int $PeriodicID, + public ?int $Periods, + public ?Periodic $Periodic, + public ?\DateTimeImmutable $StartPeriod, + public ?\DateTimeImmutable $EndPeriod, + public ?ProductType $ProductType, public ?string $Reference, public ?string $NoDiscountAmountIncl, public ?string $NoDiscountAmountExcl, @@ -37,22 +40,22 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), - Date: $bag->nullableString('Date'), - Number: $bag->nullableString('Number'), + Identifier: $bag->nullableInt('Identifier'), + Date: $bag->nullableDateTime('Date'), + Number: $bag->nullableInt('Number'), NumberSuffix: $bag->nullableString('NumberSuffix'), ProductCode: $bag->nullableString('ProductCode'), Description: $bag->nullableString('Description'), PriceExcl: $bag->nullableString('PriceExcl'), DiscountPercentage: $bag->nullableString('DiscountPercentage'), - DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), + DiscountPercentageType: self::nullableEnum($bag, 'DiscountPercentageType', DiscountPercentageType::class), TaxPercentage: $bag->nullableString('TaxPercentage'), - PeriodicID: $bag->nullableString('PeriodicID'), - Periods: $bag->nullableString('Periods'), - Periodic: $bag->nullableString('Periodic'), - StartPeriod: $bag->nullableString('StartPeriod'), - EndPeriod: $bag->nullableString('EndPeriod'), - ProductType: $bag->nullableString('ProductType'), + PeriodicID: $bag->nullableInt('PeriodicID'), + Periods: $bag->nullableInt('Periods'), + Periodic: self::nullableEnum($bag, 'Periodic', Periodic::class), + StartPeriod: $bag->nullableDateTime('StartPeriod'), + EndPeriod: $bag->nullableDateTime('EndPeriod'), + ProductType: self::nullableEnum($bag, 'ProductType', ProductType::class), Reference: $bag->nullableString('Reference'), NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), diff --git a/src/Api/Entity/Order.php b/src/Api/Entity/Order.php index ee0c9de74..7d7591151 100644 --- a/src/Api/Entity/Order.php +++ b/src/Api/Entity/Order.php @@ -2,6 +2,10 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceMethod; +use Hyperized\Hostfact\Api\Entity\Enum\OrderStatus; +use Hyperized\Hostfact\Api\Entity\Enum\Sex; +use Hyperized\Hostfact\Api\Entity\Enum\VatCalcMethod; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Order extends Entity @@ -13,20 +17,20 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $OrderCode, - public ?string $Debtor, - public ?string $Date, - public ?string $Term, + public ?int $Debtor, + public ?\DateTimeImmutable $Date, + public ?int $Term, public ?string $AmountExcl, public ?string $AmountTax, public ?string $AmountIncl, public ?string $Discount, - public ?string $VatCalcMethod, - public ?string $IgnoreDiscount, + public ?VatCalcMethod $VatCalcMethod, + public ?bool $IgnoreDiscount, public ?string $Coupon, public ?string $CompanyName, - public ?string $Sex, + public ?Sex $Sex, public ?string $Initials, public ?string $SurName, public ?string $Address, @@ -34,17 +38,17 @@ public function __construct( public ?string $City, public ?string $Country, public ?string $EmailAddress, - public ?string $InvoiceMethod, + public ?InvoiceMethod $InvoiceMethod, public ?string $Template, - public ?string $Authorisation, + public ?bool $Authorisation, public ?string $PaymentMethod, - public ?string $Paid, + public ?bool $Paid, public ?string $TransactionID, public ?string $IPAddress, public ?string $Comment, - public ?string $Status, - public ?string $Created, - public ?string $Modified, + public ?OrderStatus $Status, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?string $AmountDiscount, public ?string $AmountDiscountIncl, public array $OrderLines, @@ -65,20 +69,20 @@ public static function fromBag(DataBag $bag): static return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), OrderCode: $bag->nullableString('OrderCode'), - Debtor: $bag->nullableString('Debtor'), - Date: $bag->nullableString('Date'), - Term: $bag->nullableString('Term'), + Debtor: $bag->nullableInt('Debtor'), + Date: $bag->nullableDateTime('Date'), + Term: $bag->nullableInt('Term'), AmountExcl: $bag->nullableString('AmountExcl'), AmountTax: $bag->nullableString('AmountTax'), AmountIncl: $bag->nullableString('AmountIncl'), Discount: $bag->nullableString('Discount'), - VatCalcMethod: $bag->nullableString('VatCalcMethod'), - IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + VatCalcMethod: self::nullableEnum($bag, 'VatCalcMethod', VatCalcMethod::class), + IgnoreDiscount: $bag->nullableBool('IgnoreDiscount'), Coupon: $bag->nullableString('Coupon'), CompanyName: $bag->nullableString('CompanyName'), - Sex: $bag->nullableString('Sex'), + Sex: self::nullableEnum($bag, 'Sex', Sex::class), Initials: $bag->nullableString('Initials'), SurName: $bag->nullableString('SurName'), Address: $bag->nullableString('Address'), @@ -86,17 +90,17 @@ public static function fromBag(DataBag $bag): static City: $bag->nullableString('City'), Country: $bag->nullableString('Country'), EmailAddress: $bag->nullableString('EmailAddress'), - InvoiceMethod: $bag->nullableString('InvoiceMethod'), + InvoiceMethod: self::nullableEnum($bag, 'InvoiceMethod', InvoiceMethod::class), Template: $bag->nullableString('Template'), - Authorisation: $bag->nullableString('Authorisation'), + Authorisation: $bag->nullableBool('Authorisation'), PaymentMethod: $bag->nullableString('PaymentMethod'), - Paid: $bag->nullableString('Paid'), + Paid: $bag->nullableBool('Paid'), TransactionID: $bag->nullableString('TransactionID'), IPAddress: $bag->nullableString('IPAddress'), Comment: $bag->nullableString('Comment'), - Status: $bag->nullableString('Status'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Status: self::nullableEnum($bag, 'Status', OrderStatus::class), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), AmountDiscount: $bag->nullableString('AmountDiscount'), AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), OrderLines: $lines, diff --git a/src/Api/Entity/OrderLine.php b/src/Api/Entity/OrderLine.php index 1ddcc93f6..c1f2ea7c7 100644 --- a/src/Api/Entity/OrderLine.php +++ b/src/Api/Entity/OrderLine.php @@ -2,24 +2,27 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\DiscountPercentageType; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; +use Hyperized\Hostfact\Api\Entity\Enum\ProductType; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class OrderLine extends Entity { public function __construct( DataBag $bag, - public ?string $Identifier, - public ?string $Date, - public ?string $Number, + public ?int $Identifier, + public ?\DateTimeImmutable $Date, + public ?int $Number, public ?string $ProductCode, public ?string $Description, public ?string $PriceExcl, public ?string $TaxPercentage, public ?string $DiscountPercentage, - public ?string $DiscountPercentageType, - public ?string $Periods, - public ?string $Periodic, - public ?string $ProductType, + public ?DiscountPercentageType $DiscountPercentageType, + public ?int $Periods, + public ?Periodic $Periodic, + public ?ProductType $ProductType, public ?string $Reference, public ?string $NoDiscountAmountIncl, public ?string $NoDiscountAmountExcl, @@ -33,18 +36,18 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), - Date: $bag->nullableString('Date'), - Number: $bag->nullableString('Number'), + Identifier: $bag->nullableInt('Identifier'), + Date: $bag->nullableDateTime('Date'), + Number: $bag->nullableInt('Number'), ProductCode: $bag->nullableString('ProductCode'), Description: $bag->nullableString('Description'), PriceExcl: $bag->nullableString('PriceExcl'), TaxPercentage: $bag->nullableString('TaxPercentage'), DiscountPercentage: $bag->nullableString('DiscountPercentage'), - DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), - Periods: $bag->nullableString('Periods'), - Periodic: $bag->nullableString('Periodic'), - ProductType: $bag->nullableString('ProductType'), + DiscountPercentageType: self::nullableEnum($bag, 'DiscountPercentageType', DiscountPercentageType::class), + Periods: $bag->nullableInt('Periods'), + Periodic: self::nullableEnum($bag, 'Periodic', Periodic::class), + ProductType: self::nullableEnum($bag, 'ProductType', ProductType::class), Reference: $bag->nullableString('Reference'), NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), diff --git a/src/Api/Entity/PriceQuote.php b/src/Api/Entity/PriceQuote.php index 5928904b7..85da7ee16 100644 --- a/src/Api/Entity/PriceQuote.php +++ b/src/Api/Entity/PriceQuote.php @@ -2,6 +2,10 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceMethod; +use Hyperized\Hostfact\Api\Entity\Enum\PriceQuoteStatus; +use Hyperized\Hostfact\Api\Entity\Enum\Sex; +use Hyperized\Hostfact\Api\Entity\Enum\VatCalcMethod; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class PriceQuote extends Entity @@ -14,26 +18,26 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $PriceQuoteCode, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, - public ?string $Status, - public ?string $Date, - public ?string $Term, - public ?string $ExpirationDate, + public ?PriceQuoteStatus $Status, + public ?\DateTimeImmutable $Date, + public ?int $Term, + public ?\DateTimeImmutable $ExpirationDate, public ?string $AmountExcl, public ?string $AmountTax, public ?string $AmountIncl, public ?string $TaxRate, - public ?string $Compound, + public ?bool $Compound, public ?string $Discount, - public ?string $VatCalcMethod, - public ?string $IgnoreDiscount, + public ?VatCalcMethod $VatCalcMethod, + public ?bool $IgnoreDiscount, public ?string $Coupon, public ?string $ReferenceNumber, public ?string $CompanyName, - public ?string $Sex, + public ?Sex $Sex, public ?string $Initials, public ?string $SurName, public ?string $Address, @@ -41,14 +45,14 @@ public function __construct( public ?string $City, public ?string $Country, public ?string $EmailAddress, - public ?string $PriceQuoteMethod, + public ?InvoiceMethod $PriceQuoteMethod, public ?string $Template, - public ?string $SentDate, - public ?string $Sent, + public ?\DateTimeImmutable $SentDate, + public ?bool $Sent, public ?string $Description, public ?string $Comment, - public ?string $Created, - public ?string $Modified, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?string $AcceptURL, public ?string $AmountDiscount, public ?string $AmountDiscountIncl, @@ -71,26 +75,26 @@ public static function fromBag(DataBag $bag): static return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), PriceQuoteCode: $bag->nullableString('PriceQuoteCode'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), - Status: $bag->nullableString('Status'), - Date: $bag->nullableString('Date'), - Term: $bag->nullableString('Term'), - ExpirationDate: $bag->nullableString('ExpirationDate'), + Status: self::nullableEnum($bag, 'Status', PriceQuoteStatus::class), + Date: $bag->nullableDateTime('Date'), + Term: $bag->nullableInt('Term'), + ExpirationDate: $bag->nullableDateTime('ExpirationDate'), AmountExcl: $bag->nullableString('AmountExcl'), AmountTax: $bag->nullableString('AmountTax'), AmountIncl: $bag->nullableString('AmountIncl'), TaxRate: $bag->nullableString('TaxRate'), - Compound: $bag->nullableString('Compound'), + Compound: $bag->nullableBool('Compound'), Discount: $bag->nullableString('Discount'), - VatCalcMethod: $bag->nullableString('VatCalcMethod'), - IgnoreDiscount: $bag->nullableString('IgnoreDiscount'), + VatCalcMethod: self::nullableEnum($bag, 'VatCalcMethod', VatCalcMethod::class), + IgnoreDiscount: $bag->nullableBool('IgnoreDiscount'), Coupon: $bag->nullableString('Coupon'), ReferenceNumber: $bag->nullableString('ReferenceNumber'), CompanyName: $bag->nullableString('CompanyName'), - Sex: $bag->nullableString('Sex'), + Sex: self::nullableEnum($bag, 'Sex', Sex::class), Initials: $bag->nullableString('Initials'), SurName: $bag->nullableString('SurName'), Address: $bag->nullableString('Address'), @@ -98,14 +102,14 @@ public static function fromBag(DataBag $bag): static City: $bag->nullableString('City'), Country: $bag->nullableString('Country'), EmailAddress: $bag->nullableString('EmailAddress'), - PriceQuoteMethod: $bag->nullableString('PriceQuoteMethod'), + PriceQuoteMethod: self::nullableEnum($bag, 'PriceQuoteMethod', InvoiceMethod::class), Template: $bag->nullableString('Template'), - SentDate: $bag->nullableString('SentDate'), - Sent: $bag->nullableString('Sent'), + SentDate: $bag->nullableDateTime('SentDate'), + Sent: $bag->nullableBool('Sent'), Description: $bag->nullableString('Description'), Comment: $bag->nullableString('Comment'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), AcceptURL: $bag->nullableString('AcceptURL'), AmountDiscount: $bag->nullableString('AmountDiscount'), AmountDiscountIncl: $bag->nullableString('AmountDiscountIncl'), diff --git a/src/Api/Entity/PriceQuoteLine.php b/src/Api/Entity/PriceQuoteLine.php index 4e96da522..dcdc85991 100644 --- a/src/Api/Entity/PriceQuoteLine.php +++ b/src/Api/Entity/PriceQuoteLine.php @@ -2,26 +2,28 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\DiscountPercentageType; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class PriceQuoteLine extends Entity { public function __construct( DataBag $bag, - public ?string $Identifier, - public ?string $Date, - public ?string $Number, + public ?int $Identifier, + public ?\DateTimeImmutable $Date, + public ?int $Number, public ?string $NumberSuffix, public ?string $ProductCode, public ?string $Description, public ?string $PriceExcl, public ?string $DiscountPercentage, - public ?string $DiscountPercentageType, + public ?DiscountPercentageType $DiscountPercentageType, public ?string $TaxPercentage, - public ?string $Periods, - public ?string $Periodic, - public ?string $StartPeriod, - public ?string $EndPeriod, + public ?int $Periods, + public ?Periodic $Periodic, + public ?\DateTimeImmutable $StartPeriod, + public ?\DateTimeImmutable $EndPeriod, public ?string $NoDiscountAmountIncl, public ?string $NoDiscountAmountExcl, public ?string $DiscountAmountIncl, @@ -34,20 +36,20 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), - Date: $bag->nullableString('Date'), - Number: $bag->nullableString('Number'), + Identifier: $bag->nullableInt('Identifier'), + Date: $bag->nullableDateTime('Date'), + Number: $bag->nullableInt('Number'), NumberSuffix: $bag->nullableString('NumberSuffix'), ProductCode: $bag->nullableString('ProductCode'), Description: $bag->nullableString('Description'), PriceExcl: $bag->nullableString('PriceExcl'), DiscountPercentage: $bag->nullableString('DiscountPercentage'), - DiscountPercentageType: $bag->nullableString('DiscountPercentageType'), + DiscountPercentageType: self::nullableEnum($bag, 'DiscountPercentageType', DiscountPercentageType::class), TaxPercentage: $bag->nullableString('TaxPercentage'), - Periods: $bag->nullableString('Periods'), - Periodic: $bag->nullableString('Periodic'), - StartPeriod: $bag->nullableString('StartPeriod'), - EndPeriod: $bag->nullableString('EndPeriod'), + Periods: $bag->nullableInt('Periods'), + Periodic: self::nullableEnum($bag, 'Periodic', Periodic::class), + StartPeriod: $bag->nullableDateTime('StartPeriod'), + EndPeriod: $bag->nullableDateTime('EndPeriod'), NoDiscountAmountIncl: $bag->nullableString('NoDiscountAmountIncl'), NoDiscountAmountExcl: $bag->nullableString('NoDiscountAmountExcl'), DiscountAmountIncl: $bag->nullableString('DiscountAmountIncl'), diff --git a/src/Api/Entity/Product.php b/src/Api/Entity/Product.php index 13ecc9f24..10e9a715d 100644 --- a/src/Api/Entity/Product.php +++ b/src/Api/Entity/Product.php @@ -2,6 +2,8 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; +use Hyperized\Hostfact\Api\Entity\Enum\ProductType; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Product extends Entity @@ -12,22 +14,22 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $ProductCode, public ?string $ProductName, public ?string $ProductKeyPhrase, public ?string $ProductDescription, public ?string $NumberSuffix, public ?string $PriceExcl, - public ?string $PricePeriod, + public ?Periodic $PricePeriod, public ?string $TaxPercentage, public ?string $Cost, - public ?string $ProductType, + public ?ProductType $ProductType, public ?string $ProductTld, - public ?string $PackageID, - public ?string $HasCustomPrice, - public ?string $Created, - public ?string $Modified, + public ?int $PackageID, + public ?bool $HasCustomPrice, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public array $Groups, public array $Translations, ) { @@ -38,22 +40,22 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), ProductCode: $bag->nullableString('ProductCode'), ProductName: $bag->nullableString('ProductName'), ProductKeyPhrase: $bag->nullableString('ProductKeyPhrase'), ProductDescription: $bag->nullableString('ProductDescription'), NumberSuffix: $bag->nullableString('NumberSuffix'), PriceExcl: $bag->nullableString('PriceExcl'), - PricePeriod: $bag->nullableString('PricePeriod'), + PricePeriod: self::nullableEnum($bag, 'PricePeriod', Periodic::class), TaxPercentage: $bag->nullableString('TaxPercentage'), Cost: $bag->nullableString('Cost'), - ProductType: $bag->nullableString('ProductType'), + ProductType: self::nullableEnum($bag, 'ProductType', ProductType::class), ProductTld: $bag->nullableString('ProductTld'), - PackageID: $bag->nullableString('PackageID'), - HasCustomPrice: $bag->nullableString('HasCustomPrice'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + PackageID: $bag->nullableInt('PackageID'), + HasCustomPrice: $bag->nullableBool('HasCustomPrice'), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Groups: $bag->has('Groups') ? $bag->bags('Groups') : [], Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], ); diff --git a/src/Api/Entity/Ssl.php b/src/Api/Entity/Ssl.php index 4f7057652..c50b6acad 100644 --- a/src/Api/Entity/Ssl.php +++ b/src/Api/Entity/Ssl.php @@ -2,36 +2,37 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\SslStatus; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Ssl extends Entity { public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $CommonName, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, public ?string $Registrar, - public ?string $SSLTypeID, + public ?int $SSLTypeID, public ?string $OwnerHandle, public ?string $AdminHandle, public ?string $TechHandle, public ?string $Type, - public ?string $Wildcard, - public ?string $MultiDomain, - public ?string $MultiDomainRecords, + public ?bool $Wildcard, + public ?bool $MultiDomain, + public ?int $MultiDomainRecords, public ?string $ApproverEmail, public ?string $CSR, public ?string $ServerSoftware, - public ?string $Period, - public ?string $RequestDate, - public ?string $RenewDate, + public ?int $Period, + public ?\DateTimeImmutable $RequestDate, + public ?\DateTimeImmutable $RenewDate, public ?string $RegistrarReference, public ?string $Comment, - public ?string $Status, - public ?string $Created, - public ?string $Modified, + public ?SslStatus $Status, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?Subscription $Subscription, public ?DataBag $SSLProductInfo, public ?DataBag $RegistrarInfo, @@ -43,30 +44,30 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), CommonName: $bag->nullableString('CommonName'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), Registrar: $bag->nullableString('Registrar'), - SSLTypeID: $bag->nullableString('SSLTypeID'), + SSLTypeID: $bag->nullableInt('SSLTypeID'), OwnerHandle: $bag->nullableString('OwnerHandle'), AdminHandle: $bag->nullableString('AdminHandle'), TechHandle: $bag->nullableString('TechHandle'), Type: $bag->nullableString('Type'), - Wildcard: $bag->nullableString('Wildcard'), - MultiDomain: $bag->nullableString('MultiDomain'), - MultiDomainRecords: $bag->nullableString('MultiDomainRecords'), + Wildcard: $bag->nullableBool('Wildcard'), + MultiDomain: $bag->nullableBool('MultiDomain'), + MultiDomainRecords: $bag->nullableInt('MultiDomainRecords'), ApproverEmail: $bag->nullableString('ApproverEmail'), CSR: $bag->nullableString('CSR'), ServerSoftware: $bag->nullableString('ServerSoftware'), - Period: $bag->nullableString('Period'), - RequestDate: $bag->nullableString('RequestDate'), - RenewDate: $bag->nullableString('RenewDate'), + Period: $bag->nullableInt('Period'), + RequestDate: $bag->nullableDateTime('RequestDate'), + RenewDate: $bag->nullableDateTime('RenewDate'), RegistrarReference: $bag->nullableString('RegistrarReference'), Comment: $bag->nullableString('Comment'), - Status: $bag->nullableString('Status'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Status: self::nullableEnum($bag, 'Status', SslStatus::class), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, SSLProductInfo: $bag->has('SSLProductInfo') ? $bag->bag('SSLProductInfo') : null, RegistrarInfo: $bag->has('RegistrarInfo') ? $bag->bag('RegistrarInfo') : null, diff --git a/src/Api/Entity/Subscription.php b/src/Api/Entity/Subscription.php index 181cd808d..30932b61d 100644 --- a/src/Api/Entity/Subscription.php +++ b/src/Api/Entity/Subscription.php @@ -2,13 +2,14 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Subscription extends Entity { public function __construct( DataBag $bag, - public ?string $Number, + public ?int $Number, public ?string $NumberSuffix, public ?string $ProductCode, public ?string $Description, @@ -16,18 +17,18 @@ public function __construct( public ?string $PriceIncl, public ?string $TaxPercentage, public ?string $DiscountPercentage, - public ?string $Periods, - public ?string $Periodic, - public ?string $StartPeriod, - public ?string $EndPeriod, - public ?string $NextDate, - public ?string $ContractPeriods, - public ?string $ContractPeriodic, - public ?string $StartContract, - public ?string $EndContract, - public ?string $TerminationDate, - public ?string $Reminder, - public ?string $InvoiceAuthorisation, + public ?int $Periods, + public ?Periodic $Periodic, + public ?\DateTimeImmutable $StartPeriod, + public ?\DateTimeImmutable $EndPeriod, + public ?\DateTimeImmutable $NextDate, + public ?int $ContractPeriods, + public ?Periodic $ContractPeriodic, + public ?\DateTimeImmutable $StartContract, + public ?\DateTimeImmutable $EndContract, + public ?\DateTimeImmutable $TerminationDate, + public ?bool $Reminder, + public ?bool $InvoiceAuthorisation, public ?string $AmountExcl, public ?string $AmountIncl, ) { @@ -38,7 +39,7 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Number: $bag->nullableString('Number'), + Number: $bag->nullableInt('Number'), NumberSuffix: $bag->nullableString('NumberSuffix'), ProductCode: $bag->nullableString('ProductCode'), Description: $bag->nullableString('Description'), @@ -46,18 +47,18 @@ public static function fromBag(DataBag $bag): static PriceIncl: $bag->nullableString('PriceIncl'), TaxPercentage: $bag->nullableString('TaxPercentage'), DiscountPercentage: $bag->nullableString('DiscountPercentage'), - Periods: $bag->nullableString('Periods'), - Periodic: $bag->nullableString('Periodic'), - StartPeriod: $bag->nullableString('StartPeriod'), - EndPeriod: $bag->nullableString('EndPeriod'), - NextDate: $bag->nullableString('NextDate'), - ContractPeriods: $bag->nullableString('ContractPeriods'), - ContractPeriodic: $bag->nullableString('ContractPeriodic'), - StartContract: $bag->nullableString('StartContract'), - EndContract: $bag->nullableString('EndContract'), - TerminationDate: $bag->nullableString('TerminationDate'), - Reminder: $bag->nullableString('Reminder'), - InvoiceAuthorisation: $bag->nullableString('InvoiceAuthorisation'), + Periods: $bag->nullableInt('Periods'), + Periodic: self::nullableEnum($bag, 'Periodic', Periodic::class), + StartPeriod: $bag->nullableDateTime('StartPeriod'), + EndPeriod: $bag->nullableDateTime('EndPeriod'), + NextDate: $bag->nullableDateTime('NextDate'), + ContractPeriods: $bag->nullableInt('ContractPeriods'), + ContractPeriodic: self::nullableEnum($bag, 'ContractPeriodic', Periodic::class), + StartContract: $bag->nullableDateTime('StartContract'), + EndContract: $bag->nullableDateTime('EndContract'), + TerminationDate: $bag->nullableDateTime('TerminationDate'), + Reminder: $bag->nullableBool('Reminder'), + InvoiceAuthorisation: $bag->nullableBool('InvoiceAuthorisation'), AmountExcl: $bag->nullableString('AmountExcl'), AmountIncl: $bag->nullableString('AmountIncl'), ); diff --git a/src/Api/Entity/Ticket.php b/src/Api/Entity/Ticket.php index 223ea7af5..3576d6b18 100644 --- a/src/Api/Entity/Ticket.php +++ b/src/Api/Entity/Ticket.php @@ -2,6 +2,9 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\TicketPriority; +use Hyperized\Hostfact\Api\Entity\Enum\TicketStatus; +use Hyperized\Hostfact\Api\Entity\Enum\TicketType; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Ticket extends Entity @@ -12,21 +15,21 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $TicketID, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, public ?string $EmailAddress, public ?string $CC, - public ?string $Type, - public ?string $Date, + public ?TicketType $Type, + public ?\DateTimeImmutable $Date, public ?string $Subject, public ?string $Owner, - public ?string $Priority, - public ?string $Status, + public ?TicketPriority $Priority, + public ?TicketStatus $Status, public ?string $Comment, - public ?string $Number, - public ?string $LastDate, + public ?int $Number, + public ?\DateTimeImmutable $LastDate, public ?string $LastName, public array $TicketMessages, public array $Translations, @@ -45,21 +48,21 @@ public static function fromBag(DataBag $bag): static return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), TicketID: $bag->nullableString('TicketID'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), EmailAddress: $bag->nullableString('EmailAddress'), CC: $bag->nullableString('CC'), - Type: $bag->nullableString('Type'), - Date: $bag->nullableString('Date'), + Type: self::nullableEnum($bag, 'Type', TicketType::class), + Date: $bag->nullableDateTime('Date'), Subject: $bag->nullableString('Subject'), Owner: $bag->nullableString('Owner'), - Priority: $bag->nullableString('Priority'), - Status: $bag->nullableString('Status'), + Priority: self::nullableEnum($bag, 'Priority', TicketPriority::class), + Status: self::nullableEnum($bag, 'Status', TicketStatus::class), Comment: $bag->nullableString('Comment'), - Number: $bag->nullableString('Number'), - LastDate: $bag->nullableString('LastDate'), + Number: $bag->nullableInt('Number'), + LastDate: $bag->nullableDateTime('LastDate'), LastName: $bag->nullableString('LastName'), TicketMessages: $messages, Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], diff --git a/src/Api/Entity/TicketMessage.php b/src/Api/Entity/TicketMessage.php index 6ac04d5a3..e31e8609b 100644 --- a/src/Api/Entity/TicketMessage.php +++ b/src/Api/Entity/TicketMessage.php @@ -11,11 +11,11 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, - public ?string $Date, + public ?int $Identifier, + public ?\DateTimeImmutable $Date, public ?string $Subject, public ?string $Base64Message, - public ?string $SenderID, + public ?int $SenderID, public ?string $SenderName, public ?string $SenderEmail, public array $Attachments, @@ -27,11 +27,11 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), - Date: $bag->nullableString('Date'), + Identifier: $bag->nullableInt('Identifier'), + Date: $bag->nullableDateTime('Date'), Subject: $bag->nullableString('Subject'), Base64Message: $bag->nullableString('Base64Message'), - SenderID: $bag->nullableString('SenderID'), + SenderID: $bag->nullableInt('SenderID'), SenderName: $bag->nullableString('SenderName'), SenderEmail: $bag->nullableString('SenderEmail'), Attachments: $bag->has('Attachments') ? $bag->bags('Attachments') : [], diff --git a/src/Api/Entity/Vps.php b/src/Api/Entity/Vps.php index 6cae0d617..5627b3095 100644 --- a/src/Api/Entity/Vps.php +++ b/src/Api/Entity/Vps.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Api\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\VpsStatus; use Hyperized\Hostfact\Api\Response\DataBag; final readonly class Vps extends Entity @@ -11,23 +12,23 @@ */ public function __construct( DataBag $bag, - public ?string $Identifier, + public ?int $Identifier, public ?string $Hostname, - public ?string $Debtor, + public ?int $Debtor, public ?string $DebtorCode, public ?string $IPAddress, public ?string $Package, public ?string $Node, - public ?string $ServerID, + public ?int $ServerID, public ?string $Image, - public ?string $MemoryMB, - public ?string $DiskSpaceGB, - public ?string $BandWidthGB, - public ?string $CPUCores, + public ?int $MemoryMB, + public ?int $DiskSpaceGB, + public ?int $BandWidthGB, + public ?int $CPUCores, public ?string $Comment, - public ?string $Status, - public ?string $Created, - public ?string $Modified, + public ?VpsStatus $Status, + public ?\DateTimeImmutable $Created, + public ?\DateTimeImmutable $Modified, public ?Subscription $Subscription, public ?DataBag $NodeInfo, public array $Translations, @@ -39,23 +40,23 @@ public static function fromBag(DataBag $bag): static { return new self( bag: $bag, - Identifier: $bag->nullableString('Identifier'), + Identifier: $bag->nullableInt('Identifier'), Hostname: $bag->nullableString('Hostname'), - Debtor: $bag->nullableString('Debtor'), + Debtor: $bag->nullableInt('Debtor'), DebtorCode: $bag->nullableString('DebtorCode'), IPAddress: $bag->nullableString('IPAddress'), Package: $bag->nullableString('Package'), Node: $bag->nullableString('Node'), - ServerID: $bag->nullableString('ServerID'), + ServerID: $bag->nullableInt('ServerID'), Image: $bag->nullableString('Image'), - MemoryMB: $bag->nullableString('MemoryMB'), - DiskSpaceGB: $bag->nullableString('DiskSpaceGB'), - BandWidthGB: $bag->nullableString('BandWidthGB'), - CPUCores: $bag->nullableString('CPUCores'), + MemoryMB: $bag->nullableInt('MemoryMB'), + DiskSpaceGB: $bag->nullableInt('DiskSpaceGB'), + BandWidthGB: $bag->nullableInt('BandWidthGB'), + CPUCores: $bag->nullableInt('CPUCores'), Comment: $bag->nullableString('Comment'), - Status: $bag->nullableString('Status'), - Created: $bag->nullableString('Created'), - Modified: $bag->nullableString('Modified'), + Status: self::nullableEnum($bag, 'Status', VpsStatus::class), + Created: $bag->nullableDateTime('Created'), + Modified: $bag->nullableDateTime('Modified'), Subscription: $bag->has('Subscription') ? Subscription::fromBag($bag->bag('Subscription')) : null, NodeInfo: $bag->has('NodeInfo') ? $bag->bag('NodeInfo') : null, Translations: $bag->has('Translations') ? $bag->bags('Translations') : [], diff --git a/tests/Unit/Entity/InvoiceEntityTest.php b/tests/Unit/Entity/InvoiceEntityTest.php index 25a0fde2f..4b5a448bb 100644 --- a/tests/Unit/Entity/InvoiceEntityTest.php +++ b/tests/Unit/Entity/InvoiceEntityTest.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Tests\Unit\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\InvoiceStatus; use Hyperized\Hostfact\Api\Entity\Invoice; use Hyperized\Hostfact\Api\Entity\InvoiceLine; use Hyperized\Hostfact\Api\Response\DataBag; @@ -22,9 +23,10 @@ public function testFromBagExtractsScalarFields(): void $invoice = Invoice::fromBag($bag); - self::assertSame('10', $invoice->Identifier); + self::assertSame(10, $invoice->Identifier); self::assertSame('F0001', $invoice->InvoiceCode); self::assertSame('DB0001', $invoice->DebtorCode); + self::assertSame(InvoiceStatus::PartiallyPaid, $invoice->Status); self::assertSame('100.00', $invoice->AmountExcl); self::assertEmpty($invoice->InvoiceLines); } diff --git a/tests/Unit/Entity/ProductEntityTest.php b/tests/Unit/Entity/ProductEntityTest.php index af7790abf..eb9d7b0f3 100644 --- a/tests/Unit/Entity/ProductEntityTest.php +++ b/tests/Unit/Entity/ProductEntityTest.php @@ -2,6 +2,8 @@ namespace Hyperized\Hostfact\Tests\Unit\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; +use Hyperized\Hostfact\Api\Entity\Enum\ProductType; use Hyperized\Hostfact\Api\Entity\Product; use Hyperized\Hostfact\Api\Response\DataBag; use PHPUnit\Framework\TestCase; @@ -35,15 +37,16 @@ public function testFromBagExtractsAllFields(): void $product = Product::fromBag($bag); - self::assertSame('3', $product->Identifier); + self::assertSame(3, $product->Identifier); self::assertSame('P001', $product->ProductCode); self::assertSame('Hosting Basic', $product->ProductName); self::assertSame('Basic hosting', $product->ProductKeyPhrase); self::assertSame('250', $product->PriceExcl); self::assertSame('21', $product->TaxPercentage); - self::assertSame('hosting', $product->ProductType); - self::assertSame('no', $product->HasCustomPrice); - self::assertSame('2022-11-24 11:00:00', $product->Created); + self::assertSame(ProductType::Hosting, $product->ProductType); + self::assertSame(false, $product->HasCustomPrice); + self::assertInstanceOf(\DateTimeImmutable::class, $product->Created); + self::assertSame('2022-11-24 11:00:00', $product->Created->format('Y-m-d H:i:s')); self::assertEmpty($product->Groups); self::assertCount(1, $product->Translations); } @@ -54,7 +57,7 @@ public function testMissingFieldsReturnNull(): void $product = Product::fromBag($bag); - self::assertSame('1', $product->Identifier); + self::assertSame(1, $product->Identifier); self::assertNull($product->ProductCode); self::assertNull($product->ProductName); self::assertNull($product->PriceExcl); diff --git a/tests/Unit/Entity/SubscriptionEntityTest.php b/tests/Unit/Entity/SubscriptionEntityTest.php index 783b0f1e4..0d7280971 100644 --- a/tests/Unit/Entity/SubscriptionEntityTest.php +++ b/tests/Unit/Entity/SubscriptionEntityTest.php @@ -2,6 +2,7 @@ namespace Hyperized\Hostfact\Tests\Unit\Entity; +use Hyperized\Hostfact\Api\Entity\Enum\Periodic; use Hyperized\Hostfact\Api\Entity\Hosting; use Hyperized\Hostfact\Api\Entity\Subscription; use Hyperized\Hostfact\Api\Response\DataBag; @@ -27,12 +28,12 @@ public function testFromBagExtractsAllFields(): void $sub = Subscription::fromBag($bag); - self::assertSame('1', $sub->Number); + self::assertSame(1, $sub->Number); self::assertSame('P002', $sub->ProductCode); self::assertSame('25', $sub->PriceExcl); self::assertSame('30.25', $sub->PriceIncl); - self::assertSame('m', $sub->Periodic); - self::assertSame('yes', $sub->InvoiceAuthorisation); + self::assertSame(Periodic::Month, $sub->Periodic); + self::assertSame(true, $sub->InvoiceAuthorisation); } public function testMissingFieldsReturnNull(): void From 7adbf1441b6efcb0726e84d09b219981d0bd6029 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 16:48:19 +0200 Subject: [PATCH 14/30] Update docs and examples to use typed entities --- README.md | 85 +++++++++++++++++++++++++------- examples/customer-onboarding.php | 15 ++++-- examples/error-handling.php | 10 ++-- 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index adc4bcb36..d9dfaf9ac 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Every controller provides a static `new()` factory that reads configuration from ```php use Hyperized\Hostfact\Api\Controllers\Product; +use Hyperized\Hostfact\Api\Entity\Product as ProductEntity; use Hyperized\Hostfact\Api\Response\ListResponse; $response = Product::new()->list(['searchfor' => 'hosting']); @@ -54,9 +55,10 @@ $response = Product::new()->list(['searchfor' => 'hosting']); if ($response instanceof ListResponse) { echo $response->pagination->totalResults . ' results'; - foreach ($response->items as $product) { - echo $product->string('ProductName'); - echo $product->float('PriceExcl'); + foreach ($response->entities as $product) { + assert($product instanceof ProductEntity); + echo $product->ProductName; + echo $product->PriceExcl; } } ``` @@ -78,29 +80,78 @@ All API methods return an `ApiResponse` subclass: | Response Type | When | Properties | |---|---|---| -| `ShowResponse` | Single entity returned | `data` (DataBag) | -| `ListResponse` | Multiple entities returned | `items` (list of DataBag), `pagination` | +| `ShowResponse` | Single entity returned | `entity` (typed entity), `data` (DataBag) | +| `ListResponse` | Multiple entities returned | `entities` (list of typed entities), `items` (list of DataBag), `pagination` | | `ActionResponse` | Action with no entity data (e.g. markAsPaid) | — | | `ErrorResponse` | API returned an error | `errors` (list of strings) | All responses share: `controller`, `action`, `status`, `date`, `isSuccess()`, `isError()`, `toArray()`. +### Typed Entities + +Responses include typed entity objects with IDE autocompletion and strict PHP types: + +```php +use Hyperized\Hostfact\Api\Controllers\Invoice; +use Hyperized\Hostfact\Api\Entity\Invoice as InvoiceEntity; +use Hyperized\Hostfact\Api\Response\ShowResponse; + +$response = Invoice::new()->show(['InvoiceCode' => 'F0001']); +assert($response instanceof ShowResponse); + +$invoice = $response->entity; +assert($invoice instanceof InvoiceEntity); + +$invoice->Identifier; // ?int +$invoice->InvoiceCode; // ?string +$invoice->Status; // ?InvoiceStatus (enum) +$invoice->Date; // ?DateTimeImmutable +$invoice->AmountExcl; // ?string (for bcmath precision) +$invoice->Sent; // ?bool + +// Nested entities +foreach ($invoice->InvoiceLines as $line) { + $line->Description; // ?string + $line->PriceExcl; // ?string +} + +// Fallback to DataBag for undocumented fields +$invoice->bag->string('SomeUndocumentedField'); +``` + +For list responses: + +```php +$response = Product::new()->list(['searchfor' => 'hosting']); +assert($response instanceof ListResponse); + +foreach ($response->entities as $product) { + assert($product instanceof ProductEntity); + echo $product->ProductCode; + echo $product->ProductName; +} +``` + +Available entity classes: `Product`, `Debtor`, `Invoice`, `Domain`, `Hosting`, `Ssl`, `Vps`, `Ticket`, `Order`, `PriceQuote`, `Creditor`, `Group`. Controllers without documented fields (`Service`, `CreditInvoice`, `Handle`) return a `DataBag` as the entity. + ### DataBag -Entity data is accessed through typed methods on `DataBag`: +The raw API data is also accessible through typed methods on `DataBag`: ```php -$bag->string('ProductCode') // string -$bag->int('Identifier') // int -$bag->float('PriceExcl') // float -$bag->bool('AutoRenew') // bool (handles "yes"/"no", 1/0) -$bag->nullableString('Comment') // ?string -$bag->nullableInt('PackageID') // ?int -$bag->array('Groups') // array -$bag->bag('Subscription') // nested DataBag -$bag->bags('InvoiceLines') // list -$bag->has('SomeField') // bool -$bag['ProductCode'] // mixed (ArrayAccess) +$bag->string('ProductCode') // string +$bag->int('Identifier') // int +$bag->float('PriceExcl') // float +$bag->bool('AutoRenew') // bool (handles "yes"/"no", 1/0) +$bag->nullableString('Comment') // ?string +$bag->nullableInt('PackageID') // ?int +$bag->nullableBool('Sent') // ?bool +$bag->nullableDateTime('Created') // ?DateTimeImmutable +$bag->array('Groups') // array +$bag->bag('Subscription') // nested DataBag +$bag->bags('InvoiceLines') // list +$bag->has('SomeField') // bool +$bag['ProductCode'] // mixed (ArrayAccess) ``` ## Available Controllers diff --git a/examples/customer-onboarding.php b/examples/customer-onboarding.php index 2d235415c..0cc612f4d 100644 --- a/examples/customer-onboarding.php +++ b/examples/customer-onboarding.php @@ -14,6 +14,9 @@ use Hyperized\Hostfact\Api\Controllers\Domain; use Hyperized\Hostfact\Api\Controllers\Hosting; use Hyperized\Hostfact\Api\Controllers\Invoice; +use Hyperized\Hostfact\Api\Entity\Debtor as DebtorEntity; +use Hyperized\Hostfact\Api\Entity\Hosting as HostingEntity; +use Hyperized\Hostfact\Api\Entity\Invoice as InvoiceEntity; use Hyperized\Hostfact\Api\Response\ErrorResponse; use Hyperized\Hostfact\Api\Response\ShowResponse; use Hyperized\Hostfact\Exceptions\InvalidArgumentException; @@ -42,7 +45,9 @@ } assert($debtorResponse instanceof ShowResponse); -$debtorCode = $debtorResponse->data->string('DebtorCode'); +$debtor = $debtorResponse->entity; +assert($debtor instanceof DebtorEntity); +$debtorCode = $debtor->DebtorCode; echo "Customer created: {$debtorCode}\n"; // --------------------------------------------------------------------------- @@ -80,7 +85,9 @@ } assert($hostingResponse instanceof ShowResponse); -$hostingCode = $hostingResponse->data->string('HostingCode'); +$hosting = $hostingResponse->entity; +assert($hosting instanceof HostingEntity); +$hostingCode = $hosting->bag->string('HostingCode'); echo "Hosting created: {$hostingCode}\n"; // Provision the account on the server @@ -111,7 +118,9 @@ } assert($invoiceResponse instanceof ShowResponse); -$invoiceCode = $invoiceResponse->data->string('InvoiceCode'); +$invoice = $invoiceResponse->entity; +assert($invoice instanceof InvoiceEntity); +$invoiceCode = $invoice->InvoiceCode; // Add the hosting line Invoice::new()->lineAdd([ diff --git a/examples/error-handling.php b/examples/error-handling.php index a8eca9534..88383ac5d 100644 --- a/examples/error-handling.php +++ b/examples/error-handling.php @@ -9,6 +9,7 @@ */ use Hyperized\Hostfact\Api\Controllers\Product; +use Hyperized\Hostfact\Api\Entity\Product as ProductEntity; use Hyperized\Hostfact\Api\Response\ErrorResponse; use Hyperized\Hostfact\Api\Response\ListResponse; use Hyperized\Hostfact\Exceptions\InvalidArgumentException; @@ -32,11 +33,12 @@ } if ($response instanceof ListResponse) { - // Process the results - echo 'Found ' . count($response->items) . ' products'; + // Process the results using typed entities + echo 'Found ' . count($response->entities) . ' products'; - foreach ($response->items as $product) { - echo $product->string('ProductName'); + foreach ($response->entities as $product) { + assert($product instanceof ProductEntity); + echo $product->ProductName; } } From 67ba1ee767035960777a02ba848a752d4333b5a1 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:10:20 +0200 Subject: [PATCH 15/30] Add tests for Group, Order, PriceQuote, and Ticket entities --- tests/Unit/Entity/GroupEntityTest.php | 58 ++++++++++++++++++ tests/Unit/Entity/OrderEntityTest.php | 65 ++++++++++++++++++++ tests/Unit/Entity/PriceQuoteEntityTest.php | 66 +++++++++++++++++++++ tests/Unit/Entity/TicketEntityTest.php | 69 ++++++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 tests/Unit/Entity/GroupEntityTest.php create mode 100644 tests/Unit/Entity/OrderEntityTest.php create mode 100644 tests/Unit/Entity/PriceQuoteEntityTest.php create mode 100644 tests/Unit/Entity/TicketEntityTest.php diff --git a/tests/Unit/Entity/GroupEntityTest.php b/tests/Unit/Entity/GroupEntityTest.php new file mode 100644 index 000000000..c0f8c9103 --- /dev/null +++ b/tests/Unit/Entity/GroupEntityTest.php @@ -0,0 +1,58 @@ + '5', + 'GroupName' => 'Hosting products', + 'Type' => 'product', + 'Items' => [ + ['Identifier' => '1', 'ProductCode' => 'P001', 'ProductName' => 'Basic'], + ['Identifier' => '2', 'ProductCode' => 'P002', 'ProductName' => 'Pro'], + ], + ]); + + $group = Group::fromBag($bag); + + self::assertSame(5, $group->Identifier); + self::assertSame('Hosting products', $group->GroupName); + self::assertSame(GroupType::Product, $group->Type); + self::assertCount(2, $group->Items); + self::assertInstanceOf(GroupItem::class, $group->Items[0]); + self::assertSame(1, $group->Items[0]->Identifier); + self::assertSame('P001', $group->Items[0]->ProductCode); + self::assertSame('Basic', $group->Items[0]->ProductName); + self::assertSame('P002', $group->Items[1]->ProductCode); + } + + public function testFromBagWithoutItems(): void + { + $group = Group::fromBag(new DataBag(['Identifier' => '1'])); + + self::assertSame(1, $group->Identifier); + self::assertEmpty($group->Items); + } + + public function testGroupItemBagIsAccessible(): void + { + $bag = new DataBag([ + 'Items' => [ + ['Identifier' => '1', 'Extra' => 'data'], + ], + ]); + + $group = Group::fromBag($bag); + + self::assertSame('data', $group->Items[0]->bag->string('Extra')); + } +} diff --git a/tests/Unit/Entity/OrderEntityTest.php b/tests/Unit/Entity/OrderEntityTest.php new file mode 100644 index 000000000..2a1c128d6 --- /dev/null +++ b/tests/Unit/Entity/OrderEntityTest.php @@ -0,0 +1,65 @@ + '7', + 'OrderCode' => 'O0001', + 'OrderLines' => [ + [ + 'Identifier' => '1', + 'Description' => 'Hosting package', + 'PriceExcl' => '99.00', + 'TaxPercentage' => '21', + 'Periods' => '12', + 'Periodic' => 'm', + 'ProductType' => 'hosting', + ], + ], + ]); + + $order = Order::fromBag($bag); + + self::assertSame(7, $order->Identifier); + self::assertSame('O0001', $order->OrderCode); + self::assertCount(1, $order->OrderLines); + self::assertInstanceOf(OrderLine::class, $order->OrderLines[0]); + self::assertSame(1, $order->OrderLines[0]->Identifier); + self::assertSame('Hosting package', $order->OrderLines[0]->Description); + self::assertSame('99.00', $order->OrderLines[0]->PriceExcl); + self::assertSame(12, $order->OrderLines[0]->Periods); + self::assertSame(Periodic::Month, $order->OrderLines[0]->Periodic); + self::assertSame(ProductType::Hosting, $order->OrderLines[0]->ProductType); + } + + public function testFromBagWithoutOrderLines(): void + { + $order = Order::fromBag(new DataBag([])); + + self::assertEmpty($order->OrderLines); + } + + public function testOrderLineBagIsAccessible(): void + { + $bag = new DataBag([ + 'OrderLines' => [ + ['Identifier' => '1', 'Custom' => 'value'], + ], + ]); + + $order = Order::fromBag($bag); + + self::assertSame('value', $order->OrderLines[0]->bag->string('Custom')); + } +} diff --git a/tests/Unit/Entity/PriceQuoteEntityTest.php b/tests/Unit/Entity/PriceQuoteEntityTest.php new file mode 100644 index 000000000..4ad0fd2b9 --- /dev/null +++ b/tests/Unit/Entity/PriceQuoteEntityTest.php @@ -0,0 +1,66 @@ + '3', + 'PriceQuoteCode' => 'PQ0001', + 'PriceQuoteLines' => [ + [ + 'Identifier' => '1', + 'Description' => 'Web development', + 'PriceExcl' => '1500.00', + 'TaxPercentage' => '21', + 'Periods' => '1', + 'Periodic' => 'j', + 'StartPeriod' => '2024-01-01', + 'EndPeriod' => '2024-12-31', + ], + ], + ]); + + $quote = PriceQuote::fromBag($bag); + + self::assertSame(3, $quote->Identifier); + self::assertSame('PQ0001', $quote->PriceQuoteCode); + self::assertCount(1, $quote->PriceQuoteLines); + self::assertInstanceOf(PriceQuoteLine::class, $quote->PriceQuoteLines[0]); + self::assertSame(1, $quote->PriceQuoteLines[0]->Identifier); + self::assertSame('Web development', $quote->PriceQuoteLines[0]->Description); + self::assertSame('1500.00', $quote->PriceQuoteLines[0]->PriceExcl); + self::assertSame(1, $quote->PriceQuoteLines[0]->Periods); + self::assertSame(Periodic::Year, $quote->PriceQuoteLines[0]->Periodic); + self::assertInstanceOf(\DateTimeImmutable::class, $quote->PriceQuoteLines[0]->StartPeriod); + self::assertInstanceOf(\DateTimeImmutable::class, $quote->PriceQuoteLines[0]->EndPeriod); + } + + public function testFromBagWithoutPriceQuoteLines(): void + { + $quote = PriceQuote::fromBag(new DataBag([])); + + self::assertEmpty($quote->PriceQuoteLines); + } + + public function testPriceQuoteLineBagIsAccessible(): void + { + $bag = new DataBag([ + 'PriceQuoteLines' => [ + ['Identifier' => '1', 'Extra' => 'info'], + ], + ]); + + $quote = PriceQuote::fromBag($bag); + + self::assertSame('info', $quote->PriceQuoteLines[0]->bag->string('Extra')); + } +} diff --git a/tests/Unit/Entity/TicketEntityTest.php b/tests/Unit/Entity/TicketEntityTest.php new file mode 100644 index 000000000..f34971147 --- /dev/null +++ b/tests/Unit/Entity/TicketEntityTest.php @@ -0,0 +1,69 @@ + '12', + 'TicketID' => 'T-0001', + 'Status' => '1', + 'TicketMessages' => [ + [ + 'Identifier' => '1', + 'Date' => '2024-03-01 10:00:00', + 'Subject' => 'Help needed', + 'Base64Message' => base64_encode('Hello'), + 'SenderID' => '5', + 'SenderName' => 'Jan', + 'SenderEmail' => 'jan@example.com', + 'Attachments' => [ + ['Filename' => 'screenshot.png'], + ], + ], + ], + ]); + + $ticket = Ticket::fromBag($bag); + + self::assertSame(12, $ticket->Identifier); + self::assertSame('T-0001', $ticket->TicketID); + self::assertSame(TicketStatus::Answered, $ticket->Status); + self::assertCount(1, $ticket->TicketMessages); + self::assertInstanceOf(TicketMessage::class, $ticket->TicketMessages[0]); + self::assertSame(1, $ticket->TicketMessages[0]->Identifier); + self::assertSame('Help needed', $ticket->TicketMessages[0]->Subject); + self::assertSame(5, $ticket->TicketMessages[0]->SenderID); + self::assertSame('Jan', $ticket->TicketMessages[0]->SenderName); + self::assertInstanceOf(\DateTimeImmutable::class, $ticket->TicketMessages[0]->Date); + self::assertCount(1, $ticket->TicketMessages[0]->Attachments); + } + + public function testFromBagWithoutTicketMessages(): void + { + $ticket = Ticket::fromBag(new DataBag([])); + + self::assertEmpty($ticket->TicketMessages); + } + + public function testTicketMessageBagIsAccessible(): void + { + $bag = new DataBag([ + 'TicketMessages' => [ + ['Identifier' => '1', 'Custom' => 'field'], + ], + ]); + + $ticket = Ticket::fromBag($bag); + + self::assertSame('field', $ticket->TicketMessages[0]->bag->string('Custom')); + } +} From 2b371ff2a68f6a6184ff82f9927727a33c8b741d Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:10:23 +0200 Subject: [PATCH 16/30] Add tests for ServiceProvider::provides and Facade accessor --- tests/Feature/HostfactFacadeTest.php | 23 +++++++++++++++++++++++ tests/Feature/ServiceProviderTest.php | 6 ++++++ 2 files changed, 29 insertions(+) create mode 100644 tests/Feature/HostfactFacadeTest.php diff --git a/tests/Feature/HostfactFacadeTest.php b/tests/Feature/HostfactFacadeTest.php new file mode 100644 index 000000000..244bfb75f --- /dev/null +++ b/tests/Feature/HostfactFacadeTest.php @@ -0,0 +1,23 @@ +invoke(null); + self::assertSame('Hostfact', $accessor); + } +} diff --git a/tests/Feature/ServiceProviderTest.php b/tests/Feature/ServiceProviderTest.php index 89b94fc1f..39eed3669 100644 --- a/tests/Feature/ServiceProviderTest.php +++ b/tests/Feature/ServiceProviderTest.php @@ -95,4 +95,10 @@ public function testPublishTargetIsConfigPath(): void self::assertIsString($target); self::assertStringEndsWith('Hostfact.php', $target); } + + public function testProvidesReturnsEmptyArray(): void + { + $provider = new HostfactServiceProvider($this->app); + self::assertSame([], $provider->provides()); + } } From 7a037e30587c8cac0b3bad9f171e405c50243cde Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:10:26 +0200 Subject: [PATCH 17/30] Enable prefer-lowest in CI matrix --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 15b5009c9..add2fbcb5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,7 @@ jobs: - 8.4 - 8.5 dependency-version: - # - prefer-lowest + - prefer-lowest - prefer-stable os: - ubuntu-latest From 9dffe57d05a609e85629768fff14f10a439299b4 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:26:53 +0200 Subject: [PATCH 18/30] Reduce extractErrors cyclomatic complexity to satisfy PHPMD --- src/Api/Response/ResponseFactory.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Api/Response/ResponseFactory.php b/src/Api/Response/ResponseFactory.php index 01ef658cc..03554af57 100644 --- a/src/Api/Response/ResponseFactory.php +++ b/src/Api/Response/ResponseFactory.php @@ -146,15 +146,14 @@ private static function extractErrors(array $data): array { $raw = $data['errors'] ?? []; - /** @var list $errors */ - $errors = []; - - if (is_array($raw)) { - foreach ($raw as $error) { - $errors[] = is_scalar($error) ? (string) $error : ''; - } + if (!is_array($raw)) { + return []; } - return $errors; + /** @var list */ + return array_map( + static fn(mixed $error): string => is_scalar($error) ? (string) $error : '', + $raw, + ); } } From 1623327845267a7bbf68ff3b27f4f3e020c20761 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:26:56 +0200 Subject: [PATCH 19/30] Bump phpmd/phpmd to ^2.14 for readonly class support --- composer.json | 2 +- composer.lock | 38 +++++++++++++++++++------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/composer.json b/composer.json index 0eb895809..170310656 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ }, "require-dev": { "phpunit/phpunit": "^13.0", - "phpmd/phpmd": "^2.13", + "phpmd/phpmd": "^2.14", "orchestra/testbench": "^11.0", "phpstan/phpstan": "^2.0", "squizlabs/php_codesniffer": "^3.7 || ^4.0", diff --git a/composer.lock b/composer.lock index fbcf97d78..6a9175b8b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "121e338838aba8893eb1079a8f89349b", + "content-hash": "5ba3f0223e4e62b7653052c5c43b52db", "packages": [ { "name": "guzzlehttp/guzzle", @@ -8949,16 +8949,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -9008,7 +9008,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.34.0" }, "funding": [ { @@ -9028,7 +9028,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -9286,16 +9286,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -9347,7 +9347,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.34.0" }, "funding": [ { @@ -9367,20 +9367,20 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -9431,7 +9431,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.34.0" }, "funding": [ { @@ -9451,7 +9451,7 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php83", From d12552aeaa1d88fd6b4da064ffdc5b8069efb67c Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 17:27:38 +0200 Subject: [PATCH 20/30] Update composer.lock --- composer.lock | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/composer.lock b/composer.lock index 6a9175b8b..92ea6290f 100644 --- a/composer.lock +++ b/composer.lock @@ -9032,16 +9032,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/ad1b7b9092976d6c948b8a187cec9faaea9ec1df", + "reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df", "shasum": "" }, "require": { @@ -9090,7 +9090,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.34.0" }, "funding": [ { @@ -9110,11 +9110,11 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -9177,7 +9177,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.34.0" }, "funding": [ { @@ -9201,7 +9201,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -9262,7 +9262,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.34.0" }, "funding": [ { @@ -9455,16 +9455,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", "shasum": "" }, "require": { @@ -9511,7 +9511,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.34.0" }, "funding": [ { @@ -9531,20 +9531,20 @@ "type": "tidelift" } ], - "time": "2025-07-08T02:45:35+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", + "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", "shasum": "" }, "require": { @@ -9591,7 +9591,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.34.0" }, "funding": [ { @@ -9611,20 +9611,20 @@ "type": "tidelift" } ], - "time": "2025-06-24T13:30:11+00:00" + "time": "2026-04-10T18:47:49+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + "reference": "2c408a6bb0313e6001a83628dc5506100474254e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/2c408a6bb0313e6001a83628dc5506100474254e", + "reference": "2c408a6bb0313e6001a83628dc5506100474254e", "shasum": "" }, "require": { @@ -9671,7 +9671,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.34.0" }, "funding": [ { @@ -9691,20 +9691,20 @@ "type": "tidelift" } ], - "time": "2025-06-23T16:12:55+00:00" + "time": "2026-04-10T16:50:15+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.33.0", + "version": "v1.34.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { @@ -9754,7 +9754,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.34.0" }, "funding": [ { @@ -9774,7 +9774,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/process", @@ -10858,16 +10858,16 @@ }, { "name": "webmozart/assert", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c" + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/1b99650e7ffcad232624a260bc7fbdec2ffc407c", - "reference": "1b99650e7ffcad232624a260bc7fbdec2ffc407c", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/eb0d790f735ba6cff25c683a85a1da0eadeff9e4", + "reference": "eb0d790f735ba6cff25c683a85a1da0eadeff9e4", "shasum": "" }, "require": { @@ -10914,9 +10914,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.2.0" + "source": "https://github.com/webmozarts/assert/tree/2.3.0" }, - "time": "2026-04-09T16:54:47+00:00" + "time": "2026-04-11T10:33:05+00:00" } ], "aliases": [], From 48dac38cb81f488946b7cced1dad4843c1f31302 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 20:59:34 +0200 Subject: [PATCH 21/30] Drop PHP 8.3, require PHP 8.4+ --- .github/workflows/main.yml | 1 - README.md | 2 +- composer.json | 2 +- composer.lock | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index add2fbcb5..156ef09fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,6 @@ jobs: fail-fast: false matrix: php: - - 8.3 - 8.4 - 8.5 dependency-version: diff --git a/README.md b/README.md index d9dfaf9ac..bdf254dc6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Unofficial Laravel package for the [HostFact API v2](https://www.hostfact.nl/dev ## Requirements -- PHP 8.3+ +- PHP 8.4+ - Laravel 13 and above (auto-discovery supported) ## Installation diff --git a/composer.json b/composer.json index 170310656..ad4683a4f 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.3", + "php": "^8.4", "guzzlehttp/guzzle": "^7.5", "hyperized/value-objects": "^1.0.0", "thecodingmachine/safe": "^3.4" diff --git a/composer.lock b/composer.lock index 92ea6290f..0981b0c34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5ba3f0223e4e62b7653052c5c43b52db", + "content-hash": "937ab82915766938d92622e0bb94c243", "packages": [ { "name": "guzzlehttp/guzzle", @@ -10925,7 +10925,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^8.3" + "php": "^8.4" }, "platform-dev": {}, "plugin-api-version": "2.9.0" From 034f1e9a965ace580da6ebbe6bc9d53349af1610 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 20:59:37 +0200 Subject: [PATCH 22/30] Add #[\Override] to entity fromBag() methods --- src/Api/Entity/Creditor.php | 1 + src/Api/Entity/Debtor.php | 1 + src/Api/Entity/Domain.php | 1 + src/Api/Entity/Group.php | 1 + src/Api/Entity/GroupItem.php | 1 + src/Api/Entity/Hosting.php | 1 + src/Api/Entity/Invoice.php | 1 + src/Api/Entity/InvoiceLine.php | 1 + src/Api/Entity/Order.php | 1 + src/Api/Entity/OrderLine.php | 1 + src/Api/Entity/PriceQuote.php | 1 + src/Api/Entity/PriceQuoteLine.php | 1 + src/Api/Entity/Product.php | 1 + src/Api/Entity/Ssl.php | 1 + src/Api/Entity/Subscription.php | 1 + src/Api/Entity/Ticket.php | 1 + src/Api/Entity/TicketMessage.php | 1 + src/Api/Entity/Vps.php | 1 + 18 files changed, 18 insertions(+) diff --git a/src/Api/Entity/Creditor.php b/src/Api/Entity/Creditor.php index 141889b5c..abc811a7f 100644 --- a/src/Api/Entity/Creditor.php +++ b/src/Api/Entity/Creditor.php @@ -46,6 +46,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Debtor.php b/src/Api/Entity/Debtor.php index 968530e65..54849c06e 100644 --- a/src/Api/Entity/Debtor.php +++ b/src/Api/Entity/Debtor.php @@ -76,6 +76,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Domain.php b/src/Api/Entity/Domain.php index 765923bba..bef8b2b4c 100644 --- a/src/Api/Entity/Domain.php +++ b/src/Api/Entity/Domain.php @@ -43,6 +43,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Group.php b/src/Api/Entity/Group.php index 0a29997ce..4e30aae0d 100644 --- a/src/Api/Entity/Group.php +++ b/src/Api/Entity/Group.php @@ -20,6 +20,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { $items = []; diff --git a/src/Api/Entity/GroupItem.php b/src/Api/Entity/GroupItem.php index adc4d278f..ef085a139 100644 --- a/src/Api/Entity/GroupItem.php +++ b/src/Api/Entity/GroupItem.php @@ -15,6 +15,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Hosting.php b/src/Api/Entity/Hosting.php index bedbae13d..1cf8f1544 100644 --- a/src/Api/Entity/Hosting.php +++ b/src/Api/Entity/Hosting.php @@ -32,6 +32,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Invoice.php b/src/Api/Entity/Invoice.php index 2337100e9..6484d1de7 100644 --- a/src/Api/Entity/Invoice.php +++ b/src/Api/Entity/Invoice.php @@ -76,6 +76,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { $lines = []; diff --git a/src/Api/Entity/InvoiceLine.php b/src/Api/Entity/InvoiceLine.php index 27f7a56fd..24c8fe41f 100644 --- a/src/Api/Entity/InvoiceLine.php +++ b/src/Api/Entity/InvoiceLine.php @@ -36,6 +36,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Order.php b/src/Api/Entity/Order.php index 7d7591151..2469649f1 100644 --- a/src/Api/Entity/Order.php +++ b/src/Api/Entity/Order.php @@ -58,6 +58,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { $lines = []; diff --git a/src/Api/Entity/OrderLine.php b/src/Api/Entity/OrderLine.php index c1f2ea7c7..81bac119f 100644 --- a/src/Api/Entity/OrderLine.php +++ b/src/Api/Entity/OrderLine.php @@ -32,6 +32,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/PriceQuote.php b/src/Api/Entity/PriceQuote.php index 85da7ee16..de5495fe3 100644 --- a/src/Api/Entity/PriceQuote.php +++ b/src/Api/Entity/PriceQuote.php @@ -64,6 +64,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { $lines = []; diff --git a/src/Api/Entity/PriceQuoteLine.php b/src/Api/Entity/PriceQuoteLine.php index dcdc85991..a1be4a75b 100644 --- a/src/Api/Entity/PriceQuoteLine.php +++ b/src/Api/Entity/PriceQuoteLine.php @@ -32,6 +32,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Product.php b/src/Api/Entity/Product.php index 10e9a715d..6c9d64cc4 100644 --- a/src/Api/Entity/Product.php +++ b/src/Api/Entity/Product.php @@ -36,6 +36,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Ssl.php b/src/Api/Entity/Ssl.php index c50b6acad..334ded360 100644 --- a/src/Api/Entity/Ssl.php +++ b/src/Api/Entity/Ssl.php @@ -40,6 +40,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Subscription.php b/src/Api/Entity/Subscription.php index 30932b61d..797eb9060 100644 --- a/src/Api/Entity/Subscription.php +++ b/src/Api/Entity/Subscription.php @@ -35,6 +35,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Ticket.php b/src/Api/Entity/Ticket.php index 3576d6b18..bdc6668d2 100644 --- a/src/Api/Entity/Ticket.php +++ b/src/Api/Entity/Ticket.php @@ -37,6 +37,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { $messages = []; diff --git a/src/Api/Entity/TicketMessage.php b/src/Api/Entity/TicketMessage.php index e31e8609b..3d6fc359c 100644 --- a/src/Api/Entity/TicketMessage.php +++ b/src/Api/Entity/TicketMessage.php @@ -23,6 +23,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( diff --git a/src/Api/Entity/Vps.php b/src/Api/Entity/Vps.php index 5627b3095..e90376dec 100644 --- a/src/Api/Entity/Vps.php +++ b/src/Api/Entity/Vps.php @@ -36,6 +36,7 @@ public function __construct( parent::__construct($bag); } + #[\Override] public static function fromBag(DataBag $bag): static { return new self( From d415cfe3960cb25ad30e45690875ab912533baf2 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 20:59:40 +0200 Subject: [PATCH 23/30] Raise PHPMD cyclomatic complexity threshold to 10 --- cyclomatic.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cyclomatic.xml b/cyclomatic.xml index 97bcc338e..722a1509d 100644 --- a/cyclomatic.xml +++ b/cyclomatic.xml @@ -14,7 +14,7 @@ 1 - + From 64a6363c515e9391655a39a18c90f2d72d75df64 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 21:59:05 +0200 Subject: [PATCH 24/30] Bump hyperized/value-objects to ^2.0.0 --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index ad4683a4f..e8d887caf 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": "^8.4", "guzzlehttp/guzzle": "^7.5", - "hyperized/value-objects": "^1.0.0", + "hyperized/value-objects": "^2.0.0", "thecodingmachine/safe": "^3.4" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 0981b0c34..33b49bc2d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "937ab82915766938d92622e0bb94c243", + "content-hash": "c758ccca6c723305c1d865082929cca6", "packages": [ { "name": "guzzlehttp/guzzle", @@ -334,20 +334,20 @@ }, { "name": "hyperized/value-objects", - "version": "v1.1.0", + "version": "v2.0.0", "source": { "type": "git", "url": "https://github.com/hyperized/value-objects.git", - "reference": "1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c" + "reference": "226db89b16795834c670f0d61566bc3b4e542f59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hyperized/value-objects/zipball/1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c", - "reference": "1c8897f5f31fc1d2d0a59fb9dde22678dc5dd17c", + "url": "https://api.github.com/repos/hyperized/value-objects/zipball/226db89b16795834c670f0d61566bc3b4e542f59", + "reference": "226db89b16795834c670f0d61566bc3b4e542f59", "shasum": "" }, "require": { - "php": "^8.3" + "php": "^8.4" }, "require-dev": { "infection/infection": "^0.32.6", @@ -373,9 +373,9 @@ "description": "A basic value objects collection", "support": { "issues": "https://github.com/hyperized/value-objects/issues", - "source": "https://github.com/hyperized/value-objects/tree/v1.1.0" + "source": "https://github.com/hyperized/value-objects/tree/v2.0.0" }, - "time": "2026-04-11T11:42:56+00:00" + "time": "2026-04-11T19:54:01+00:00" }, { "name": "psr/http-client", From de05b76a2f998476a8d4904caf309dc7af12b667 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:00:35 +0200 Subject: [PATCH 25/30] Remove thecodingmachine/safe, use native JSON_THROW_ON_ERROR --- composer.json | 3 +- composer.lock | 288 ++++++++++++++++++++++++------------------------ src/Api/Api.php | 8 +- 3 files changed, 150 insertions(+), 149 deletions(-) diff --git a/composer.json b/composer.json index e8d887caf..66cfc9456 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,7 @@ "require": { "php": "^8.4", "guzzlehttp/guzzle": "^7.5", - "hyperized/value-objects": "^2.0.0", - "thecodingmachine/safe": "^3.4" + "hyperized/value-objects": "^2.0.0" }, "require-dev": { "phpunit/phpunit": "^13.0", diff --git a/composer.lock b/composer.lock index 33b49bc2d..26fdc97be 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c758ccca6c723305c1d865082929cca6", + "content-hash": "98c9e24314f0c590a9ba4d3055ba7d91", "packages": [ { "name": "guzzlehttp/guzzle", @@ -647,149 +647,6 @@ } ], "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "thecodingmachine/safe", - "version": "v3.4.0", - "source": { - "type": "git", - "url": "https://github.com/thecodingmachine/safe.git", - "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/705683a25bacf0d4860c7dea4d7947bfd09eea19", - "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.4", - "phpstan/phpstan": "^2", - "phpunit/phpunit": "^10", - "squizlabs/php_codesniffer": "^3.2" - }, - "type": "library", - "autoload": { - "files": [ - "lib/special_cases.php", - "generated/apache.php", - "generated/apcu.php", - "generated/array.php", - "generated/bzip2.php", - "generated/calendar.php", - "generated/classobj.php", - "generated/com.php", - "generated/cubrid.php", - "generated/curl.php", - "generated/datetime.php", - "generated/dir.php", - "generated/eio.php", - "generated/errorfunc.php", - "generated/exec.php", - "generated/fileinfo.php", - "generated/filesystem.php", - "generated/filter.php", - "generated/fpm.php", - "generated/ftp.php", - "generated/funchand.php", - "generated/gettext.php", - "generated/gmp.php", - "generated/gnupg.php", - "generated/hash.php", - "generated/ibase.php", - "generated/ibmDb2.php", - "generated/iconv.php", - "generated/image.php", - "generated/imap.php", - "generated/info.php", - "generated/inotify.php", - "generated/json.php", - "generated/ldap.php", - "generated/libxml.php", - "generated/lzf.php", - "generated/mailparse.php", - "generated/mbstring.php", - "generated/misc.php", - "generated/mysql.php", - "generated/mysqli.php", - "generated/network.php", - "generated/oci8.php", - "generated/opcache.php", - "generated/openssl.php", - "generated/outcontrol.php", - "generated/pcntl.php", - "generated/pcre.php", - "generated/pgsql.php", - "generated/posix.php", - "generated/ps.php", - "generated/pspell.php", - "generated/readline.php", - "generated/rnp.php", - "generated/rpminfo.php", - "generated/rrd.php", - "generated/sem.php", - "generated/session.php", - "generated/shmop.php", - "generated/sockets.php", - "generated/sodium.php", - "generated/solr.php", - "generated/spl.php", - "generated/sqlsrv.php", - "generated/ssdeep.php", - "generated/ssh2.php", - "generated/stream.php", - "generated/strings.php", - "generated/swoole.php", - "generated/uodbc.php", - "generated/uopz.php", - "generated/url.php", - "generated/var.php", - "generated/xdiff.php", - "generated/xml.php", - "generated/xmlrpc.php", - "generated/yaml.php", - "generated/yaz.php", - "generated/zip.php", - "generated/zlib.php" - ], - "classmap": [ - "lib/DateTime.php", - "lib/DateTimeImmutable.php", - "lib/Exceptions/", - "generated/Exceptions/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHP core functions that throw exceptions instead of returning FALSE on error", - "support": { - "issues": "https://github.com/thecodingmachine/safe/issues", - "source": "https://github.com/thecodingmachine/safe/tree/v3.4.0" - }, - "funding": [ - { - "url": "https://github.com/OskarStark", - "type": "github" - }, - { - "url": "https://github.com/shish", - "type": "github" - }, - { - "url": "https://github.com/silasjoisten", - "type": "github" - }, - { - "url": "https://github.com/staabm", - "type": "github" - } - ], - "time": "2026-02-04T18:08:13+00:00" } ], "packages-dev": [ @@ -10593,6 +10450,149 @@ ], "time": "2026-03-30T15:14:47+00:00" }, + { + "name": "thecodingmachine/safe", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/safe.git", + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/705683a25bacf0d4860c7dea4d7947bfd09eea19", + "reference": "705683a25bacf0d4860c7dea4d7947bfd09eea19", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10", + "squizlabs/php_codesniffer": "^3.2" + }, + "type": "library", + "autoload": { + "files": [ + "lib/special_cases.php", + "generated/apache.php", + "generated/apcu.php", + "generated/array.php", + "generated/bzip2.php", + "generated/calendar.php", + "generated/classobj.php", + "generated/com.php", + "generated/cubrid.php", + "generated/curl.php", + "generated/datetime.php", + "generated/dir.php", + "generated/eio.php", + "generated/errorfunc.php", + "generated/exec.php", + "generated/fileinfo.php", + "generated/filesystem.php", + "generated/filter.php", + "generated/fpm.php", + "generated/ftp.php", + "generated/funchand.php", + "generated/gettext.php", + "generated/gmp.php", + "generated/gnupg.php", + "generated/hash.php", + "generated/ibase.php", + "generated/ibmDb2.php", + "generated/iconv.php", + "generated/image.php", + "generated/imap.php", + "generated/info.php", + "generated/inotify.php", + "generated/json.php", + "generated/ldap.php", + "generated/libxml.php", + "generated/lzf.php", + "generated/mailparse.php", + "generated/mbstring.php", + "generated/misc.php", + "generated/mysql.php", + "generated/mysqli.php", + "generated/network.php", + "generated/oci8.php", + "generated/opcache.php", + "generated/openssl.php", + "generated/outcontrol.php", + "generated/pcntl.php", + "generated/pcre.php", + "generated/pgsql.php", + "generated/posix.php", + "generated/ps.php", + "generated/pspell.php", + "generated/readline.php", + "generated/rnp.php", + "generated/rpminfo.php", + "generated/rrd.php", + "generated/sem.php", + "generated/session.php", + "generated/shmop.php", + "generated/sockets.php", + "generated/sodium.php", + "generated/solr.php", + "generated/spl.php", + "generated/sqlsrv.php", + "generated/ssdeep.php", + "generated/ssh2.php", + "generated/stream.php", + "generated/strings.php", + "generated/swoole.php", + "generated/uodbc.php", + "generated/uopz.php", + "generated/url.php", + "generated/var.php", + "generated/xdiff.php", + "generated/xml.php", + "generated/xmlrpc.php", + "generated/yaml.php", + "generated/yaz.php", + "generated/zip.php", + "generated/zlib.php" + ], + "classmap": [ + "lib/DateTime.php", + "lib/DateTimeImmutable.php", + "lib/Exceptions/", + "generated/Exceptions/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP core functions that throw exceptions instead of returning FALSE on error", + "support": { + "issues": "https://github.com/thecodingmachine/safe/issues", + "source": "https://github.com/thecodingmachine/safe/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://github.com/OskarStark", + "type": "github" + }, + { + "url": "https://github.com/shish", + "type": "github" + }, + { + "url": "https://github.com/silasjoisten", + "type": "github" + }, + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2026-02-04T18:08:13+00:00" + }, { "name": "theseer/tokenizer", "version": "2.0.1", diff --git a/src/Api/Api.php b/src/Api/Api.php index 06e214798..df48d1cd2 100644 --- a/src/Api/Api.php +++ b/src/Api/Api.php @@ -16,7 +16,7 @@ use Hyperized\Hostfact\Types\FormParameter; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Safe\Exceptions\JsonException; +use JsonException; abstract class Api implements ApiInterface { @@ -77,7 +77,7 @@ public function sendRequest(string $controller, string $action, array $input): A /** * @var array $result */ - $result = \Safe\json_decode( + $result = json_decode( static::getResponseBody( static::getResponse( $this->getHttpClient(), @@ -87,7 +87,9 @@ public function sendRequest(string $controller, string $action, array $input): A $action ) ), - true + true, + 512, + JSON_THROW_ON_ERROR, ); } catch (JsonException $exception) { return new ErrorResponse( From 3c9f0461a4641a0e35b822a90d6483b78ab99c51 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:11:50 +0200 Subject: [PATCH 26/30] Preserve controller/action in JSON parse error responses --- src/Api/Api.php | 11 +++++------ tests/Feature/ApiIntegrationTest.php | 6 +++--- tests/Unit/ApiTest.php | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Api/Api.php b/src/Api/Api.php index df48d1cd2..272b79b35 100644 --- a/src/Api/Api.php +++ b/src/Api/Api.php @@ -78,7 +78,7 @@ public function sendRequest(string $controller, string $action, array $input): A * @var array $result */ $result = json_decode( - static::getResponseBody( + json: static::getResponseBody( static::getResponse( $this->getHttpClient(), static::getRequest(), @@ -87,14 +87,13 @@ public function sendRequest(string $controller, string $action, array $input): A $action ) ), - true, - 512, - JSON_THROW_ON_ERROR, + associative: true, + flags: JSON_THROW_ON_ERROR, ); } catch (JsonException $exception) { return new ErrorResponse( - 'invalid', - 'invalid', + $controller, + $action, Status::Error, new \DateTimeImmutable(), [$exception->getMessage()], diff --git a/tests/Feature/ApiIntegrationTest.php b/tests/Feature/ApiIntegrationTest.php index cce0253ec..9f259314a 100644 --- a/tests/Feature/ApiIntegrationTest.php +++ b/tests/Feature/ApiIntegrationTest.php @@ -210,8 +210,8 @@ public function testInvalidJsonResponseReturnsErrorResponse(): void self::assertInstanceOf(ErrorResponse::class, $result); self::assertTrue($result->isError()); - self::assertSame('invalid', $result->controller); - self::assertSame('invalid', $result->action); + self::assertSame('product', $result->controller); + self::assertSame('list', $result->action); self::assertNotEmpty($result->errors); } @@ -232,7 +232,7 @@ public function testConnectionFailureThrowsException(): void $product = Product::fromHttpClient($stubClient); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('cURL error 7'); + $this->expectExceptionMessage('API call failed'); $product->list([]); } diff --git a/tests/Unit/ApiTest.php b/tests/Unit/ApiTest.php index 15e8caa9b..1c0be2420 100644 --- a/tests/Unit/ApiTest.php +++ b/tests/Unit/ApiTest.php @@ -67,8 +67,8 @@ public function testSendRequestHandlesInvalidJsonResponse(): void $result = $controller->list(); self::assertInstanceOf(ErrorResponse::class, $result); - self::assertSame('invalid', $result->controller); - self::assertSame('invalid', $result->action); + self::assertSame('product', $result->controller); + self::assertSame('list', $result->action); self::assertSame(Status::Error, $result->status); self::assertNotEmpty($result->errors); self::assertIsString($result->errors[0]); @@ -118,7 +118,7 @@ public function testSendRequestWrapsGuzzleException(): void $controller = Product::fromHttpClient($stubClient); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('Connection refused'); + $this->expectExceptionMessage('API call failed'); $controller->show(['Identifier' => '1']); } From 11860102390c767cca5e8bb02d804014cde8570a Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:11:54 +0200 Subject: [PATCH 27/30] Use ReflectionNamedType for enum backing type check --- src/Api/Entity/Entity.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Api/Entity/Entity.php b/src/Api/Entity/Entity.php index 41a343cdc..0825b2ed8 100644 --- a/src/Api/Entity/Entity.php +++ b/src/Api/Entity/Entity.php @@ -30,7 +30,7 @@ protected static function nullableEnum(DataBag $bag, string $key, string $enumCl $backing = (new \ReflectionEnum($enumClass))->getBackingType(); - if ($backing !== null && (string) $backing === 'int') { + if ($backing instanceof \ReflectionNamedType && $backing->getName() === 'int') { return $enumClass::tryFrom((int) $value); } From b65fab1b31cd8771d22b2c4446958367dd799f07 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:11:56 +0200 Subject: [PATCH 28/30] Prevent credential leaks in exception messages --- src/Exceptions/InvalidArgumentException.php | 2 +- tests/Unit/InvalidArgumentExceptionTest.php | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Exceptions/InvalidArgumentException.php b/src/Exceptions/InvalidArgumentException.php index c0526954b..0cf790e32 100644 --- a/src/Exceptions/InvalidArgumentException.php +++ b/src/Exceptions/InvalidArgumentException.php @@ -8,7 +8,7 @@ class InvalidArgumentException extends \InvalidArgumentException { public static function apiFailed(GuzzleException $exception): InvalidArgumentException { - return new self('API call returned an invalid response: ' . $exception->getMessage() . '.'); + return new self('API call failed: ' . $exception->getCode(), previous: $exception); } public static function configVariableNotAString(): InvalidArgumentException diff --git a/tests/Unit/InvalidArgumentExceptionTest.php b/tests/Unit/InvalidArgumentExceptionTest.php index 769763c3d..a390a268c 100644 --- a/tests/Unit/InvalidArgumentExceptionTest.php +++ b/tests/Unit/InvalidArgumentExceptionTest.php @@ -18,24 +18,21 @@ public function testApiFailedMessageFormat(): void $exception = InvalidArgumentException::apiFailed($guzzleException); - self::assertSame( - 'API call returned an invalid response: Connection refused.', - $exception->getMessage() - ); + self::assertSame('API call failed: 0', $exception->getMessage()); + self::assertSame($guzzleException, $exception->getPrevious()); } - public function testApiFailedPreservesExceptionMessage(): void + public function testApiFailedDoesNotExposeRequestDetails(): void { $guzzleException = new RequestException( - 'Timeout exceeded', - new Request('POST', 'https://example.com') + 'Error with https://secret.example.com/api?key=abc123', + new Request('POST', 'https://secret.example.com/api?key=abc123') ); $exception = InvalidArgumentException::apiFailed($guzzleException); - self::assertStringStartsWith('API call returned an invalid response: ', $exception->getMessage()); - self::assertStringEndsWith('.', $exception->getMessage()); - self::assertStringContainsString('Timeout exceeded', $exception->getMessage()); + self::assertStringNotContainsString('secret.example.com', $exception->getMessage()); + self::assertStringNotContainsString('abc123', $exception->getMessage()); } public function testConfigVariableNotAString(): void From 70d2293cab7f0f9e7e4021744ec6c836a2375aed Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:12:00 +0200 Subject: [PATCH 29/30] Fix dependabot typo in mergify config --- .mergify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index 57ec8225a..51229eeb1 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -7,7 +7,7 @@ pull_request_rules: type: APPROVE message: Automatically approving dependabot - - name: automatic merge on depenabot pull requests + - name: automatic merge on dependabot pull requests conditions: - author=dependabot[bot] - check-success~=^test* From 16020af064658cf4a8208a785b58b6b23ed6c829 Mon Sep 17 00:00:00 2001 From: Gerben Geijteman Date: Sat, 11 Apr 2026 22:21:35 +0200 Subject: [PATCH 30/30] Remove phpcbf from CI, bump phpcs minimum to 3.8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHPCBF is a fixer, not a validator — it returns exit code 1 when it fixes code, causing CI failures. PHPCS already validates style. Bump phpcs minimum to 3.8 for readonly class support. --- composer.json | 5 +---- composer.lock | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 66cfc9456..3b8e1a609 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "phpmd/phpmd": "^2.14", "orchestra/testbench": "^11.0", "phpstan/phpstan": "^2.0", - "squizlabs/php_codesniffer": "^3.7 || ^4.0", + "squizlabs/php_codesniffer": "^3.8 || ^4.0", "povils/phpmnd": "^3.0", "infection/infection": "^0.32" }, @@ -55,8 +55,6 @@ "@phpmd --strict src text cyclomatic.xml", "@phpstan --version", "@phpstan analyse", - "@phpcbf --version", - "@phpcbf src", "@phpcs --version", "@phpcs src --standard=PSR2", "@phpmnd --version", @@ -73,7 +71,6 @@ "phpmd": "vendor/bin/phpmd", "phpstan": "vendor/bin/phpstan", "phpcs": "vendor/bin/phpcs", - "phpcbf": "vendor/bin/phpcbf", "phpmnd": "vendor/bin/phpmnd src", "infection": "vendor/bin/infection", "major": [ diff --git a/composer.lock b/composer.lock index 26fdc97be..bfbaa5227 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "98c9e24314f0c590a9ba4d3055ba7d91", + "content-hash": "0e55a970b7f588f60e3f4bb86603d87f", "packages": [ { "name": "guzzlehttp/guzzle",