diff --git a/.env.example b/.env.example deleted file mode 100644 index a582da8..0000000 --- a/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -TERMII_API_KEY="" -TERMII_SENDER_ID="" -TEST_PHONE_NUMBER="+1234567890" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..464d013 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Ensure all text files use LF line endings +* text eol=lf + +# Specific file types +*.php text eol=lf +*.json text eol=lf +*.md text eol=lf diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..6d304f5 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [Douglasokolaa] diff --git a/.github/workflows/php-cs.yml b/.github/workflows/php-cs.yml new file mode 100644 index 0000000..095a68f --- /dev/null +++ b/.github/workflows/php-cs.yml @@ -0,0 +1,27 @@ +name: php-cs + +on: + push: + paths: + - '**.php' + pull_request: + branches: [ "master", "develop" ] + +jobs: + php-cs-lint: + name: analyze + runs-on: ubuntu-latest + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + tools: none + + - uses: actions/checkout@v4 + + - name: Install composer dependencies + run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist + + - name: Lint + run: ./vendor/bin/php-cs-fixer check --allow-risky=yes diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..4d18afb --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,29 @@ +name: PHPStan + +on: + push: + paths: + - '**.php' + - 'phpstan.neon.dist' + - '.github/workflows/phpstan.yml' + pull_request: + branches: [ "master", "develop" ] + +jobs: + phpstan: + name: analyze + runs-on: ubuntu-latest + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + tools: none + + - uses: actions/checkout@v4 + + - name: Install composer dependencies + run: composer install -q --no-ansi --no-interaction --no-progress --prefer-dist + + - name: Run PHPStan + run: ./vendor/bin/phpstan analyze --error-format=github diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..cc4039c --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,36 @@ +name: Run Tests + +on: + push: + paths: + - '**.php' + - 'composer.json' + - 'composer.lock' + - 'phpunit.xml' + pull_request: + branches: [ "master", "develop" ] + +jobs: + pest: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ 'ubuntu-latest', 'windows-latest', 'macos-latest' ] + php-versions: [ '8.2', '8.3', '8.4' ] + phpunit-versions: [ 'latest' ] + steps: + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl + ini-values: post_max_size=256M, max_execution_time=180 + coverage: xdebug + tools: php-cs-fixer, phpunit:${{ matrix.phpunit-versions }} + + - uses: actions/checkout@v3 + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist + + - name: run tests + run: ./vendor/bin/pest \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..09cc2e8 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,57 @@ +in(__DIR__ . '/src') + ->in(__DIR__ . '/tests'); + +return (new Config()) + ->setRules([ + '@PSR12' => true, + 'strict_param' => true, + 'array_syntax' => ['syntax' => 'short'], + 'no_trailing_comma_in_singleline_array' => true, + 'trim_array_spaces' => true, + 'single_quote' => true, + 'blank_line_after_namespace' => true, + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + 'class_attributes_separation' => [ + 'elements' => [ + 'method' => 'one', + 'property' => 'one', + ], + ], + 'function_declaration' => ['closure_function_spacing' => 'none'], + 'method_argument_space' => [ + 'on_multiline' => 'ensure_fully_multiline', + ], + 'visibility_required' => ['elements' => ['property', 'method', 'const']], + + 'binary_operator_spaces' => ['default' => 'align_single_space_minimal'], + 'cast_spaces' => ['space' => 'single'], + 'concat_space' => ['spacing' => 'one'], + + 'control_structure_continuation_position' => ['position' => 'same_line'], + 'curly_braces_position' => [ + 'control_structures_opening_brace' => 'same_line', + 'functions_opening_brace' => 'next_line_unless_newline_at_signature_end', + 'classes_opening_brace' => 'next_line_unless_newline_at_signature_end', + ], + + 'phpdoc_align' => ['align' => 'vertical'], + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'declare_strict_types' => false, + 'no_blank_lines_after_phpdoc' => true, + 'no_extra_blank_lines' => ['tokens' => ['curly_brace_block', 'extra']], + 'no_trailing_whitespace' => true, + 'no_whitespace_in_blank_line' => true, + 'semicolon_after_instruction' => true, + ]) + ->setFinder($finder) + ->setIndent(" ") + ->setLineEnding("\n"); diff --git a/README.md b/README.md index df87ce3..44ecc5b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Termii PHP

+

Termii PHP SDK

Github top language @@ -27,115 +27,367 @@ ## :dart: About ## -PHP Library for [Termii API](http://developer.termii.com/docs/) +Termii PHP SDK is a robust library designed to facilitate seamless integration with +the [Termii API](http://developer.termii.com/docs/). +It enables developers to efficiently send SMS messages, manage sender IDs, +handle campaigns, and verify tokens within PHP applications. ## :white_check_mark: Requirements ## -Before starting :checkered_flag:, you need to have [Git](https://git-scm.com) and [PHP 7+](https://php.net/) installed. +1. To use Termii's APIs, you need to first create an account for free at [termii.com](https://termii.com/). +2. BASE URL: Your Termii account has its own base URL, which you should use in all API requests. + Your base URL can be found on your dashboard. -## :checkered_flag: Usage ## +3. Ensure that PHP 8.1 [PHP 8.1+](https://php.net/) or higher is installed on your system. + +## :hammer: Installation ## ```bash # Installation -$ composer require okolaa/termiiphp +composer require okolaa/termiiphp +``` + +## :checkered_flag: Usage ## + +### TLDR; + +> * Your API Token can be found in your Termii account settings https://app.termii.com/account/api + +```php + + use Okolaa\TermiiPHP\Endpoints\Messaging\GetSenderIdsEndpoint; + use Okolaa\TermiiPHP\Termii; + + // Initialize the SDK + $termii = Termii::initialize('api-token', 'https://termi-base-url'); + + // make a request + $response = $termii->senderIdApi()->getIds(page: 1); + + // get result as array + $response->json(); + + // Alternatively, convert result to DTO + $request = new GetSenderIdsEndpoint(); + $senderIds = $request->createDtoFromResponse($response); + // you can now interact with data e.g. + $senderIds->currentPage; // int + $senderIds->currentPage; // int + $senderIds->lastPage; // int + $senderIds->total; //int + $senderIds->data; //array + +``` + +### Switch API + +Termii’s Messaging allows you to send messages to any country in the world across SMS and WhatsApp channel through a +REST API. Every request made is identified by a unique ID that help our users track the status of their message either +by receiving Delivery Reports (DLRs) over their set webhook endpoints or polling the status of the message using a +specific endpoint. +#### Messaging + +### Send Message + +```php +use Okolaa\TermiiPHP\Data\Message; +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); +$message = new Message( + to: "23490555546", + from: "talert", + sms: "Hi There, Testing Termii", + type: "plain", + channel:\Okolaa\TermiiPHP\Enums\MessageChannel::DND, + media: null, + time_to_live: 0 +); +$response = $termii->messagingApi()->send($message); +``` + +### Send Bulk Message + +```php +$bulkMessage = new Message( + to: ["2347012345678", "2349067890123"], + from: "bulkAlert", + sms: "Bulk message content, Testing Termii", + type: "plain", + channel: \Okolaa\TermiiPHP\Enums\MessageChannel::DND, + media: null, + time_to_live: 1 // Example TTL in minutes +); +$response = $termii->messagingApi()->sendBulk($bulkMessage); ``` -#Usage -- Send sms +### Send Device Template + ```php -$termii = new Termii('TERMII_SENDER_ID', 'TERMII_API_KEY'); +$deviceTemplate = new \Okolaa\TermiiPHP\Data\DeviceTemplate( + template_id: "sampleTemplate1234", + phone_number: "2348076543210", + device_key: "ABCD1234DEVICEKEY" +); +$response = $termii->messagingApi()->sendDeviceTemplate($deviceTemplate); +``` -$sent = $termii->sendMessage( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - "message" => "Unit Test Message" - ] +### Sender ID + +```php +$response = $termii->senderIdApi()->getIds($pageNumber); +$senderId = new \Okolaa\TermiiPHP\Data\SenderId(...); +$senderId = new \Okolaa\TermiiPHP\Data\SenderId( + name: "TestSender", + company: "TestCompany Ltd", + purpose: "Testing purposes for SDK" ); ``` -- SendToken +### Campaigns + ```php -$termii = new Termii('TERMII_SENDER_ID', 'TERMII_API_KEY'); +$campaign = new \Okolaa\TermiiPHP\Data\Campaign( + name: "Test Campaign", + message: "This is a test campaign message", + sender_id: "TestSenderId", + recipients: ["2347012345678", "2349067890123"], + channel: "sms", + time_to_send: "2023-12-01 10:00:00" +); +$response = $termii->campaignApi()->send($campaign); +$response = $termii->campaignApi()->get($campaingId, $pageNumber); +$response = $termii->campaignApi()->getHistory($pageNumber); +``` -//Set Options -$termii->setMaxAttempts(2); - ->setPinTimeToLive(5); - ->SetPinLength(4); - ->setPinType("NUMERIC"); - ->setMaxAttempts(1); +### Phonebook -$sent = $termii->sendToken( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - "message" => "Your pin is < _pin_ >" - ] +```php +$phonebook = new \Okolaa\TermiiPHP\Data\Phonebook( + name: "Test Phonebook", + description: "Sample description for test phonebook" ); +$responseCreate = $termii->campaignApi()->phoneBook()->create($phonebook); +$responseUpdate = $termii->campaignApi()->phoneBook()->update($phonebook); +$response = $termii->campaignApi()->phoneBook()->get(); +$response = $termii->campaignApi()->phoneBook()->delete($phonebook->id); ``` -- verifyToken +### Contact + ```php -$termii = new Termii('TERMII_SENDER_ID', 'TERMII_API_KEY'); -$response = $termii->verifyToken( - [ - "pin_id" => "f862cb33-9dd3-42b3-b705-18200c0e800f", - "pin" => "1234", - ] +$contact = new \Okolaa\TermiiPHP\Data\Contact( + phone_number: "2347012345678", + first_name: "John", + last_name: "Doe", + email: "johndoe@example.com", + phonebook_id: "testPhonebook123" ); +$responseAddContact = $termii->campaignApi()->phoneBook()->addContact($contact); +$importedContactsResponse = $termii->campaignApi()->phoneBook()->importContact($phonebook->id, 234, 'path/to/your/file.csv'); + +$fetchedContactsResponse = $termii->campaignApi()->phoneBook()->getContacts($phonebook->id, $pageNumber); +$deleteContactResponse = $termii->campaignApi()->phoneBook()->deleteContact($contact->id); ``` -- InApp Token +## Token API + +The `TokenApi` in the Termii PHP SDK enables businesses to **generate**, **send**, and **verify One-Time Passwords ( +OTPs)**. +It's a powerful feature tailored for two-factor authentication and secure user verification processes. + +### Send Token + ```php -$termii = new Termii('TERMII_SENDER_ID', 'TERMII_API_KEY'); -$response = $termii->InAppToken( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - ] +use Okolaa\TermiiPHP\Data\TokenSend; +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); + +$tokenSend = new \Okolaa\TermiiPHP\Data\Token\SendToken( + to: "23490555546", + from: "talert", + messageText: "Your verification code is <%pin%>", + pinType: \Okolaa\TermiiPHP\Enums\PinType::AlphaNumeric, + pinAttempts: 3, + pinTimeToLiveMinute: 5, + pinLength: 6, + pinPlaceHolder: "<%pin%>", + channel: \Okolaa\TermiiPHP\Enums\MessageChannel::DND + messageType: 'plain', ); + +$response = $termii->tokenApi()->send($tokenSend); ``` -- Available Methods +### Voice Token + +The voice token API enables you to generate and trigger one-time passwords (OTP) through the voice channel to a phone +number. + ```php -$termii = new Termii('TERMII_SENDER_ID', 'TERMII_API_KEY'); +use Okolaa\TermiiPHP\Data\Token\VoiceToken; +use Okolaa\TermiiPHP\Termii; -$termii->sendMessage(); -$termii->sendToken(); -$termii->verifyToken(); -$termii->InAppToken(); -$termii->sendWithAutoGeneratedNumber(); -$termii->getSenderIds(); -$termii->getResponse(); -$termii->setMaxAttempts(); -$termii->setPinTimeToLive(); -$termii->setPinType(); -$termii->setChannel(); -$termii->SetPinPlaceholder(); -$termii->setMessageType(); -$termii->setTokenMessageType(); -$termii->SetPinLength(); -$termii->setSender(); -$termii->setAPIKey(); -$termii->getSenderIds(); -$termii->getBallance(); -$termii->search(); +$termii = Termii::initialize('api-token'); + +$voiceToken = new VoiceToken( + phoneNumber: "2348000000000", + pin_length: 6 +); + +$response = $termii->tokenApi()->voice($voiceToken); ``` +### Voice Call Token -## :hammer: Countribution +The voice call API enables you to send messages from your application through our voice channel to a phone number. -```bash +```php +use Okolaa\TermiiPHP\Data\Token\VoiceToken; +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); + +$response = $termii->tokenApi()->voiceCall('2348000000000', '12345); +``` + +### Verify Token + +Verify token API, checks tokens sent to customers and returns a response confirming the status of the token. + +```php +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); + +$response = $termii->tokenApi()->verify('pinId', 'the-pin-code'); +``` + +### Email Token + +The email token API enables you to send one-time-passwords from your application through our email channel to an email +address. + +```php +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); + +$response = $termii->tokenApi()->email('test@test.com', 'the-pin-code', 'email-config-id'); +``` + +### In-App Token + +This API returns OTP codes in JSON format which can be used within any web or mobile app. + +```php +use Okolaa\TermiiPHP\Termii; + +$termii = Termii::initialize('api-token'); + +$payload = new \Okolaa\TermiiPHP\Data\Token\InAppToken( + pinType: \Okolaa\TermiiPHP\Enums\PinType::Numeric, + phoneNumber: '2348000000000' + ); + +$response = $termii->tokenApi()->inApp($payload); +``` + +## Advanced Configuration + +- Customizing Requests + +```php +use Okolaa\TermiiPHP\Endpoints\Messaging\RequestSenderIdEndpoint; +use Okolaa\TermiiPHP\Termii; + +$senderIdData = new \Okolaa\TermiiPHP\Data\SenderId( + 'okolaa', + 'Okolaa INC', + 'To be used for sending alerts to customers.' +); +$request = new RequestSenderIdEndpoint($senderIdData); +$request->query()->merge(['page' => 4]); +$request->headers()->merge(...); +$request->body()->merge(...); +$request->config()->merge(...); + +$client = Termii::initialize('api-token'); +$response = $client->send($request); + +``` + +- The Response Class + +```php +use Okolaa\TermiiPHP\Termii; +$termii = Termii::initialize('api-token'); +$response = $termii->send($request); + +$response->json(); // returns array/scalar value +$response->collect(); // returns Illuminate/Collection or scalar value +$response->object(); // returns php object +$response->dto(); // returns Data objects e.g. PaginationData, SenderId, Message, Phonebook +$response->headers(); // returns all the response headers +$response->stream(); // returns the body as a stream +``` + +## Troubleshooting +The simplest way to debug a request and response is to use the debug() +method on your connector before sending a request. +This will output an easy-to-understand array of the request and the response. +```php + use Okolaa\TermiiPHP\Termii; + $termii = Termii::initialize('api-token')); + // You can provide the die argument if you would like to terminate the application after receiving the response. + $termii->debug(die: false); +``` +You may also use debugRequest and debugResponse independently +if you would like to debug just the request or response respectively. + ```php + $termii->debugRequest(); // $connector->debugRequest(die: true); + $termii->debugResponse(); // $connector->debugResponse(die: true); + ``` + +### Common Issues +1. Invalid API Key: + Ensure you’ve set a valid API key. You can validate this by logging into the Termii Dashboard. + +2. SSL Certificate Issues: + If you encounter SSL errors in local environments, ensure your system’s CA certificates are up to date. + Alternatively, you can disable the SSL certificate verification as shown below: + ```php + $termii->config() + ->merge([ + 'verify' => false + ]); + ``` +3. Timeouts: + Increase the timeout values if the Termii API is slow to respond: + ```php + use Okolaa\TermiiPHP\Termii; + $termii = Termii::initialize('api-token')); + $termii->config()->merge( + [ + 'connect_timeout' => 60, + 'timeout' => 120 + ] + ); + ``` + +## :hammer: Contribution + +```shell # fork and Clone the fork project # Access the folder -$ cd termiiphp +cd termiiphp # Install dependencies -$ composer Install - -# Create .env and update -$ cp .ev.example .env +composer Install # Run test -$ ./vendor/phpunit/phpunit/phpunit tests - +./vendor/bin/pest ``` ## :memo: License ## @@ -146,8 +398,5 @@ Made with :heart: by   -## Todo: - -- Update Readme with Usage Back to top diff --git a/composer.json b/composer.json index 2a33970..eda8702 100644 --- a/composer.json +++ b/composer.json @@ -9,11 +9,16 @@ "api" ], "require": { - "guzzlehttp/guzzle": "^6.2 || ^7.0", - "vlucas/phpdotenv": "^5.2" + "php": "^8.2", + "saloonphp/saloon": "^3.10", + "symfony/var-dumper": "^7.2" }, "require-dev": { - "phpunit/phpunit": "^9.4" + "pestphp/pest": "^3.5", + "pestphp/pest-plugin-faker": "^3.0", + "jonpurvis/lawman": "^3.1", + "phpstan/phpstan": "^2.0", + "friendsofphp/php-cs-fixer": "^3.65" }, "autoload": { "psr-4": { @@ -37,5 +42,10 @@ "dev-master": "1.0-dev" } }, - "prefer-stable": true + "prefer-stable": true, + "config": { + "allow-plugins": { + "pestphp/pest-plugin": true + } + } } diff --git a/composer.lock b/composer.lock index 125a3e9..c01eebb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,92 +4,26 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e56186d06d973ffdf80f842ae50c4b86", + "content-hash": "86ebb25598bd9ee3cd7783375e129e81", "packages": [ - { - "name": "graham-campbell/result-type", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "7e279d2cd5d7fbb156ce46daada972355cea27bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/7e279d2cd5d7fbb156ce46daada972355cea27bb", - "reference": "7e279d2cd5d7fbb156ce46daada972355cea27bb", - "shasum": "" - }, - "require": { - "php": "^7.0|^8.0", - "phpoption/phpoption": "^1.7.3" - }, - "require-dev": { - "phpunit/phpunit": "^6.5|^7.5|^8.5|^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "graham@alt-three.com" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.1" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2020-04-13T13:17:36+00:00" - }, { "name": "guzzlehttp/guzzle", - "version": "7.4.5", + "version": "7.9.2", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -98,10 +32,11 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -111,8 +46,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "7.4-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { @@ -178,7 +114,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.5" + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" }, "funding": [ { @@ -194,33 +130,37 @@ "type": "tidelift" } ], - "time": "2022-06-20T22:16:13+00:00" + "time": "2024-07-24T11:22:20+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -257,7 +197,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.3" + "source": "https://github.com/guzzle/promises/tree/2.0.4" }, "funding": [ { @@ -273,7 +213,7 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2024-10-17T10:06:22+00:00" }, { "name": "guzzlehttp/psr7", @@ -391,75 +331,6 @@ ], "time": "2024-07-18T11:15:46+00:00" }, - { - "name": "phpoption/phpoption", - "version": "1.7.5", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/994ecccd8f3283ecf5ac33254543eb0ac946d525", - "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525", - "shasum": "" - }, - "require": { - "php": "^5.5.9 || ^7.0 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.7.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2020-07-20T17:29:33+00:00" - }, { "name": "psr/http-client", "version": "1.0.3", @@ -665,36 +536,53 @@ "time": "2019-03-08T08:55:37+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v2.5.4", + "name": "saloonphp/saloon", + "version": "v3.10.1", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" + "url": "https://github.com/saloonphp/saloon.git", + "reference": "d5bb5d6d72ed33efe19a8463ef259f0aa7e98579" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", - "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", + "url": "https://api.github.com/repos/saloonphp/saloon/zipball/d5bb5d6d72ed33efe19a8463ef259f0aa7e98579", + "reference": "d5bb5d6d72ed33efe19a8463ef259f0aa7e98579", "shasum": "" }, "require": { - "php": ">=7.1" + "guzzlehttp/guzzle": "^7.6", + "guzzlehttp/promises": "^1.5 || ^2.0", + "guzzlehttp/psr7": "^2.0", + "php": "^8.1", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "conflict": { + "sammyjo20/saloon": "*" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "illuminate/collections": "^9.39 || ^10.0", + "league/flysystem": "^3.0", + "pestphp/pest": "^2.10", + "phpstan/phpstan": "^1.11.4", + "saloonphp/xml-wrangler": "^1.1", + "spatie/ray": "^1.33", + "symfony/dom-crawler": "^6.0 || ^7.0", + "symfony/var-dumper": "^6.3 || ^7.0" + }, + "suggest": { + "illuminate/collections": "Required for the response collect() method.", + "saloonphp/xml-wrangler": "Required for the response xmlReader() method.", + "symfony/dom-crawler": "Required for the response dom() method.", + "symfony/var-dumper": "Required for default debugging drivers." }, + "type": "library", "autoload": { - "files": [ - "function.php" - ] + "psr-4": { + "Saloon\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -702,71 +590,62 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sam Carré", + "email": "29132017+Sammyjo20@users.noreply.github.com", + "role": "Developer" } ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", + "description": "Build beautiful API integrations and SDKs with Saloon", + "homepage": "https://github.com/saloonphp/saloon", + "keywords": [ + "api", + "api-integrations", + "saloon", + "sammyjo20", + "sdk" + ], "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" + "issues": "https://github.com/saloonphp/saloon/issues", + "source": "https://github.com/saloonphp/saloon/tree/v3.10.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sammyjo20", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-12-03T00:16:23+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "3.5-dev" }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ - "bootstrap.php" + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -775,24 +654,18 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -808,45 +681,45 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -872,7 +745,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -888,44 +761,50 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "name": "symfony/var-dumper", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ - "bootstrap.php" + "Resources/functions/dump.php" ], - "classmap": [ - "Resources/stubs" + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -933,10 +812,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -946,16 +821,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "debug", + "dump" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" }, "funding": [ { @@ -971,120 +844,129 @@ "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" - }, + "time": "2024-11-08T15:48:14+00:00" + } + ], + "packages-dev": [ { - "name": "vlucas/phpdotenv", - "version": "v5.3.0", + "name": "brianium/paratest", + "version": "v7.7.0", "source": { "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56" + "url": "https://github.com/paratestphp/paratest.git", + "reference": "4fb3f73bc5a4c3146bac2850af7dc72435a32daf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", - "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/4fb3f73bc5a4c3146bac2850af7dc72435a32daf", + "reference": "4fb3f73bc5a4c3146bac2850af7dc72435a32daf", "shasum": "" }, "require": { + "ext-dom": "*", "ext-pcre": "*", - "graham-campbell/result-type": "^1.0.1", - "php": "^7.1.3 || ^8.0", - "phpoption/phpoption": "^1.7.4", - "symfony/polyfill-ctype": "^1.17", - "symfony/polyfill-mbstring": "^1.17", - "symfony/polyfill-php80": "^1.17" + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.2.0", + "jean85/pretty-package-versions": "^2.1.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.5.1", + "sebastian/environment": "^7.2.0", + "symfony/console": "^6.4.14 || ^7.2.1", + "symfony/process": "^6.4.14 || ^7.2.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "ext-filter": "*", - "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5.1" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." + "doctrine/coding-standard": "^12.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^2.0.3", + "phpstan/phpstan-deprecation-rules": "^2.0.1", + "phpstan/phpstan-phpunit": "^2.0.1", + "phpstan/phpstan-strict-rules": "^2", + "squizlabs/php_codesniffer": "^3.11.1", + "symfony/filesystem": "^6.4.13 || ^7.2.0" }, + "bin": [ + "bin/paratest", + "bin/paratest_for_phpstorm" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3-dev" - } - }, "autoload": { "psr-4": { - "Dotenv\\": "src/" + "ParaTest\\": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "homepage": "https://gjcampbell.co.uk/" + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" }, { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://vancelucas.com/" + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" } ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", "keywords": [ - "dotenv", - "env", - "environment" + "concurrent", + "parallel", + "phpunit", + "testing" ], "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.3.0" + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.7.0" }, "funding": [ { - "url": "https://github.com/GrahamCampbell", + "url": "https://github.com/sponsors/Slamdunk", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" } ], - "time": "2021-01-20T15:23:13+00:00" - } - ], - "packages-dev": [ + "time": "2024-12-11T14:50:44+00:00" + }, { - "name": "doctrine/instantiator", - "version": "1.4.0", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": ">=5.3", + "react/stream": "^1.2" }, "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1093,288 +975,331 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "constructor", - "instantiate" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", + "url": "https://clue.engineering/support", "type": "custom" }, { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" + "url": "https://github.com/clue", + "type": "github" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-12-23T10:58:28+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.10.2", + "name": "composer/pcre", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.4 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.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" + ] + } + }, "autoload": { "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] + "Composer\\Pcre\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "PCRE", + "preg", + "regex", + "regular expression" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { - "name": "nikic/php-parser", - "version": "v4.12.0", + "name": "composer/semver", + "version": "3.4.3", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", - "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=7.0" + "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" } ], - "description": "A PHP parser written in PHP", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "parser", - "php" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" }, - "time": "2021-07-21T10:44:31+00:00" + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" }, { - "name": "phar-io/manifest", - "version": "2.0.3", + "name": "composer/xdebug-handler", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" }, { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "url": "https://github.com/composer", + "type": "github" }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" } ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "phar-io/version", - "version": "3.1.0", + "name": "doctrine/deprecations", + "version": "1.1.4", "source": { "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "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": { - "classmap": [ - "src/" - ] + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } + "MIT" ], - "description": "Library for handling version information and constraints", + "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/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": ">=7.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } + "require-dev": { + "phpunit/phpunit": "^9 || ^6" }, + "type": "library", "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src/" + "Evenement\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1383,58 +1308,61 @@ ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "Événement is a very simple event dispatching library for PHP", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "event-dispatcher", + "event-emitter" ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "time": "2020-06-27T09:03:43+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "name": "fakerphp/faker", + "version": "v1.24.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", "shasum": "" }, "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." }, + "type": "library", "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Faker\\": "src/Faker/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1443,51 +1371,53 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "name": "François Zaninotto" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" }, - "time": "2020-09-03T19:13:55+00:00" + "time": "2024-11-21T13:46:39+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "name": "fidry/cpu-core-counter", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "ext-tokenizer": "*" + "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", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Fidry\\CpuCoreCounter\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1496,51 +1426,63 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, - "time": "2020-09-17T18:55:26+00:00" + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" }, { - "name": "phpspec/prophecy", - "version": "1.13.0", + "name": "filp/whoops", + "version": "2.16.0", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" + "url": "https://github.com/filp/whoops.git", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", - "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", + "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", + "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0 || ^9.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", + "whoops/soap": "Formats errors as SOAP responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "2.7-dev" } }, "autoload": { "psr-4": { - "Prophecy\\": "src/Prophecy" + "Whoops\\": "src/Whoops/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1549,310 +1491,339 @@ ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" ], "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.16.0" }, - "time": "2021-03-17T13:42:18+00:00" + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2024-09-25T12:00:00+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "9.2.6", + "name": "friendsofphp/php-cs-fixer", + "version": "v3.65.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f6293e1b30a2354e8428e004689671b83871edde" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", - "reference": "f6293e1b30a2354e8428e004689671b83871edde", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/79d4f3e77b250a7d8043d76c6af8f0695e8a469f", + "reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.21 || ^10.5.38 || ^11.4.3", + "symfony/var-dumper": "^5.4.47 || ^6.4.15 || ^7.1.8", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.1.6" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.2-dev" - } + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "A tool to automatically fix PHP code style", "keywords": [ - "coverage", - "testing", - "xunit" + "Static code analysis", + "fixer", + "standards", + "static analysis" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.65.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/keradus", "type": "github" } ], - "time": "2021-03-28T07:26:59+00:00" + "time": "2024-11-25T00:39:24+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "name": "jean85/pretty-package-versions", + "version": "2.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", + "reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10", "shasum": "" }, "require": { - "php": ">=7.3" + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "vimeo/psalm": "^4.3 || ^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "1.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Jean85\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "description": "A library to get pretty versions strings of installed dependencies", "keywords": [ - "filesystem", - "iterator" + "composer", + "package", + "release", + "versions" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2024-11-18T16:19:46+00:00" }, { - "name": "phpunit/php-invoker", - "version": "3.1.1", + "name": "jonpurvis/lawman", + "version": "v3.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "url": "https://github.com/JonPurvis/lawman.git", + "reference": "fef0b37bcd3dd353815112966201abffb2f630cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/JonPurvis/lawman/zipball/fef0b37bcd3dd353815112966201abffb2f630cc", + "reference": "fef0b37bcd3dd353815112966201abffb2f630cc", "shasum": "" }, "require": { - "php": ">=7.3" + "pestphp/pest": "^3.0", + "pestphp/pest-plugin": "^3.0", + "php": "^8.2" }, "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" + "pestphp/pest-dev-tools": "^2.9", + "saloonphp/cache-plugin": "^3.0", + "saloonphp/pagination-plugin": "^2.0", + "saloonphp/rate-limit-plugin": "^2.0", + "saloonphp/saloon": "^3.6" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "JonPurvis\\Lawman\\": "src/", + "Tests\\Fixtures\\Arch\\": "tests/Fixtures/Arch" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "MIT" ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "A PestPHP Plugin to help with architecture testing SaloonPHP integrations", "keywords": [ - "process" + "framework", + "pest", + "php", + "plugin", + "saloon", + "test", + "testing", + "unit" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "issues": "https://github.com/JonPurvis/lawman/issues", + "source": "https://github.com/JonPurvis/lawman/tree/v3.1.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2024-09-16T02:13:16+00:00" }, { - "name": "phpunit/php-text-template", - "version": "2.0.4", + "name": "myclabs/deep-copy", + "version": "1.12.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { - "php": ">=7.3" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "MIT" ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "template" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { - "name": "phpunit/php-timer", - "version": "5.0.3", + "name": "nikic/php-parser", + "version": "v5.3.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { @@ -1860,9 +1831,9 @@ } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1870,267 +1841,3039 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nikita Popov" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "A PHP parser written in PHP", "keywords": [ - "timer" + "parser", + "php" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { - "name": "phpunit/phpunit", - "version": "9.5.8", + "name": "nunomaduro/collision", + "version": "v8.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "191768ccd5c85513b4068bdbe99bb6390c7d54fb" + "url": "https://github.com/nunomaduro/collision.git", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/191768ccd5c85513b4068bdbe99bb6390c7d54fb", - "reference": "191768ccd5c85513b4068bdbe99bb6390c7d54fb", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", + "reference": "f5c101b929c958e849a633283adff296ed5f38f5", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" + "filp/whoops": "^2.16.0", + "nunomaduro/termwind": "^2.1.0", + "php": "^8.2.0", + "symfony/console": "^7.1.5" }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "conflict": { + "laravel/framework": "<11.0.0 || >=12.0.0", + "phpunit/phpunit": "<10.5.1 || >=12.0.0" + }, + "require-dev": { + "larastan/larastan": "^2.9.8", + "laravel/framework": "^11.28.0", + "laravel/pint": "^1.18.1", + "laravel/sail": "^1.36.0", + "laravel/sanctum": "^4.0.3", + "laravel/tinker": "^2.10.0", + "orchestra/testbench-core": "^9.5.3", + "pestphp/pest": "^2.36.0 || ^3.4.0", + "sebastian/environment": "^6.1.0 || ^7.2.0" }, - "bin": [ - "phpunit" - ], "type": "library", "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, "branch-alias": { - "dev-master": "9.5-dev" + "dev-8.x": "8.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ - "src/Framework/Assert/Functions.php" - ] + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "Cli error handling for console/command-line PHP applications.", "keywords": [ - "phpunit", - "testing", - "xunit" + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.8" + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://www.paypal.com/paypalme/enunomaduro", "type": "custom" }, { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/nunomaduro", "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" } ], - "time": "2021-07-31T15:17:34+00:00" + "time": "2024-10-15T16:06:32+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.1", + "name": "nunomaduro/termwind", + "version": "v2.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.1.8" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "illuminate/console": "^11.33.2", + "laravel/pint": "^1.18.2", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0", + "phpstan/phpstan": "^1.12.11", + "phpstan/phpstan-strict-rules": "^1.6.1", + "symfony/var-dumper": "^7.1.8", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, "branch-alias": { - "dev-master": "1.0-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-11-21T10:39:51+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.8", + "name": "pestphp/pest", + "version": "v3.7.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "url": "https://github.com/pestphp/pest.git", + "reference": "bf3178473dcaa53b0458f21dfdb271306ea62512" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/pestphp/pest/zipball/bf3178473dcaa53b0458f21dfdb271306ea62512", + "reference": "bf3178473dcaa53b0458f21dfdb271306ea62512", "shasum": "" }, "require": { - "php": ">=7.3" + "brianium/paratest": "^7.7.0", + "nunomaduro/collision": "^8.5.0", + "nunomaduro/termwind": "^2.3.0", + "pestphp/pest-plugin": "^3.0.0", + "pestphp/pest-plugin-arch": "^3.0.0", + "pestphp/pest-plugin-mutate": "^3.0.5", + "php": "^8.2.0", + "phpunit/phpunit": "^11.5.1" + }, + "conflict": { + "filp/whoops": "<2.16.0", + "phpunit/phpunit": ">11.5.1", + "sebastian/exporter": "<6.0.0", + "webmozart/assert": "<1.11.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "pestphp/pest-dev-tools": "^3.3.0", + "pestphp/pest-plugin-type-coverage": "^3.2.0", + "symfony/process": "^7.2.0" }, + "bin": [ + "bin/pest" + ], "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "pest": { + "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v3.7.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-12-12T11:52:01+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.2" + }, + "conflict": { + "pestphp/pest": "<3.0.0" + }, + "require-dev": { + "composer/composer": "^2.7.9", + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-08T23:21:41+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "reference": "0a27e55a270cfe73d8cb70551b91002ee2cb64b0", + "shasum": "" + }, + "require": { + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "ta-tikoma/phpunit-architecture-test": "^0.8.4" + }, + "require-dev": { + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-08T23:23:55+00:00" + }, + { + "name": "pestphp/pest-plugin-faker", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-faker.git", + "reference": "48343e2806cfc12a042dead90ffff4a043167e3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-faker/zipball/48343e2806cfc12a042dead90ffff4a043167e3e", + "reference": "48343e2806cfc12a042dead90ffff4a043167e3e", + "shasum": "" + }, + "require": { + "fakerphp/faker": "^1.23.1", + "pestphp/pest": "^3.0.0", + "php": "^8.2" + }, + "require-dev": { + "pestphp/pest-dev-tools": "^3.0.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Faker.php" + ], + "psr-4": { + "Pest\\Faker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Faker Plugin", + "keywords": [ + "faker", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-faker/tree/v3.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-09-08T23:56:08+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.2.0", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^3.0.8", + "pestphp/pest-dev-tools": "^3.0.0", + "pestphp/pest-plugin-type-coverage": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-09-22T07:54:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+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.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "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|^2.0", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "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.6.1" + }, + "time": "2024-12-07T09:39:29+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "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.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "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/2.0.0" + }, + "time": "2024-10-13T11:29:49+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46b4d3529b12178112d9008337beda0cc2a1a6b4", + "reference": "46b4d3529b12178112d9008337beda0cc2a1a6b4", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2024-11-28T22:19:37+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-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 that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "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/11.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-11T12:34:27+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.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": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.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": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "2b94d4f2450b9869fa64a46fd8a6a41997aef56a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2b94d4f2450b9869fa64a46fd8a6a41997aef56a", + "reference": "2b94d4f2450b9869fa64a46fd8a6a41997aef56a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.2.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.1" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-12-11T10:52:48+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.5", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/socket": "^1.8", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.5" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-09-16T13:41:56+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.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", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "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/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "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", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-12T09:59:06+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-31T05:30:08+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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 calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-05T09:17:50+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.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", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-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": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-17T13:12:04+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "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/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2145,14 +4888,16 @@ "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 that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "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/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { @@ -2160,817 +4905,1264 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "sebastian/comparator", - "version": "4.0.6", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "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", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" + "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/console", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, + "type": "library", "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Volker Dusch", - "email": "github@wallbash.com" + "url": "https://github.com/fabpot", + "type": "github" }, { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", + "time": "2024-12-11T03:49:26+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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": "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.2.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-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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 dispatching event", + "homepage": "https://symfony.com", "keywords": [ - "comparator", - "compare", - "equality" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + }, + "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-09-25T14:20:29+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T15:49:45+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { - "name": "sebastian/complexity", - "version": "2.0.2", + "name": "symfony/finder", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "url": "https://github.com/symfony/finder.git", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/symfony/finder/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T15:52:27+00:00" + "time": "2024-10-23T06:56:12+00:00" }, { - "name": "sebastian/diff", - "version": "4.0.4", + "name": "symfony/options-resolver", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" + "config", + "configuration", + "options" ], "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T13:10:38+00:00" + "time": "2024-11-20T11:17:29+00:00" }, { - "name": "sebastian/environment", - "version": "5.1.3", + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=7.2" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "provide": { + "ext-ctype": "*" }, "suggest": { - "ext-posix": "*" + "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "5.1-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", "keywords": [ - "Xdebug", - "environment", - "hhvm" + "compatibility", + "ctype", + "polyfill", + "portable" ], "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-09-28T05:52:38+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/exporter", - "version": "4.0.3", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "php": ">=7.2" }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "4.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "classmap": [ - "src/" - ] + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", "keywords": [ - "export", - "exporter" + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-09-28T05:24:23+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/global-state", - "version": "5.0.3", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" + "php": ">=7.2" }, "suggest": { - "ext-uopz": "*" + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "5.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", "keywords": [ - "global state" + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" ], "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "1.0.3", + "name": "symfony/polyfill-php80", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-11-28T06:42:11+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "4.0.4", + "name": "symfony/polyfill-php81", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "4.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ - "src/" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T13:12:34+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "sebastian/object-reflector", - "version": "2.0.4", + "name": "symfony/process", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T13:14:26+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { - "name": "sebastian/recursion-context", - "version": "4.0.4", + "name": "symfony/service-contracts", + "version": "v3.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-10-26T13:17:30+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.3", + "name": "symfony/stopwatch", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "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": "2020-09-28T06:45:17+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "sebastian/type", - "version": "2.3.4", + "name": "symfony/string", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, "autoload": { - "classmap": [ - "src/" + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { - "name": "sebastian/version", - "version": "3.0.2", + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", "shasum": "" }, "require": { - "php": ">=7.3" + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } + "require-dev": { + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" }, + "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PHPUnit\\Architecture\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-01-05T14:10:56+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -2999,7 +6191,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.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -3007,25 +6199,25 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2024-03-03T12:36:25+00:00" }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -3063,9 +6255,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], @@ -3073,7 +6265,9 @@ "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, - "platform": [], + "platform": { + "php": "^8.2" + }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..5d53717 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,4 @@ +parameters: + level: 5 + paths: + - src diff --git a/phpunit.xml b/phpunit.xml index 3bb6875..98bac7c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,16 +1,20 @@ - + + failOnDeprecation="true" + failOnWarning="true" + failOnNotice="true" +> - - tests + + ./tests - - - - \ No newline at end of file + + + ./src + + + diff --git a/src/Data/Campaign.php b/src/Data/Campaign.php new file mode 100644 index 0000000..fd54631 --- /dev/null +++ b/src/Data/Campaign.php @@ -0,0 +1,59 @@ + $this->countryCode, + 'sender_id' => $this->senderId, + 'message' => $this->message, + 'channel' => $this->channel->value, + 'message_type' => $this->messageType, + 'phonebook_id' => $this->phonebookId, + 'delimiter' => $this->delimiter, + 'remove_duplicate' => $this->removeDuplicate, + 'campaign_type' => $this->campaignType, + 'schedule_time' => $this->runAt, + 'schedule_sms_status' => $this->status, + ]; + } +} diff --git a/src/Data/CampaignHistory.php b/src/Data/CampaignHistory.php new file mode 100644 index 0000000..0362b98 --- /dev/null +++ b/src/Data/CampaignHistory.php @@ -0,0 +1,40 @@ + $this->phoneNumber, + 'email_address' => $this->email, + 'first_name' => $this->firstName, + 'last_name' => $this->lastName, + 'company' => $this->companyName, + 'country_code' => $this->countryCode, + ]; + } +} diff --git a/src/Data/Contracts/ConvertsArrayToDTO.php b/src/Data/Contracts/ConvertsArrayToDTO.php new file mode 100644 index 0000000..494744e --- /dev/null +++ b/src/Data/Contracts/ConvertsArrayToDTO.php @@ -0,0 +1,8 @@ + + */ + public function toRequestArray(): array; +} diff --git a/src/Data/DeviceTemplate.php b/src/Data/DeviceTemplate.php new file mode 100644 index 0000000..fb058ea --- /dev/null +++ b/src/Data/DeviceTemplate.php @@ -0,0 +1,26 @@ + $this->phoneNumber, + 'template_id' => $this->templateId, + 'device_id' => $this->deviceId, + 'data' => $this->data, + ]; + } +} diff --git a/src/Data/Message.php b/src/Data/Message.php new file mode 100644 index 0000000..acf5e94 --- /dev/null +++ b/src/Data/Message.php @@ -0,0 +1,44 @@ + $this->to, + 'from' => $this->from, + 'sms' => $this->sms, + 'type' => $this->type, + 'channel' => $this->channel->value, + 'media' => [ + 'url' => $this->mediaUrl, + 'caption' => $this->mediaCaption, + ] + ]; + } +} diff --git a/src/Data/PaginatedData.php b/src/Data/PaginatedData.php new file mode 100644 index 0000000..56241ee --- /dev/null +++ b/src/Data/PaginatedData.php @@ -0,0 +1,55 @@ + $data + * @param int $currentPage + * @param int $lastPage + * @param int $total + * @param int $perPage + * @param int $from + * @param int $to + */ + public function __construct( + public readonly array $data, + public readonly int $currentPage, + public readonly int $lastPage, + public readonly int $total, + public readonly int $perPage, + public readonly int $from, + public readonly int $to, + ) { + } + + /** + * @param class-string $dtoClass + * @return self + */ + public static function fromResponse(Response $response, string $dtoClass): PaginatedData + { + $pagination = $response->json(); + /** @var array $data */ + $data = array_map( + fn (array $item) => $dtoClass::fromArray($item), + $pagination['data'] + ); + + return new PaginatedData( + data: $data, + currentPage: $pagination['current_page'] ?? $pagination['meta']['current_page'], + lastPage: $pagination['last_page'] ?? $pagination['meta']['last_page'], + total: $pagination['total'] ?? $pagination['meta']['total'], + perPage: $pagination['per_page'] ?? $pagination['meta']['per_page'], + from: $pagination['from'] ?? $pagination['meta']['from'], + to: $pagination['to'] ?? $pagination['meta']['to'], + ); + } +} diff --git a/src/Data/Phonebook.php b/src/Data/Phonebook.php new file mode 100644 index 0000000..4f1935f --- /dev/null +++ b/src/Data/Phonebook.php @@ -0,0 +1,39 @@ + $this->name, + 'description' => $this->description, + ]; + } +} diff --git a/src/Data/SenderId.php b/src/Data/SenderId.php new file mode 100644 index 0000000..442815b --- /dev/null +++ b/src/Data/SenderId.php @@ -0,0 +1,38 @@ + $this->id, + 'usecase' => $this->useCase, + 'company' => $this->company + ]; + } +} diff --git a/src/Data/Token/InAppToken.php b/src/Data/Token/InAppToken.php new file mode 100644 index 0000000..45391d5 --- /dev/null +++ b/src/Data/Token/InAppToken.php @@ -0,0 +1,29 @@ + $this->pinType->value, + 'phone_number' => $this->phoneNumber, + 'pin_attempts' => $this->pinAttempts, + 'pin_time_to_live' => $this->pinTimeToLiveMinute, + 'pin_length' => $this->pinLength, + ]; + } +} diff --git a/src/Data/Token/SendToken.php b/src/Data/Token/SendToken.php new file mode 100644 index 0000000..1fde257 --- /dev/null +++ b/src/Data/Token/SendToken.php @@ -0,0 +1,40 @@ + $this->messageType, + 'to' => $this->to, + 'from' => $this->from, + 'channel' => $this->channel->value, + 'message_text' => $this->messageText, + 'pin_placeholder' => $this->pinPlaceHolder, + 'pin_type' => $this->pinType->value, + 'pin_attempts' => $this->pinAttempts, + 'pin_time_to_live' => $this->pinTimeToLiveMinute, + 'pin_length' => $this->pinLength, + ]; + } +} diff --git a/src/Data/Token/VoiceToken.php b/src/Data/Token/VoiceToken.php new file mode 100644 index 0000000..67894f2 --- /dev/null +++ b/src/Data/Token/VoiceToken.php @@ -0,0 +1,26 @@ + $this->phoneNumber, + 'pin_attempts' => $this->pinAttempts, + 'pin_time_to_live' => $this->pinTimeToLiveMinute, + 'pin_length' => $this->pinLength, + ]; + } +} diff --git a/src/Endpoints/Campaign/GetCampaignHistoryEndpoint.php b/src/Endpoints/Campaign/GetCampaignHistoryEndpoint.php new file mode 100644 index 0000000..d4e7c61 --- /dev/null +++ b/src/Endpoints/Campaign/GetCampaignHistoryEndpoint.php @@ -0,0 +1,42 @@ + $this->page, + ]; + } + + public function resolveEndpoint(): string + { + return "/api/sms/campaigns/$this->campaignId"; + } + + /** + * @param Response $response + * @return PaginatedData + */ + public function createDtoFromResponse(Response $response): PaginatedData + { + return PaginatedData::fromResponse($response, CampaignHistory::class); + } +} diff --git a/src/Endpoints/Campaign/GetCampaignsEndpoint.php b/src/Endpoints/Campaign/GetCampaignsEndpoint.php new file mode 100644 index 0000000..32e20a3 --- /dev/null +++ b/src/Endpoints/Campaign/GetCampaignsEndpoint.php @@ -0,0 +1,42 @@ + $this->page, + ]; + } + + public function resolveEndpoint(): string + { + return '/api/sms/campaigns'; + } + + /** + * @param Response $response + * @return PaginatedData + */ + public function createDtoFromResponse(Response $response): PaginatedData + { + return PaginatedData::fromResponse($response, Campaign::class); + } +} diff --git a/src/Endpoints/Campaign/Phonebook/AddContactEndpoint.php b/src/Endpoints/Campaign/Phonebook/AddContactEndpoint.php new file mode 100644 index 0000000..17bc802 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/AddContactEndpoint.php @@ -0,0 +1,36 @@ +contact->toRequestArray(); + } + + public function resolveEndpoint(): string + { + return "/api/phonebooks/{$this->phonebookId}/contacts"; + } + + public function createDtoFromResponse(Response $response): Contact + { + return Contact::fromArray($response->json('data')); + } +} diff --git a/src/Endpoints/Campaign/Phonebook/CreatePhonebookEndpoint.php b/src/Endpoints/Campaign/Phonebook/CreatePhonebookEndpoint.php new file mode 100644 index 0000000..c2cd4fc --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/CreatePhonebookEndpoint.php @@ -0,0 +1,30 @@ +phonebook->toRequestArray(); + } +} diff --git a/src/Endpoints/Campaign/Phonebook/DeleteContactEndpoint.php b/src/Endpoints/Campaign/Phonebook/DeleteContactEndpoint.php new file mode 100644 index 0000000..b74bf96 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/DeleteContactEndpoint.php @@ -0,0 +1,20 @@ +contactId"; + } + + public function __construct(private readonly string $contactId) + { + } +} diff --git a/src/Endpoints/Campaign/Phonebook/DeletePhonebookEndpoint.php b/src/Endpoints/Campaign/Phonebook/DeletePhonebookEndpoint.php new file mode 100644 index 0000000..1507a1f --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/DeletePhonebookEndpoint.php @@ -0,0 +1,20 @@ +phonebookId"; + } + + public function __construct(private readonly string $phonebookId) + { + } +} diff --git a/src/Endpoints/Campaign/Phonebook/GetContactsEndpoint.php b/src/Endpoints/Campaign/Phonebook/GetContactsEndpoint.php new file mode 100644 index 0000000..74cb944 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/GetContactsEndpoint.php @@ -0,0 +1,42 @@ + $this->page, + ]; + } + + public function resolveEndpoint(): string + { + return "/api/phonebooks/{$this->phonebookId}/contacts"; + } + + /** + * @param Response $response + * @return PaginatedData + */ + public function createDtoFromResponse(Response $response): PaginatedData + { + return PaginatedData::fromResponse($response, Contact::class); + } +} diff --git a/src/Endpoints/Campaign/Phonebook/GetPhonebooksEndpoint.php b/src/Endpoints/Campaign/Phonebook/GetPhonebooksEndpoint.php new file mode 100644 index 0000000..c2af677 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/GetPhonebooksEndpoint.php @@ -0,0 +1,42 @@ + $this->page, + ]; + } + + public function resolveEndpoint(): string + { + return '/api/phonebooks'; + } + + /** + * @param Response $response + * @return PaginatedData + */ + public function createDtoFromResponse(Response $response): PaginatedData + { + return PaginatedData::fromResponse($response, Phonebook::class); + } +} diff --git a/src/Endpoints/Campaign/Phonebook/ImportContactEndpoint.php b/src/Endpoints/Campaign/Phonebook/ImportContactEndpoint.php new file mode 100644 index 0000000..95f0ba8 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/ImportContactEndpoint.php @@ -0,0 +1,45 @@ +file), + new MultipartValue('contact', json_encode([ + 'pid' => $this->phonebookId, + 'country_code' => $this->countryCode, + ])), + ]; + } +} diff --git a/src/Endpoints/Campaign/Phonebook/UpdatePhonebookEndpoint.php b/src/Endpoints/Campaign/Phonebook/UpdatePhonebookEndpoint.php new file mode 100644 index 0000000..24e99a3 --- /dev/null +++ b/src/Endpoints/Campaign/Phonebook/UpdatePhonebookEndpoint.php @@ -0,0 +1,30 @@ +phonebook->id}"; + } + + public function __construct(private readonly Phonebook $phonebook) + { + } + + protected function defaultBody(): array + { + return $this->phonebook->toRequestArray(); + } +} diff --git a/src/Endpoints/Campaign/SendCampaignEndpoint.php b/src/Endpoints/Campaign/SendCampaignEndpoint.php new file mode 100644 index 0000000..a37f055 --- /dev/null +++ b/src/Endpoints/Campaign/SendCampaignEndpoint.php @@ -0,0 +1,30 @@ +campaign->toRequestArray(); + } +} diff --git a/src/Endpoints/Insight/GetBalanceEndpoint.php b/src/Endpoints/Insight/GetBalanceEndpoint.php new file mode 100644 index 0000000..e585f0c --- /dev/null +++ b/src/Endpoints/Insight/GetBalanceEndpoint.php @@ -0,0 +1,16 @@ + $this->messageId + ]; + } +} diff --git a/src/Endpoints/Insight/PhoneNumberStatusEndpoint.php b/src/Endpoints/Insight/PhoneNumberStatusEndpoint.php new file mode 100644 index 0000000..94bd198 --- /dev/null +++ b/src/Endpoints/Insight/PhoneNumberStatusEndpoint.php @@ -0,0 +1,30 @@ + $this->phoneNumber, + 'country_code' => $this->countryCode + ]; + } +} diff --git a/src/Endpoints/Insight/SearchPhoneNumberEndpoint.php b/src/Endpoints/Insight/SearchPhoneNumberEndpoint.php new file mode 100644 index 0000000..74a7350 --- /dev/null +++ b/src/Endpoints/Insight/SearchPhoneNumberEndpoint.php @@ -0,0 +1,28 @@ + $this->phoneNumber + ]; + } +} diff --git a/src/Endpoints/Messaging/GetSenderIdsEndpoint.php b/src/Endpoints/Messaging/GetSenderIdsEndpoint.php new file mode 100644 index 0000000..a2faf99 --- /dev/null +++ b/src/Endpoints/Messaging/GetSenderIdsEndpoint.php @@ -0,0 +1,42 @@ + $this->page + ]; + } + + /** + * @param Response $response + * @return PaginatedData + */ + public function createDtoFromResponse(Response $response): PaginatedData + { + return PaginatedData::fromResponse($response, SenderId::class); + } +} diff --git a/src/Endpoints/Messaging/RequestSenderIdEndpoint.php b/src/Endpoints/Messaging/RequestSenderIdEndpoint.php new file mode 100644 index 0000000..dadf710 --- /dev/null +++ b/src/Endpoints/Messaging/RequestSenderIdEndpoint.php @@ -0,0 +1,30 @@ +sender->toRequestArray(); + } +} diff --git a/src/Endpoints/Messaging/SendBulkMessageEndpoint.php b/src/Endpoints/Messaging/SendBulkMessageEndpoint.php new file mode 100644 index 0000000..24bb216 --- /dev/null +++ b/src/Endpoints/Messaging/SendBulkMessageEndpoint.php @@ -0,0 +1,30 @@ +message->toRequestArray(); + } +} diff --git a/src/Endpoints/Messaging/SendDeviceTemplateEndpoint.php b/src/Endpoints/Messaging/SendDeviceTemplateEndpoint.php new file mode 100644 index 0000000..c404d93 --- /dev/null +++ b/src/Endpoints/Messaging/SendDeviceTemplateEndpoint.php @@ -0,0 +1,30 @@ +deviceTemplate->toRequestArray(); + } +} diff --git a/src/Endpoints/Messaging/SendMessageEndpoint.php b/src/Endpoints/Messaging/SendMessageEndpoint.php new file mode 100644 index 0000000..8845834 --- /dev/null +++ b/src/Endpoints/Messaging/SendMessageEndpoint.php @@ -0,0 +1,30 @@ +message->toRequestArray(); + } +} diff --git a/src/Endpoints/Messaging/SendMessageFromAutoNumberEndpoint.php b/src/Endpoints/Messaging/SendMessageFromAutoNumberEndpoint.php new file mode 100644 index 0000000..87b49ac --- /dev/null +++ b/src/Endpoints/Messaging/SendMessageFromAutoNumberEndpoint.php @@ -0,0 +1,36 @@ + $this->to, + 'message' => $this->message, + ]; + } +} diff --git a/src/Endpoints/Token/EmailTokenEndpoint.php b/src/Endpoints/Token/EmailTokenEndpoint.php new file mode 100644 index 0000000..58b3360 --- /dev/null +++ b/src/Endpoints/Token/EmailTokenEndpoint.php @@ -0,0 +1,40 @@ + $this->emailAddress, + 'code' => $this->code, + 'email_configuration_id' => $this->emailConfigurationId, + ]; + } +} diff --git a/src/Endpoints/Token/InAppTokenEndpoint.php b/src/Endpoints/Token/InAppTokenEndpoint.php new file mode 100644 index 0000000..54cbeeb --- /dev/null +++ b/src/Endpoints/Token/InAppTokenEndpoint.php @@ -0,0 +1,34 @@ +inAppToken->toRequestArray(); + } +} diff --git a/src/Endpoints/Token/SendTokenEndpoint.php b/src/Endpoints/Token/SendTokenEndpoint.php new file mode 100644 index 0000000..3cb27e1 --- /dev/null +++ b/src/Endpoints/Token/SendTokenEndpoint.php @@ -0,0 +1,34 @@ +sendToken->toRequestArray(); + } +} diff --git a/src/Endpoints/Token/VerifyTokenEndpoint.php b/src/Endpoints/Token/VerifyTokenEndpoint.php new file mode 100644 index 0000000..7a83e27 --- /dev/null +++ b/src/Endpoints/Token/VerifyTokenEndpoint.php @@ -0,0 +1,38 @@ + $this->pinId, + 'pin' => $this->pin, + ]; + } +} diff --git a/src/Endpoints/Token/VoiceCallEndpoint.php b/src/Endpoints/Token/VoiceCallEndpoint.php new file mode 100644 index 0000000..2819024 --- /dev/null +++ b/src/Endpoints/Token/VoiceCallEndpoint.php @@ -0,0 +1,38 @@ + $this->phoneNumber, + 'code' => $this->code, + ]; + } +} diff --git a/src/Endpoints/Token/VoiceTokenEndpoint.php b/src/Endpoints/Token/VoiceTokenEndpoint.php new file mode 100644 index 0000000..cd52fa5 --- /dev/null +++ b/src/Endpoints/Token/VoiceTokenEndpoint.php @@ -0,0 +1,34 @@ +voiceToken->toRequestArray(); + } +} diff --git a/src/Enums/MessageChannel.php b/src/Enums/MessageChannel.php new file mode 100644 index 0000000..351d21f --- /dev/null +++ b/src/Enums/MessageChannel.php @@ -0,0 +1,15 @@ +get('sms/inbox', $this->payload()); - } - - /** - * returns your total balance and balance information from your wallet, - * such as currency. http://developer.termii.com/docs/balance/ - * - * @return array - */ - public function getBallance() - { - return $this->get('get-balance', $this->payload()); - } - - /** - * verify phone numbers and automatically detect their - * status as well as current network. It also tells ifthe number - * has activated the do-not-disturb settings. http://developer.termii.com/docs/search/ - * - * @param string $phone_number Phone number to search for - * @return array - */ - public function search($phone_number) - { - $payload = array_merge( - $this->payload(), - [ - 'phone_number' => $phone_number - ] - ); - - return $this->get('check/dnd', $payload); - } -} \ No newline at end of file diff --git a/src/RequestException.php b/src/RequestException.php new file mode 100644 index 0000000..d06e273 --- /dev/null +++ b/src/RequestException.php @@ -0,0 +1,9 @@ +phonebookResource ??= new PhonebookResource($this->connector); + } + + public function send(Campaign $campaign): Response + { + return $this->connector->send(new SendCampaignEndpoint($campaign)); + } + + public function get(int $page = 1): Response + { + return $this->connector->send(new GetCampaignsEndpoint($page)); + } + + public function getHistory(string|int $campaignId, int $page = 1): Response + { + return $this->connector->send(new GetCampaignHistoryEndpoint($campaignId, $page)); + } +} diff --git a/src/Resources/Campaign/PhonebookResource.php b/src/Resources/Campaign/PhonebookResource.php new file mode 100644 index 0000000..4326d09 --- /dev/null +++ b/src/Resources/Campaign/PhonebookResource.php @@ -0,0 +1,65 @@ +connector->send(new GetPhonebooksEndpoint($page)); + } + + public function create(Phonebook $phonebook): Response + { + return $this->connector->send(new CreatePhonebookEndpoint($phonebook)); + } + + public function update(Phonebook $phonebook): Response + { + return $this->connector->send(new UpdatePhonebookEndpoint($phonebook)); + } + + public function delete(string $phonebookId): Response + { + return $this->connector->send(new DeletePhonebookEndpoint($phonebookId)); + } + + public function getContacts(string $phonebookId, int $page = 1): Response + { + return $this->connector->send(new GetContactsEndpoint($phonebookId, $page)); + } + + public function addContact(string $phonebookId, Contact $contact): Response + { + return $this->connector->send(new AddContactEndpoint($phonebookId, $contact)); + } + + public function deleteContact(string $contactId): Response + { + return $this->connector->send(new DeleteContactEndpoint($contactId)); + } + + /** + * @param string $phonebookId + * @param string $countryCode + * @param StreamInterface|resource|string|int $file + */ + public function importContact(string $phonebookId, string $countryCode, $file): Response + { + return $this->connector->send(new ImportContactEndpoint($phonebookId, $countryCode, $file)); + } +} diff --git a/src/Resources/InsightResource.php b/src/Resources/InsightResource.php new file mode 100644 index 0000000..9a54954 --- /dev/null +++ b/src/Resources/InsightResource.php @@ -0,0 +1,33 @@ +connector->send(new GetBalanceEndpoint()); + } + + public function searchPhoneNumber(string $phoneNumber): Response + { + return $this->connector->send(new SearchPhoneNumberEndpoint($phoneNumber)); + } + + public function statusOfPhoneNumber(string $phoneNumber, string $countryCode): Response + { + return $this->connector->send(new PhoneNumberStatusEndpoint($phoneNumber, $countryCode)); + } + + public function history(?string $messageId = null): Response + { + return $this->connector->send(new HistoryEndpoint($messageId)); + } +} diff --git a/src/Resources/MessagingResource.php b/src/Resources/MessagingResource.php new file mode 100644 index 0000000..bc8ef51 --- /dev/null +++ b/src/Resources/MessagingResource.php @@ -0,0 +1,55 @@ +connector->send(new SendMessageEndpoint($message)); + } + + /** + + * @throws RequestException + */ + public function sendBulk(Message $message): Response + { + return $this->connector->send(new SendBulkMessageEndpoint($message)); + } + + /** + + * @throws RequestException + */ + public function SendMessageFromAutoNumber(string $to, string $message): Response + { + return $this->connector->send(new SendMessageFromAutoNumberEndpoint($to, $message)); + } + + /** + + * @throws RequestException + */ + public function sendDeviceTemplate(DeviceTemplate $deviceTemplate): Response + { + return $this->connector->send(new SendDeviceTemplateEndpoint($deviceTemplate)); + } +} diff --git a/src/Resources/SenderIdResource.php b/src/Resources/SenderIdResource.php new file mode 100644 index 0000000..18116ba --- /dev/null +++ b/src/Resources/SenderIdResource.php @@ -0,0 +1,32 @@ +connector->send(new GetSenderIdsEndpoint($page)); + } + + /** + * @throws RequestException + */ + public function requestId(SenderId $sender): Response + { + return $this->connector->send(new RequestSenderIdEndpoint($sender)); + } +} diff --git a/src/Resources/TokenResource.php b/src/Resources/TokenResource.php new file mode 100644 index 0000000..17e51c3 --- /dev/null +++ b/src/Resources/TokenResource.php @@ -0,0 +1,51 @@ +connector->send(new EmailTokenEndpoint($emailAddress, $code, $emailConfigurationId)); + } + + public function inApp(InAppToken $inAppToken): Response + { + return $this->connector->send(new InAppTokenEndpoint($inAppToken)); + } + + public function send(SendToken $sendToken): Response + { + return $this->connector->send(new SendTokenEndpoint($sendToken)); + } + + public function verify(string $pinId, string $pinCode): Response + { + return $this->connector->send(new VerifyTokenEndpoint($pinId, $pinCode)); + } + + public function voiceCall(string $phoneNumber, string $code): Response + { + return $this->connector->send(new VoiceCallEndpoint($phoneNumber, $code)); + } + + public function voice(VoiceToken $voiceToken): Response + { + return $this->connector->send(new VoiceTokenEndpoint($voiceToken)); + } +} diff --git a/src/Termii.php b/src/Termii.php index 853b708..8b9d95f 100644 --- a/src/Termii.php +++ b/src/Termii.php @@ -2,365 +2,16 @@ namespace Okolaa\TermiiPHP; -use GuzzleHttp\Client; - -/** - * Termii SMS APi Library for PHP - * @author Douglas Okolaa - */ class Termii { - public $verifySSL = true; - protected $apiKey; - protected $senderId; - protected $maxAttempts = 3; - protected $pinTimeToLive = 0; - protected $pinLength = 6; - protected $pinPlaceholder = "< _pin_ >"; - protected $pinType = "NUMERIC"; - protected $channel = "generic"; - protected $tokenMessageType = "ALPHANUMERIC"; - protected $messageType = "plain"; - protected $response; - - /** - * Termii constructor. - */ - public function __construct($senderId = 'N-Alert', $apiKey = '') - { - $this->senderId = $senderId; - $this->apiKey = $apiKey; - } - - /** - * send text messages to their customers. The API accepts - * form-encoded request bodies, returns JSON-encoded responses, - * and uses standard HTTP response codes. - * more info: http://developer.termii.com/docs/messaging/ - * - * @param array $payload - * @return array - */ - public function sendMessage($payload) - { - $data = array_merge( - $this->payload(), - [ - "from" => $this->senderId, - "channel" => $this->channel, - "type" => $this->messageType, - "to" => $payload['phone_number'], - "sms" => $payload['message'], - ] - ); - - return $this->post('sms/send', $data,); - } + private static ?TermiiConnector $connector = null; - /** - * Request Payload - * @return array - */ - protected function payload() + public static function initialize(string $apiKey, string $baseUrl = 'https://v3.api.termii.com'): TermiiConnector { - return ["api_key" => $this->apiKey]; - } - - /** - * Submit post request to Termii - * @param string $path - * @param array $payload - * @return array Request response payload - */ - protected function post(string $path, array $payload) - { - $response = $this->client()->post( - 'api/' . $path, - [ - 'headers' => ['Content-Type' => 'application/json'], - 'json' => $payload, - 'verify' => $this->verifySSL - ] - ); - - $this->response = $response; - return json_decode($response->getBody(), true); - } - - /** - * Initialize client - * @return Client - */ - protected function client() - { - return new Client(['base_uri' => $this->getBaseURI()]); - } - - /** - * Base URI of API endpoint - * @return string - */ - protected function getBaseURI() - { - return 'https://api.ng.termii.com/'; - } + if (self::$connector === null) { + self::$connector = new TermiiConnector($apiKey, $baseUrl); + } - /** - * trigger one-time-passwords (pins) across any available - * messaging channel on Termii. Passwords created are generated - * randomly and there's an option to set an expiry time. - * more info: http://developer.termii.com/docs/send-token/ - * - * @param array $payload - * @return array - */ - public function sendToken(array $payload) - { - $data = array_merge( - $this->payload(), - [ - "message_type" => $this->tokenMessageType, - "to" => $payload['phone_number'], - "from" => $this->senderId, - "channel" => $this->channel, - "pin_attempts" => $this->maxAttempts, - "pin_time_to_live" => $this->pinTimeToLive, - "pin_length" => $this->pinLength, - "pin_placeholder" => $this->pinPlaceholder, - "message_text" => $payload['message'], - "pin_type" => $this->pinType - ] - ); - - return $this->post('sms/otp/send', $data); - } - - /** - * checks tokens sent to customers and returns a response - * confirming the status of the token. A token can either be - * confirmed as verified or expired based on the timer set for - * the token. http://developer.termii.com/docs/verify-token/ - * - * @param array $payload - * @return array - */ - public function verifyToken(array $payload) - { - $data = array_merge( - $this->payload(), - [ - "pin_id" => $payload['pin_id'], - "pin" => $payload['pin'] - ] - ); - - return $this->post('sms/otp/verify', $data); - } - - /** - * Tokens are numeric or alpha-numeric codes generated - * to authenticate login requests and verify customer - * transactions. http://developer.termii.com/docs/in-app-token/ - * - * @param array $payload - * @return array - */ - public function InAppToken(array $payload) - { - $data = array_merge( - $this->payload(), - [ - "pin_type" => $this->pinType, - "phone_number" => $payload['phone_number'], - "pin_attempts" => $this->maxAttempts, - "pin_time_to_live" => $this->pinTimeToLive, - "pin_length" => $this->pinLength - ] - ); - - return $this->post('sms/otp/generate', $data); - } - - /** - * send messages to customers using Termii's - * auto-generated messaging numbers that adapt to customers location. - * http://developer.termii.com/docs/number/ - * - * @param array $payload - * @return array - */ - public function sendWithAutoGeneratedNumber(array $payload) - { - $data = array_merge( - $this->payload(), - [ - "to" => $payload['phone_number'], - "sms" => $payload['message'] - ] - ); - - return $this->post('sms/number/send', $data); - } - - /** - * retrieve the status of all registered sender ID - * and request registration of sender ID through - * GET request type. http://developer.termii.com/docs/senderid/ - * - * @param array $payload - * @return array - */ - public function getSenderIds() - { - return $this->get('sender-id', $this->payload()); - } - - /** - * Submit get request to Termii API - * @param string $path - * @param array $payload - * @return array Request response payload - */ - protected function get(string $path, array $payload) - { - $response = $this->client()->get( - 'api/' . $path, - [ - 'headers' => ['Content-Type' => 'application/json'], - 'query' => $payload, - 'verify' => $this->verifySSL - ] - ); - - $this->response = $response; - return json_decode($response->getBody(), true); - } - - /** - * Get last Response from Termii - * @return object|null - */ - public function getResponse() - { - return $this->response ?? null; - } - - /** - * Sets Max Attempts - * - * @param int $attempts - * @return $this - */ - public function setMaxAttempts(int $attempts) - { - $this->maxAttempts = $attempts; - return $this; - } - - /** - * Sets Pin Time To Live - * - * @param int $minute - * @return $this - */ - public function setPinTimeToLive(int $minute) - { - $this->pinTimeToLive = $minute; - return $this; - } - - /** - * Sets Pin Type - * - * @param string $type - * @return $this - */ - public function setPinType(string $type) - { - $this->pinType = $type; - return $this; - } - - /** - * Sets Channel to Send Message Via - * - * @param string $channel - * @return $this - */ - public function setChannel(string $channel) - { - $this->channel = $channel; - return $this; - } - - /** - * Sets Pin Placeholder - * - * @param string $placeholder - * @return $this - */ - public function SetPinPlaceholder(string $placeholder) - { - $this->pinPlaceholder = $placeholder; - return $this; - } - - /** - * Sets Message Type - * - * @param string $messageType - * @return $this - */ - public function setMessageType(string $messageType) - { - $this->messageType = $messageType; - return $this; - } - - /** - * Sets Token Message Type - * - * @param string $tokenMessageType - * @return $this - */ - public function setTokenMessageType(string $tokenMessageType) - { - $this->tokenMessageType = $tokenMessageType; - return $this; - } - - /** - * Sets Pin Length - * @param int $pinLength - * @return $this - */ - public function SetPinLength(int $pinLength) - { - $this->pinLength = $pinLength; - return $this; - } - - /** - * Sets Sender Id - * - * @param string $sender - * @return $this - */ - public function setSender(string $sender) - { - $this->senderId = $sender; - return $this; - } - - /** - * Sets API Key - * - * @param string $key - * @return $this - */ - public function setAPIKey(string $key) - { - $this->apiKey = $key; - return $this; + return self::$connector; } } diff --git a/src/TermiiAuthenticator.php b/src/TermiiAuthenticator.php new file mode 100644 index 0000000..7f8eb08 --- /dev/null +++ b/src/TermiiAuthenticator.php @@ -0,0 +1,60 @@ +isQueryBasedMethod($pendingRequest->getMethod())) { + $pendingRequest->query()->add('api_key', $this->apiKey); + } else { + $this->mergeApiKeyIntoBody($pendingRequest->body()); + } + } + + /** + * Check if the HTTP method supports query-based API key injection. + */ + private function isQueryBasedMethod(Method $method): bool + { + return match ($method) { + Method::GET, Method::DELETE => true, + default => false, + }; + } + + /** + * Merge the API key into the request body if the body is mergeable. + */ + private function mergeApiKeyIntoBody(BodyRepository $body): void + { + if ($body instanceof MultipartBodyRepository) { + $body->add( + 'contact', + json_encode( + json_decode($body->get('contact')->value, true) + + [ + 'api_key' => $this->apiKey + ] + ) + ); + } elseif ($body instanceof MergeableBody) { + $body->merge(['api_key' => $this->apiKey]); + } + } +} diff --git a/src/TermiiConnector.php b/src/TermiiConnector.php new file mode 100644 index 0000000..90c0df7 --- /dev/null +++ b/src/TermiiConnector.php @@ -0,0 +1,96 @@ +baseUrl; + } + + public function senderIdApi(): SenderIdResource + { + return $this->senderIdResource ??= new SenderIdResource($this); + } + + public function messagingApi(): MessagingResource + { + return $this->messagingResource ??= new MessagingResource($this); + } + + public function campaignApi(): CampaignResource + { + return $this->campaignResource ??= new CampaignResource($this); + } + + public function tokenApi(): TokenResource + { + return $this->tokenResource ??= new TokenResource($this); + } + + public function insightApi(): InsightResource + { + return $this->insightResource ??= new InsightResource($this); + } + + protected function defaultAuth(): TermiiAuthenticator + { + return new TermiiAuthenticator($this->apiKey); + } + + protected function defaultHeaders(): array + { + return [ + 'Content-Type' => 'application/json', + ]; + } + + protected function defaultConfig(): array + { + return [ + 'verify' => true, + ]; + } + + public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable + { + return new RequestException($response, previous: $senderException); + } +} diff --git a/tests/Feature/CompaignApiTest.php b/tests/Feature/CompaignApiTest.php new file mode 100644 index 0000000..62555ed --- /dev/null +++ b/tests/Feature/CompaignApiTest.php @@ -0,0 +1,212 @@ +toSendGetRequest() + ->toUse(CreatesDtoFromResponse::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->get() + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->dto())->toBeInstanceOf(PaginatedData::class) + ->and($response->dto()->data[0])->toBeInstanceOf(Phonebook::class); +}); + +test('it can create a phonebook', closure: function() { + expect(CreatePhonebookEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->create($phonebook = new Phonebook(fake()->jobTitle(), fake()->sentence())) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('phonebook_name', $phonebook->name) + ->toHaveKey('description', $phonebook->description); +}); + +test('it can update a phonebook', closure: function() { + expect(UpdatePhonebookEndpoint::class) + ->toSendPatchRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->update($phonebook = new Phonebook(fake()->jobTitle(), fake()->sentence())) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('phonebook_name', $phonebook->name) + ->toHaveKey('description', $phonebook->description); +}); + +test('it can delete a phonebook', closure: function() { + expect(DeletePhonebookEndpoint::class) + ->toSendDeleteRequest() + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->delete('phonebook-id') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/phonebooks/phonebook-id'); +}); + +test('it can fetch contacts', closure: function() { + expect(GetContactsEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->getContacts('phonebook-id') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/phonebooks/phonebook-id/contacts') + ->and($response->dto())->toBeInstanceOf(PaginatedData::class) + ->and($response->dto()->data[0])->toBeInstanceOf(Contact::class); +}); + +test('it can add a single contact to phonebook', closure: function() { + expect(AddContactEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->addContact('phonebook-id', new Contact(fake()->phoneNumber(), fake()->safeEmail())) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/phonebooks/phonebook-id/contacts') + ->and($response->dto())->toBeInstanceOf(Contact::class); +}); + +test('it can add a multiple contact to phonebook', closure: function() { + expect(ImportContactEndpoint::class) + ->toSendPostRequest() + ->toUse(HasMultipartBody::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->importContact('phonebook-id', 'NG', fake()->file('./', './vendor')) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/phonebooks/contacts/upload'); +}); + +test('it can DELETE a contact to phonebook', closure: function() { + expect(DeleteContactEndpoint::class) + ->toSendDeleteRequest() + ->and( + $response = createTestConnector() + ->campaignApi() + ->phoneBook() + ->deleteContact('contact-id') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/phonebook/contact/contact-id'); +}); + +test('it can send campaign', closure: function() { + expect(SendCampaignEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->campaignApi() + ->send(new Campaign(fake()->phoneNumber(), fake()->slug(), MessageChannel::Generic, 'personalized')) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/campaigns/send'); +}); + +test('it can fetch campaigns', closure: function() { + expect(GetCampaignsEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->campaignApi() + ->get() + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/campaigns') + ->and($response->dto())->toBeInstanceOf(PaginatedData::class) + ->and($response->dto()->data[0])->toBeInstanceOf(Campaign::class); + ; +}); + +test('it can fetch campaign HISTORY', closure: function() { + expect(GetCampaignHistoryEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->campaignApi() + ->getHistory(64) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/campaigns/64') + ->and($response->dto())->toBeInstanceOf(PaginatedData::class) + ->and($response->dto()->data[0])->toBeInstanceOf(CampaignHistory::class); +}); diff --git a/tests/Feature/InsightApiTest.php b/tests/Feature/InsightApiTest.php new file mode 100644 index 0000000..5c722f5 --- /dev/null +++ b/tests/Feature/InsightApiTest.php @@ -0,0 +1,78 @@ +toSendGetRequest() + ->and( + $response = createTestConnector() + ->insightApi() + ->getBalance() + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/get-balance') + ; +}); + +test('it can search phone number', closure: function() { + expect(SearchPhoneNumberEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->insightApi() + ->searchPhoneNumber('1234567890') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->query()->all()) + ->not()->toBeEmpty() + ->toHaveKey('phone_number', '1234567890') + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/check/dnd'); +}); + +test('it can check phone number status', closure: function() { + expect(PhoneNumberStatusEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->insightApi() + ->statusOfPhoneNumber('1234567890', 'US') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->query()->all()) + ->not()->toBeEmpty() + ->toHaveKey('phone_number', '1234567890') + ->toHaveKey('country_code', 'US') + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/insight/number/query'); +}); + +test('it can get history', closure: function() { + expect(HistoryEndpoint::class) + ->toSendGetRequest() + ->and( + $response = createTestConnector() + ->insightApi() + ->history() + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getRequest()->query()->all()) + ->toHaveKey('message_id', null) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/inbox') + ; +}); diff --git a/tests/Feature/MessagingApiTest.php b/tests/Feature/MessagingApiTest.php new file mode 100644 index 0000000..6142814 --- /dev/null +++ b/tests/Feature/MessagingApiTest.php @@ -0,0 +1,98 @@ +toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->messagingApi() + ->send($message = new Message(fake()->phoneNumber(), fake()->company(), fake()->sentence())) + ) + ->toBeInstanceOf(\Saloon\Http\Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('to', $message->to) + ->toHaveKey('from', $message->from) + ->toHaveKey('sms', $message->sms); +}); + +test('it can send bulk message', closure: function() { + expect(SendBulkMessageEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->messagingApi() + ->sendBulk($message = new Message([fake()->phoneNumber()], fake()->company(), fake()->sentence())) + ) + ->toBeInstanceOf(\Saloon\Http\Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('to', $message->to) + ->toHaveKey('from', $message->from) + ->toHaveKey('sms', $message->sms); +}); + +test('it can send device template', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Messaging\SendDeviceTemplateEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + createTestConnector() + ->messagingApi() + ->sendDeviceTemplate(new DeviceTemplate(fake()->phoneNumber(), fake()->uuid(), [])) + ->status() + ) + ->toBe(200); +}); + +test('it can send message with termii number', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Messaging\SendMessageFromAutoNumberEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + createTestConnector() + ->messagingApi() + ->SendMessageFromAutoNumber(fake()->phoneNumber(), fake()->sentence()) + ->status() + ) + ->toBe(200); +}); + +test('it can get sender ids', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Messaging\GetSenderIdsEndpoint::class) + ->toSendGetRequest() + ->and( + createTestConnector() + ->senderIdApi() + ->getIds(2) + ->dto() + ) + ->toBeInstanceOf(\Okolaa\TermiiPHP\Data\PaginatedData::class); +}); + +test('it can request sender id', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Messaging\RequestSenderIdEndpoint::class) + ->toSendPostRequest() + ->and( + $response = createTestConnector() + ->senderIdApi() + ->requestId(new \Okolaa\TermiiPHP\Data\SenderId('demo-inc', 'Demo Inc', 'send notifications')) + ) + ->toBeInstanceOf(\Saloon\Http\Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('company', 'Demo Inc') + ->toHaveKey('usecase', 'send notifications') + ->toHaveKey('sender_id', 'demo-inc'); +}); diff --git a/tests/Feature/TokenApiTest.php b/tests/Feature/TokenApiTest.php new file mode 100644 index 0000000..dee1830 --- /dev/null +++ b/tests/Feature/TokenApiTest.php @@ -0,0 +1,160 @@ +toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->send(new SendToken( + 'NUMERIC', + '23490126727', + 'Termii', + TokenChannel::GENERIC, + '123456', + '< 1234 >', + PinType::AlphaNumeric, + )) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKeys([ + 'message_type', + 'to', + 'from', + 'channel', + 'pin_attempts', + 'pin_time_to_live', + 'pin_length', + 'pin_placeholder', + 'message_text', + 'message_text', + ]) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/otp/send'); +}); +test('it can verify token', closure: function() { + expect(VerifyTokenEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->verify('123456', '23490126727') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKeys([ + 'pin_id', + 'pin', + ]) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/otp/verify'); +}); + +test('it can request token', closure: function() { + expect(EmailTokenEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->email('test@test.com', '1234', 'config-id') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKeys([ + 'email_address', + 'code', + 'email_configuration_id' + ]) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/email/otp/send'); +}); + +test('it can check token status', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Token\InAppTokenEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->inApp(new InAppToken(PinType::Numeric, '2348000000000', 1)) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKeys([ + 'pin_type', + 'phone_number', + 'pin_attempts', + 'pin_time_to_live', + 'pin_length', + ]) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/otp/generate'); +}); + +test('it can send voice token', closure: function() { + expect(VoiceTokenEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->voice(new VoiceToken( + '23490126727', + )) + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKeys([ + 'phone_number', + 'pin_attempts', + 'pin_time_to_live', + 'pin_length', + ]) + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/otp/send/voice'); +}); + +test('it can send voice call token', closure: function() { + expect(\Okolaa\TermiiPHP\Endpoints\Token\VoiceCallEndpoint::class) + ->toSendPostRequest() + ->toUse(HasJsonBody::class) + ->and( + $response = createTestConnector() + ->tokenApi() + ->voiceCall('23490126727', '123456') + ) + ->toBeInstanceOf(Response::class) + ->and($response->status())->toBe(200) + ->and($response->getPendingRequest()->body()->all()) + ->toHaveKey('phone_number', '23490126727') + ->toHaveKey('code', '123456') + ->and($response->getRequest()->resolveEndpoint()) + ->toBeString() + ->toEndWith('/api/sms/otp/call'); +}); diff --git a/tests/Fixtures/Saloon/get_balance.json.json b/tests/Fixtures/Saloon/get_balance.json.json new file mode 100644 index 0000000..1864480 --- /dev/null +++ b/tests/Fixtures/Saloon/get_balance.json.json @@ -0,0 +1,19 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Fri, 13 Dec 2024 07:50:39 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "user": "Tayo Joel", + "balance": 0, + "currency": "NGN" + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/get_campaign_history.json.json b/tests/Fixtures/Saloon/get_campaign_history.json.json new file mode 100644 index 0000000..0ee47ee --- /dev/null +++ b/tests/Fixtures/Saloon/get_campaign_history.json.json @@ -0,0 +1,47 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Mon, 09 Dec 2024 19:28:58 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "data": [ + { + "id": 64, + "sender": "Termii", + "receiver": "2347089509657", + "message": "Hi This is from Termii Campaign", + "message_abbreviation": "Hi This is from Termii Campaign", + "amount": 1, + "channel": "Generic", + "sms_type": "plain", + "message_id": "0011551727393226622357573897694282599004522965786793671662369098835884420487860904021011663", + "status": "Sent", + "date_created": "2020-01-26 07:24:29", + "last_updated": "2020-01-26 07:24:29" + } + ], + "links": { + "first": "https://BASE_URL/api/sms/campaigns/C5dbae7faa2b65?page=1", + "last": "https://BASE_URL/api/sms/campaigns/C5dbae7faa2b65?page=1", + "prev": null, + "next": null + }, + "meta": { + "current_page": 1, + "from": 1, + "last_page": 1, + "path": "https://BASE_URL/api/sms/campaigns/C5dbae7faa2b65", + "per_page": 15, + "to": 1, + "total": 1 + } + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/get_campaigns.json.json b/tests/Fixtures/Saloon/get_campaigns.json.json new file mode 100644 index 0000000..29a6ba2 --- /dev/null +++ b/tests/Fixtures/Saloon/get_campaigns.json.json @@ -0,0 +1,154 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Mon, 09 Dec 2024 19:25:05 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "data": [ + { + "campaign_id": "C60e30b2c806da", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2022-07-05 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-05T13:37:48.000000Z" + }, + { + "campaign_id": "C60e306e63478d", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2022-07-05 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-05T13:19:34.000000Z" + }, + { + "campaign_id": "C60e306c106c21", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2022-07-05 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-05T13:18:57.000000Z" + }, + { + "campaign_id": "C60e2f2a4782b8", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-07-22 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-05T11:53:08.000000Z" + }, + { + "campaign_id": "C60ddda932de77", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-07-22 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-01T15:09:07.000000Z" + }, + { + "campaign_id": "C60ddda80ea6cc", + "phone_book": "test", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-07-22 00:00:00", + "status": "Scheduled", + "created_at": "2021-07-01T15:08:48.000000Z" + }, + { + "campaign_id": "C60dc5a8437e63", + "phone_book": "adeyinka", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-06-30 06:00:00", + "status": "Scheduled", + "created_at": "2021-06-30T11:50:28.000000Z" + }, + { + "campaign_id": "C60db3fc2954a0", + "phone_book": "adeyinka", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-06-29 05:00:00", + "status": "Scheduled", + "created_at": "2021-06-29T15:44:02.000000Z" + }, + { + "campaign_id": "C60db3f70c8df9", + "phone_book": "-", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-06-29 05:00:00", + "status": "Pending", + "created_at": "2021-06-29T15:42:40.000000Z" + }, + { + "campaign_id": "C60db3ef5a3ceb", + "phone_book": "-", + "sender": "Termii", + "camp_type": "scheduled", + "channel": "-", + "total_recipients": 0, + "run_at": "2021-06-29 05:00:00", + "status": "Pending", + "created_at": "2021-06-29T15:40:37.000000Z" + }, + { + "campaign_id": "C5dbae7faa2b65", + "phone_book": "-", + "sender": "Termii", + "camp_type": "regular", + "channel": "Sms", + "total_recipients": 2, + "run_at": "2019-10-31 15:56:10", + "status": "Delivered", + "created_at": "2019-10-31T14:56:10.000000Z" + } + ], + "links": { + "first": "https://BASE_URL/api/sms/campaigns?page=1", + "last": "https://BASE_URL/api/sms/campaigns?page=1", + "prev": null, + "next": null + }, + "meta": { + "current_page": 1, + "from": 1, + "last_page": 1, + "path": "https://BASE_URL/api/sms/campaigns", + "per_page": 15, + "to": 11, + "total": 11 + } + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/get_contacts.json.json b/tests/Fixtures/Saloon/get_contacts.json.json new file mode 100644 index 0000000..f20c1d6 --- /dev/null +++ b/tests/Fixtures/Saloon/get_contacts.json.json @@ -0,0 +1,93 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Mon, 09 Dec 2024 18:42:08 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "data": [ + { + "id": 3, + "pid": 4, + "phone_number": "2347062609181", + "email_address": null, + "message": null, + "company": null, + "first_name": null, + "last_name": null, + "create_at": "2021-06-30 12:02:15", + "updated_at": "2021-06-30 12:02:15" + }, + { + "id": 4, + "pid": 4, + "phone_number": "2347051428948", + "email_address": null, + "message": null, + "company": null, + "first_name": null, + "last_name": null, + "create_at": "2021-06-30 12:02:20", + "updated_at": "2021-06-30 12:02:20" + }, + { + "id": 5, + "pid": 4, + "phone_number": "2348173343852", + "email_address": null, + "message": null, + "company": null, + "first_name": null, + "last_name": null, + "create_at": "2021-06-30 12:02:20", + "updated_at": "2021-06-30 12:02:20" + }, + { + "id": 6, + "pid": 4, + "phone_number": "2348057616056", + "email_address": null, + "message": null, + "company": null, + "first_name": null, + "last_name": null, + "create_at": "2021-06-30 12:02:20", + "updated_at": "2021-06-30 12:02:20" + }, + { + "id": 7, + "pid": 4, + "phone_number": "2348060463787", + "email_address": null, + "message": null, + "company": null, + "first_name": null, + "last_name": null, + "create_at": "2021-06-30 12:02:20", + "updated_at": "2021-06-30 12:02:20" + } + ], + "links": { + "first": "https://BASE_URL/api/phonebooks/04c3ebcc-3a7e-485a-88c1-68e731386f77/contacts?page=1", + "last": "https://BASE_URL/api/phonebooks/04c3ebcc-3a7e-485a-88c1-68e731386f77/contacts?page=1", + "prev": null, + "next": null + }, + "meta": { + "current_page": 1, + "from": 1, + "last_page": 1, + "path": "https://BASE_URL/api/phonebooks/04c3ebcc-3a7e-485a-88c1-68e731386f77/contacts", + "per_page": 25, + "to": 22, + "total": 22 + } + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/get_phonebooks.json.json b/tests/Fixtures/Saloon/get_phonebooks.json.json new file mode 100644 index 0000000..2a500f9 --- /dev/null +++ b/tests/Fixtures/Saloon/get_phonebooks.json.json @@ -0,0 +1,89 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Thu, 28 Nov 2024 08:44:37 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "data": [ + { + "id": "f9c28de9-ab5a-4513-9c9f-338be8e1c390", + "name": "labore", + "total_number_of_contacts": 0, + "date_created": "2021-07-01 14:44:42", + "last_updated": "2021-07-01 14:44:42" + }, + { + "id": "0d974867-7fc8-4dd9-b069-6ca33dc12930", + "name": "numquam", + "total_number_of_contacts": 0, + "date_created": "2021-07-01 14:44:33", + "last_updated": "2021-07-01 14:44:33" + }, + { + "id": "b8bd4d35-1dba-4ffb-9fd6-8ecd672801fd", + "name": "totam", + "total_number_of_contacts": 0, + "date_created": "2021-07-01 14:44:16", + "last_updated": "2021-07-01 14:44:16" + }, + { + "id": "2d9f4a02-85b8-45e5-9f5b-30f93ef472e2", + "name": "adeyinka", + "total_number_of_contacts": 0, + "date_created": "2021-06-29 12:23:42", + "last_updated": "2021-06-29 12:23:42" + }, + { + "id": "779c2bbe-130b-4ea8-a30e-1e81f7e4d4d9", + "name": "testerboos", + "total_number_of_contacts": 0, + "date_created": "2021-06-28 15:50:06", + "last_updated": "2021-06-28 15:50:06" + }, + { + "id": "04c3ebcc-3a7e-485a-88c1-68e731386f77", + "name": "omnis", + "total_number_of_contacts": 22, + "date_created": "2021-06-25 15:11:56", + "last_updated": "2021-06-30 12:02:23" + }, + { + "id": "145d23bd-daef-4403-8236-73f648c63387", + "name": "bosun", + "total_number_of_contacts": 0, + "date_created": "2021-06-25 12:59:10", + "last_updated": "2021-06-25 12:59:10" + }, + { + "id": "67503708-0725-49eb-9bc6-feee9faea58a", + "name": "test", + "total_number_of_contacts": 776, + "date_created": "2021-06-25 12:58:45", + "last_updated": "2021-07-01 15:39:35" + } + ], + "links": { + "first": "https://BASE_URL/api/phonebooks?page=1", + "last": "https://BASE_URL/api/phonebooks?page=1", + "prev": null, + "next": null + }, + "meta": { + "current_page": 1, + "from": 1, + "last_page": 1, + "path": "https://BASE_URL/api/phonebooks", + "per_page": 15, + "to": 8, + "total": 8 + } + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/get_sender_ids.json.json b/tests/Fixtures/Saloon/get_sender_ids.json.json new file mode 100644 index 0000000..d422dad --- /dev/null +++ b/tests/Fixtures/Saloon/get_sender_ids.json.json @@ -0,0 +1,77 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Wed, 27 Nov 2024 19:59:16 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "current_page": 1, + "data": [ + { + "sender_id": "ACME Key", + "status": "unblock", + "company": "ACME", + "usecase": null, + "country": null, + "created_at": "2021-03-29 16:51:53" + }, + { + "sender_id": "ACME Alert", + "status": "unblock", + "company": "ACME", + "usecase": null, + "country": null, + "created_at": "2021-03-29 16:51:09" + }, + { + "sender_id": "ACME Wall", + "status": "unblock", + "company": "ACME", + "usecase": null, + "country": null, + "created_at": "2021-03-29 16:50:38" + }, + { + "sender_id": "Hooli", + "status": "unblock", + "company": "Hooli", + "usecase": null, + "country": null, + "created_at": "2021-03-26 13:19:16" + }, + { + "sender_id": "Google", + "status": "unblock", + "company": null, + "usecase": null, + "country": null, + "created_at": "2021-01-19 17:41:30" + }, + { + "sender_id": "Facebook", + "status": "unblock", + "company": null, + "usecase": null, + "country": null, + "created_at": "2021-01-19 17:41:14" + } + ], + "first_page_url": "https://BASE_URL/api/sender-id?page=1", + "from": 1, + "last_page": 47, + "last_page_url": "https://BASE_URL/api/sender-id?page=47", + "next_page_url": "https://BASE_URL/api/sender-id?page=2", + "path": "https://BASE_URL/api/sender-id", + "per_page": 10, + "prev_page_url": null, + "to": 15, + "total": 704 + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/history.json.json b/tests/Fixtures/Saloon/history.json.json new file mode 100644 index 0000000..a49e9fc --- /dev/null +++ b/tests/Fixtures/Saloon/history.json.json @@ -0,0 +1,47 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Fri, 13 Dec 2024 08:34:19 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": [ + { + "sender": "N-Alert", + "receiver": "233257883990", + "message": "New year in a bit", + "amount": 1, + "reroute": 0, + "status": "DND Active on Phone Number", + "sms_type": "plain", + "send_by": "sender", + "media_url": null, + "message_id": "5508751839629937023", + "notify_url": null, + "notify_id": null, + "created_at": "2020-08-15 12:36:42" + }, + { + "sender": "N-Alert", + "receiver": "233222883380", + "message": "New year in a bit", + "amount": 1, + "reroute": 0, + "status": "DND Active on Phone Number", + "sms_type": "plain", + "send_by": "sender", + "media_url": null, + "message_id": "5508755559629937033", + "notify_url": null, + "notify_id": null, + "created_at": "2020-08-15 12:36:42" + } + + ] +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/in_app_token.json.json b/tests/Fixtures/Saloon/in_app_token.json.json new file mode 100644 index 0000000..ff23b96 --- /dev/null +++ b/tests/Fixtures/Saloon/in_app_token.json.json @@ -0,0 +1,24 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Type": "application\/json", + "Content-Length": "43", + "Date": "Wed, 11 Dec 2024 22:10:03 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "status": "success", + "data": { + "pin_id": "db34d5ce-9bd4-4f10-b8ec-8ee402ccd0", + "otp": "522726", + "phone_number": "2348109077743", + "phone_number_other": "Termii" + } + } +} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/phone_number_status.json.json b/tests/Fixtures/Saloon/phone_number_status.json.json new file mode 100644 index 0000000..675b377 --- /dev/null +++ b/tests/Fixtures/Saloon/phone_number_status.json.json @@ -0,0 +1,38 @@ +{ + "statusCode": 200, + "headers": { + "Vary": [ + "Origin", + "Access-Control-Request-Method", + "Access-Control-Request-Headers" + ], + "Content-Length": "0", + "Date": "Fri, 13 Dec 2024 08:30:36 GMT", + "Via": "1.1 google", + "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + "data": { + "result": [ + { + "routeDetail": { + "number": "2348753243651", + "ported": 0 + }, + "countryDetail": { + "countryCode": "234", + "mobileCountryCode": "621", + "iso": "NG" + }, + "operatorDetail": { + "operatorCode": "ANG", + "operatorName": "Airtel Nigeria", + "mobileNumberCode": "20", + "mobileRoutingCode": "41", + "carrierIdentificationCode": "23433", + "lineType": "Mobile" + }, + "status": 200 + } + ] + } +} \ No newline at end of file diff --git a/tests/InsightTest.php b/tests/InsightTest.php deleted file mode 100644 index c26cb37..0000000 --- a/tests/InsightTest.php +++ /dev/null @@ -1,67 +0,0 @@ -load(); - } - - /** - * check if the Termii has no syntax error - */ - public function testCheckForSyntaxError() - { - $termii = new Insight; - $this->assertTrue(is_object($termii)); - unset($termii); - } - - public function testGetSenderIds() - { - $termii = new Insight(); - $termii->setAPIKey($_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->getSenderIds(); - - $this->assertIsArray($response, "Invalid Response"); - } - - public function testGetBallance() - { - $termii = new Insight(); - $termii->setAPIKey($_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->getBallance(); - - $this->assertIsArray($response, "Invalid Response"); - } - - public function testSearch() - { - $termii = new Insight(); - $termii->setAPIKey($_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->search($_ENV["TEST_PHONE_NUMBER"]); - $this->assertIsArray($response, "Invalid Response"); - } -} diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 0000000..e8f2154 --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,91 @@ +extend(Tests\TestCase::class) + ->group('feature') + ->in('Feature'); + +pest()->extend(Tests\TestCase::class) + ->group('unit') + ->in('Unit'); + +/* +|-------------------------------------------------------------------------- +| Expectations +|-------------------------------------------------------------------------- +| +| When you're writing tests, you often need to check that values meet certain conditions. The +| "expect()" function gives you access to a set of "expectations" methods that you can use +| to assert different things. Of course, you may extend the Expectation API at any time. +| +*/ + +expect()->extend('toBeOne', function() { + return $this->toBe(1); +}); + +/* +|-------------------------------------------------------------------------- +| Functions +|-------------------------------------------------------------------------- +| +| While Pest is very powerful out-of-the-box, you may have some testing code specific to your +| project that you don't want to repeat in every file. Here you can also expose helpers as +| global functions to help you to reduce the number of lines of code in your test files. +| +*/ + +function createTestConnector(?MockClient $mockClient = null): \Okolaa\TermiiPHP\TermiiConnector +{ + $connector = Termii::initialize('api-key'); + $connector->getAuthenticator(); + + if ($mockClient !== null) { + $connector->withMockClient($mockClient); + } + + return $connector; +} + +function createTestEndpoint(Method $method = Method::GET): Request +{ + return new class ($method) extends Request implements HasBody { + use HasJsonBody; + + public function __construct(Method $method) + { + $this->method = $method; + } + + public function resolveEndpoint(): string + { + return '/test'; + } + }; +} + +Config::preventStrayRequests(); + +uses() + ->beforeEach(fn () => MockClient::destroyGlobal()) + ->beforeEach(fn () => TestCase::initGlobalMockClient()) + ->in(__DIR__); diff --git a/tests/TermiiTest.php b/tests/TermiiTest.php deleted file mode 100644 index 2e45b33..0000000 --- a/tests/TermiiTest.php +++ /dev/null @@ -1,150 +0,0 @@ -load(); - } - - /** - * check if the Termii has no syntax error - */ - public function testCheckForSyntaxError() - { - $termii = new Termii; - $this->assertTrue(is_object($termii)); - unset($termii); - } - - public function testHasApiKeyAttribute() - { - $this->assertClassHasAttribute("apiKey", Termii::class); - } - - public function testHasSenderIdAttribute() - { - $this->assertClassHasAttribute("senderId", Termii::class); - } - - public function testCanSendMessage() - { - $termii = new Termii($_ENV["TERMII_SENDER_ID"], $_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $sent = $termii->sendMessage( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - "message" => "Unit Test Message" - ] - ); - - $this->assertIsArray($sent, "Invalid Response"); - $this->assertArrayHasKey("message_id", $sent); - unset($termii); - } - - public function testCanSendToken() - { - $termii = new Termii($_ENV["TERMII_SENDER_ID"], $_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - //Set Options - $termii->setMaxAttempts(2); - $termii->setPinTimeToLive(5); - $termii->SetPinLength(4); - $termii->setPinType("NUMERIC"); - $termii->setMaxAttempts(1); - - $sent = $termii->sendToken( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - "message" => "Your pin is < _pin_ >" - ] - ); - - $this->assertArrayHasKey("pinId", $sent); - } - - public function testVerifyToken() - { - $termii = new Termii($_ENV["TERMII_SENDER_ID"], $_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->verifyToken( - [ - "pin_id" => "f862cb33-9dd3-42b3-b705-18200c0e800f", - "pin" => "1234", - ] - ); - - $this->assertIsArray($response, "Invalid Response"); - } - - public function testInAppToken() - { - $termii = new Termii($_ENV["TERMII_SENDER_ID"], $_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->InAppToken( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - ] - ); - - $this->assertIsArray($response, "Invalid Response"); - $this->assertEquals("success", $response["status"]); - $this->assertIsArray($response["data"]); - } - - public function testSendWithAutoGeneratedNumber() - { - $termii = new Termii(); - $termii->setAPIKey($_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->sendWithAutoGeneratedNumber( - [ - "phone_number" => $_ENV["TEST_PHONE_NUMBER"], - 'message' => "TermiiPHP Unit Test", - ] - ); - - $this->assertIsArray($response, "Invalid Response"); - $this->assertEquals("ok", $response["code"]); - } - - public function testGetSenderIds() - { - $termii = new Termii(); - $termii->setAPIKey($_ENV["TERMII_API_KEY"]); - - // Disable Verify SSL in Guzzle - $termii->verifySSL = $this->verifySSL; - - $response = $termii->getSenderIds(); - - $this->assertIsArray($response, "Invalid Response"); - $this->assertIsArray($response["data"]); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..1bb25e4 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,112 @@ + MockResponse::make(), + SendMessageEndpoint::class => MockResponse::make([ + 'message_id' => '9122821270554876574', + 'message' => 'Successfully Sent', + 'balance' => 9, + 'user' => 'Peter Mcleish' + ]), + SendBulkMessageEndpoint::class => MockResponse::make([ + 'code' => 'ok', + 'message_id' => '9122821270554876574', + 'message' => 'Successfully Sent', + 'balance' => 9, + 'user' => 'Peter Mcleish' + ]), + SendDeviceTemplateEndpoint::class => MockResponse::make([ + 'code' => 'ok', + 'message_id' => '2255298515609943356', + 'message' => 'Successfully Sent', + 'balance' => 'unlimited', + 'user' => 'Termii Inc.' + ]), + SendMessageFromAutoNumberEndpoint::class => MockResponse::make([ + 'code' => 'ok', + 'message_id' => '174749423', + 'message' => 'Successfully Sent', + 'balance' => 8, + 'user' => 'Seun Junior' + ]), + GetSenderIdsEndpoint::class => MockResponse::fixture('get_sender_ids.json'), + RequestSenderIdEndpoint::class => MockResponse::make(), + GetPhonebooksEndpoint::class => MockResponse::fixture('get_phonebooks.json'), + CreatePhonebookEndpoint::class => MockResponse::make(), + UpdatePhonebookEndpoint::class => MockResponse::make(), + DeletePhonebookEndpoint::class => MockResponse::make(), + GetContactsEndpoint::class => MockResponse::fixture('get_contacts.json'), + AddContactEndpoint::class => MockResponse::make([ + 'data' => [ + 'id' => 3647982, + 'phone_number' => '123456789', + 'email_address' => 'test@gmail.com', + 'first_name' => 'test', + 'last_name' => 'contact', + 'company' => 'Termii', + 'country_code' => '234', + 'message' => null, + 'create_at' => '2021-10-11 10:15:35', + 'updated_at' => '2021-10-11 10:15:35', + ] + ]), + ImportContactEndpoint::class => MockResponse::make(), + DeleteContactEndpoint::class => MockResponse::make(), + SendCampaignEndpoint::class => MockResponse::make(), + GetCampaignsEndpoint::class => MockResponse::fixture('get_campaigns.json'), + GetCampaignHistoryEndpoint::class => MockResponse::fixture('get_campaign_history.json'), + SendTokenEndpoint::class => MockResponse::make(), + VoiceTokenEndpoint::class => MockResponse::make(), + VerifyTokenEndpoint::class => MockResponse::make(), + EmailTokenEndpoint::class => MockResponse::make(), + InAppTokenEndpoint::class => MockResponse::fixture('in_app_token.json'), + VoiceCallEndpoint::class => MockResponse::make(), + GetBalanceEndpoint::class => MockResponse::fixture('get_balance.json'), + SearchPhoneNumberEndpoint::class => MockResponse::make([ + 'number' => '2347089509657', + 'status' => 'DND blacklisted', + 'network' => 'Airtel Nigeria', + 'network_code' => '62120', + ]), + PhoneNumberStatusEndpoint::class => MockResponse::fixture('phone_number_status.json'), + HistoryEndpoint::class => MockResponse::fixture('history.json'), + ]); + } +} diff --git a/tests/Unit/ConnectorTest.php b/tests/Unit/ConnectorTest.php new file mode 100644 index 0000000..ee88e06 --- /dev/null +++ b/tests/Unit/ConnectorTest.php @@ -0,0 +1,69 @@ +toBeInstanceOf(TermiiConnector::class) + ->toBeInstanceOf(Connector::class); +}); + +test('connector has authentication configured correctly', function() { + expect(createTestConnector()->getAuthenticator()) + ->toBeInstanceOf(TermiiAuthenticator::class) + ->toBeInstanceOf(Authenticator::class); +}); + +test('has default client config', function() { + expect(createTestConnector()->config()->all()) + ->not()->toBeEmpty() + ->toHaveKey('verify', true); +}); + +test('has default required header', function() { + expect(createTestConnector()->headers()->all()) + ->not()->toBeEmpty() + ->toHaveKey('Content-Type', 'application/json'); +}); + +test('configures baseURL correctly', function() { + $connector = new TermiiConnector('api-key', 'https://test-base-url/'); + + expect($connector->resolveBaseUrl()) + ->toBe('https://test-base-url/'); +}); + +test('senderIdApi method returns an instance of SenderIdResource', function() { + expect(createTestConnector()->senderIdApi()) + ->toBeInstanceOf(SenderIdResource::class) + ->toBeInstanceOf(BaseResource::class); +}); + +test('messagingApi returns instance of MessagingResource', function() { + expect(createTestConnector()->messagingApi()) + ->toBeInstanceOf(MessagingResource::class) + ->toBeInstanceOf(BaseResource::class); +}); + +test('campaignApi returns instance of MessagingResource', function() { + $resource = createTestConnector()->campaignApi(); + expect($resource)->toBeInstanceOf(CampaignResource::class) + ->toBeInstanceOf(BaseResource::class) + ->and($resource->phoneBook()) + ->toBeInstanceOf(PhonebookResource::class)->toBeInstanceOf(BaseResource::class); +}); + +test('tokenApi returns instance of MessagingResource', function() { + expect(createTestConnector()->tokenApi()) + ->toBeInstanceOf(TokenResource::class) + ->toBeInstanceOf(BaseResource::class); +}); diff --git a/tests/Unit/TermiiAuthenticatorTest.php b/tests/Unit/TermiiAuthenticatorTest.php new file mode 100644 index 0000000..b8084a5 --- /dev/null +++ b/tests/Unit/TermiiAuthenticatorTest.php @@ -0,0 +1,43 @@ +set($pendingRequest); + + expect($pendingRequest->query()->all())->toHaveKey('api_key', 'test_api_key'); +}); + +test('TermiiAuthenticator sets API key in query for DELETE method', function() { + $pendingRequest = new PendingRequest(createTestConnector(), createTestEndpoint(Method::DELETE)); + $authenticator = new TermiiAuthenticator('test_api_key'); + + $authenticator->set($pendingRequest); + + expect($pendingRequest->query()->all())->toHaveKey('api_key', 'test_api_key'); +}); + +test('TermiiAuthenticator sets API key in body for POST method', function() { + $pendingRequest = new PendingRequest(createTestConnector(), createTestEndpoint(Method::POST)); + $authenticator = new TermiiAuthenticator('test_api_key'); + + $authenticator->set($pendingRequest); + + expect($pendingRequest->body()->all())->toHaveKey('api_key', 'test_api_key'); +}); + +test('TermiiAuthenticator does not set API key in query for POST method', function() { + $pendingRequest = new PendingRequest(createTestConnector(), createTestEndpoint(Method::POST)); + $authenticator = new TermiiAuthenticator('test_api_key'); + + $authenticator->set($pendingRequest); + + expect($pendingRequest->query()->all())->not->toHaveKey('api_key'); +});