diff --git a/.docker/php/Dockerfile b/.docker/php/Dockerfile new file mode 100644 index 0000000..a3a7de4 --- /dev/null +++ b/.docker/php/Dockerfile @@ -0,0 +1,25 @@ +ARG PHP_VERSION=8.3 + +FROM php:${PHP_VERSION}-alpine + +# Install system dependencies +RUN apk update && apk add --no-cache \ + $PHPIZE_DEPS \ + linux-headers \ + zlib-dev \ + libmemcached-dev \ + cyrus-sasl-dev + +RUN pecl install xdebug redis memcached \ + && docker-php-ext-enable xdebug redis memcached + +# Copy custom PHP configuration +COPY .docker/php/kariricode-php.ini /usr/local/etc/php/conf.d/ + +# Instalação do Composer +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +RUN apk del --purge $PHPIZE_DEPS && rm -rf /var/cache/apk/* + +# Mantém o contêiner ativo sem fazer nada +CMD tail -f /dev/null diff --git a/.docker/php/kariricode-php.ini b/.docker/php/kariricode-php.ini new file mode 100644 index 0000000..9e90446 --- /dev/null +++ b/.docker/php/kariricode-php.ini @@ -0,0 +1,14 @@ +[PHP] +memory_limit = 256M +upload_max_filesize = 50M +post_max_size = 50M +date.timezone = America/Sao_Paulo + +[Xdebug] +; zend_extension=xdebug.so +xdebug.mode=debug +xdebug.start_with_request=yes +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 +xdebug.log=/tmp/xdebug.log +xdebug.idekey=VSCODE diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e461630 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +KARIRI_APP_ENV=develop +KARIRI_PHP_VERSION=8.3 +KARIRI_PHP_PORT=9003 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..31f41b6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +/.docker export-ignore +/.github export-ignore +/.vscode export-ignore +/tests export-ignore +/vendor export-ignore +/.env export-ignore +/.env.example export-ignore +/.gitignore export-ignore +/.php-cs-fixer.php export-ignore +/.phpcs-cache export-ignore +/docker-compose.yml export-ignore +/phpcs.xml export-ignore +/phpinsights.php export-ignore +/phpstan.neon export-ignore +/phpunit.xml export-ignore +/psalm.xml export-ignore +/Makefile export-ignore \ No newline at end of file diff --git a/.github/workflows/kariri-ci-cd.yml b/.github/workflows/kariri-ci-cd.yml new file mode 100644 index 0000000..bd9f272 --- /dev/null +++ b/.github/workflows/kariri-ci-cd.yml @@ -0,0 +1,72 @@ +name: Kariri CI Pipeline + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + setup-and-lint: + runs-on: ubuntu-latest + strategy: + matrix: + php: ["8.3"] + + steps: + - uses: actions/checkout@v3 + + - name: Cache Composer dependencies + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Set up PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: mbstring, xml + tools: composer:v2, php-cs-fixer, phpunit + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Validate composer.json + run: composer validate + + - name: Coding Standards Check + run: vendor/bin/php-cs-fixer fix --dry-run --diff + + unit-tests: + needs: setup-and-lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Download Composer Cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Set up PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: mbstring, xml + tools: composer:v2, php-cs-fixer, phpunit + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Run PHPUnit Tests + run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text + + - name: Security Check + run: vendor/bin/security-checker security:check diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e5baad --- /dev/null +++ b/.gitignore @@ -0,0 +1,66 @@ +# Arquivos de configuração do sistema +/.idea/ +*.sublime-project +*.sublime-workspace +/.phpunit.result.cache +/.php_cs.cache +/.php_cs.dist.cache +/phpstan.neon.dist +/phpstan.neon.cache +/.phpstan.result.cache +/.phpcs-cache + +# Dependências +/vendor/ +/node_modules/ + +# Arquivos específicos do sistema operacional +.DS_Store +Thumbs.db + +# Arquivos de build e compilação +/build/ +/dist/ +*.log +*.tlog +*.tmp +*.temp + +# Arquivos e pastas de ambientes virtuais +.env + +# Arquivos de cache +/cache/ +*.cache +*.class + +# Arquivos de log +*.log +*.sql +*.sqlite + +# Pasta de testes que não devem ser incluídas no repositório +coverage/ +coverage* + +# Arquivos de pacotes +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# Outros arquivos e pastas +*.swp +*~ +._* +temp/ +tmp/ +.vscode/launch.json +.vscode/extensions.json +tests/lista_de_arquivos.php +tests/lista_de_arquivos_test.php +lista_de_arquivos.txt +lista_de_arquivos_tests.txt +add_static_to_providers.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..c3a51bb --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,69 @@ +in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') + ->exclude('var') + ->exclude('config') + ->exclude('vendor'); + +return (new PhpCsFixer\Config()) + ->setParallelConfig(new PhpCsFixer\Runner\Parallel\ParallelConfig(4, 20)) + ->setRules([ + '@PSR12' => true, + '@Symfony' => true, + 'full_opening_tag' => false, + 'phpdoc_var_without_name' => false, + 'phpdoc_to_comment' => false, + 'array_syntax' => ['syntax' => 'short'], + 'concat_space' => ['spacing' => 'one'], + 'binary_operator_spaces' => [ + 'default' => 'single_space', + 'operators' => [ + '=' => 'single_space', + '=>' => 'single_space', + ], + ], + 'blank_line_before_statement' => [ + 'statements' => ['return'] + ], + 'cast_spaces' => ['space' => 'single'], + 'class_attributes_separation' => [ + 'elements' => [ + 'const' => 'none', + 'method' => 'one', + 'property' => 'none' + ] + ], + 'declare_equal_normalize' => ['space' => 'none'], + 'function_typehint_space' => true, + 'lowercase_cast' => true, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'ordered_imports' => true, + 'phpdoc_align' => ['align' => 'left'], + 'phpdoc_no_alias_tag' => ['replacements' => ['type' => 'var', 'link' => 'see']], + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'trim_array_spaces' => true, + 'space_after_semicolon' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_whitespace_before_comma_in_array' => true, + 'whitespace_after_comma_in_array' => true, + 'visibility_required' => ['elements' => ['const', 'method', 'property']], + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'method_chaining_indentation' => true, + 'class_definition' => [ + 'single_item_single_line' => false, + 'multi_line_extends_each_single_line' => true, + ], + 'not_operator_with_successor_space' => false + ]) + ->setRiskyAllowed(true) + ->setFinder($finder) + ->setUsingCache(false); diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..38f7f80 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "[php]": { + "editor.defaultFormatter": "junstyle.php-cs-fixer" + }, + "php-cs-fixer.executablePath": "${workspaceFolder}/vendor/bin/php-cs-fixer", + "php-cs-fixer.onsave": true, + "php-cs-fixer.rules": "@PSR12", + "php-cs-fixer.config": ".php_cs.dist", + "php-cs-fixer.formatHtml": true +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..07b1871 --- /dev/null +++ b/Makefile @@ -0,0 +1,174 @@ +# Initial configurations +PHP_SERVICE := kariricode-exception +DC := docker-compose + +# Command to execute commands inside the PHP container +EXEC_PHP := $(DC) exec -T php + +# Icons +CHECK_MARK := ✅ +WARNING := ⚠️ +INFO := ℹ️ + +# Colors +RED := \033[0;31m +GREEN := \033[0;32m +YELLOW := \033[1;33m +NC := \033[0m # No Color + +# Check if Docker is installed +CHECK_DOCKER := @command -v docker > /dev/null 2>&1 || { echo >&2 "${YELLOW}${WARNING} Docker is not installed. Aborting.${NC}"; exit 1; } +# Check if Docker Compose is installed +CHECK_DOCKER_COMPOSE := @command -v docker-compose > /dev/null 2>&1 || { echo >&2 "${YELLOW}${WARNING} Docker Compose is not installed. Aborting.${NC}"; exit 1; } +# Function to check if the container is running +CHECK_CONTAINER_RUNNING := @docker ps | grep $(PHP_SERVICE) > /dev/null 2>&1 || { echo >&2 "${YELLOW}${WARNING} The container $(PHP_SERVICE) is not running. Run 'make up' to start it.${NC}"; exit 1; } +# Check if the .env file exists +CHECK_ENV := @test -f .env || { echo >&2 "${YELLOW}${WARNING} .env file not found. Run 'make setup-env' to configure.${NC}"; exit 1; } + +## setup-env: Copy .env.example to .env if the latter does not exist +setup-env: + @test -f .env || (cp .env.example .env && echo "${GREEN}${CHECK_MARK} .env file created successfully from .env.example${NC}") + +check-environment: + @echo "${GREEN}${INFO} Checking Docker, Docker Compose, and .env file...${NC}" + $(CHECK_DOCKER) + $(CHECK_DOCKER_COMPOSE) + $(CHECK_ENV) + +check-container-running: + $(CHECK_CONTAINER_RUNNING) + +## up: Start all services in the background +up: check-environment + @echo "${GREEN}${INFO} Starting services...${NC}" + @$(DC) up -d + @echo "${GREEN}${CHECK_MARK} Services are up!${NC}" + +## down: Stop and remove all containers +down: check-environment + @echo "${YELLOW}${INFO} Stopping and removing services...${NC}" + @$(DC) down + @echo "${GREEN}${CHECK_MARK} Services stopped and removed!${NC}" + +## build: Build Docker images +build: check-environment + @echo "${YELLOW}${INFO} Building services...${NC}" + @$(DC) build + @echo "${GREEN}${CHECK_MARK} Services built!${NC}" + +## logs: Show container logs +logs: check-environment + @echo "${YELLOW}${INFO} Container logs:${NC}" + @$(DC) logs + +## re-build: Rebuild and restart containers +re-build: check-environment + @echo "${YELLOW}${INFO} Stopping and removing current services...${NC}" + @$(DC) down + @echo "${GREEN}${INFO} Rebuilding services...${NC}" + @$(DC) build + @echo "${GREEN}${INFO} Restarting services...${NC}" + @$(DC) up -d + @echo "${GREEN}${CHECK_MARK} Services rebuilt and restarted successfully!${NC}" + @$(DC) logs + +## shell: Access the shell of the PHP container +shell: check-environment check-container-running + @echo "${GREEN}${INFO} Accessing the shell of the PHP container...${NC}" + @$(DC) exec php sh + +## composer-install: Install Composer dependencies. Use make composer-install [PKG="[vendor/package [version]]"] [DEV="--dev"] +composer-install: check-environment check-container-running + @echo "${GREEN}${INFO} Installing Composer dependencies...${NC}" + @if [ -z "$(PKG)" ]; then \ + $(EXEC_PHP) composer install; \ + else \ + $(EXEC_PHP) composer require $(PKG) $(DEV); \ + fi + @echo "${GREEN}${CHECK_MARK} Composer operation completed!${NC}" + +## composer-remove: Remove Composer dependencies. Usage: make composer-remove PKG="vendor/package" +composer-remove: check-environment check-container-running + @if [ -z "$(PKG)" ]; then \ + echo "${RED}${WARNING} You must specify a package to remove. Usage: make composer-remove PKG=\"vendor/package\"${NC}"; \ + else \ + $(EXEC_PHP) composer remove $(PKG); \ + echo "${GREEN}${CHECK_MARK} Package $(PKG) removed successfully!${NC}"; \ + fi + +## composer-update: Update Composer dependencies +composer-update: check-environment check-container-running + @echo "${GREEN}${INFO} Updating Composer dependencies...${NC}" + $(EXEC_PHP) composer update + @echo "${GREEN}${CHECK_MARK} Dependencies updated!${NC}" + +## test: Run tests +test: check-environment check-container-running + @echo "${GREEN}${INFO} Running tests...${NC}" + $(EXEC_PHP) ./vendor/bin/phpunit --testdox --colors=always tests + @echo "${GREEN}${CHECK_MARK} Tests completed!${NC}" + +## test-file: Run tests on a specific class. Usage: make test-file FILE=[file] +test-file: check-environment check-container-running + @echo "${GREEN}${INFO} Running test for class $(FILE)...${NC}" + $(EXEC_PHP) ./vendor/bin/phpunit --testdox --colors=always tests/$(FILE) + @echo "${GREEN}${CHECK_MARK} Test for class $(FILE) completed!${NC}" + +## coverage: Run test coverage with visual formatting +coverage: check-environment check-container-running + @echo "${GREEN}${INFO} Analyzing test coverage...${NC}" + XDEBUG_MODE=coverage $(EXEC_PHP) ./vendor/bin/phpunit --coverage-text --colors=always tests | ccze -A + +## coverage-html: Run test coverage and generate HTML report +coverage-html: check-environment check-container-running + @echo "${GREEN}${INFO} Analyzing test coverage and generating HTML report...${NC}" + XDEBUG_MODE=coverage $(EXEC_PHP) ./vendor/bin/phpunit --coverage-html ./coverage-report-html tests + @echo "${GREEN}${INFO} Test coverage report generated in ./coverage-report-html${NC}" + +## run-script: Run a PHP script. Usage: make run-script SCRIPT="path/to/script.php" +run-script: check-environment check-container-running + @echo "${GREEN}${INFO} Running script: $(SCRIPT)...${NC}" + $(EXEC_PHP) php $(SCRIPT) + @echo "${GREEN}${CHECK_MARK} Script executed!${NC}" + +## cs-check: Run PHP_CodeSniffer to check code style +cs-check: check-environment check-container-running + @echo "${GREEN}${INFO} Checking code style...${NC}" + $(EXEC_PHP) ./vendor/bin/php-cs-fixer fix --dry-run --diff + @echo "${GREEN}${CHECK_MARK} Code style check completed!${NC}" + +## cs-fix: Run PHP CS Fixer to fix code style +cs-fix: check-environment check-container-running + @echo "${GREEN}${INFO} Fixing code style with PHP CS Fixer...${NC}" + $(EXEC_PHP) ./vendor/bin/php-cs-fixer fix + @echo "${GREEN}${CHECK_MARK} Code style fixed!${NC}" + +## security-check: Check for security vulnerabilities in dependencies +security-check: check-environment check-container-running + @echo "${GREEN}${INFO} Checking for security vulnerabilities with Security Checker...${NC}" + $(EXEC_PHP) ./vendor/bin/security-checker security:check + @echo "${GREEN}${CHECK_MARK} Security check completed!${NC}" + +## quality: Run all quality commands +quality: check-environment check-container-running cs-check test security-check + @echo "${GREEN}${CHECK_MARK} All quality commands executed!${NC}" + +## help: Show initial setup steps and available commands +help: + @echo "${GREEN}Initial setup steps for configuring the project:${NC}" + @echo "1. ${YELLOW}Initial environment setup:${NC}" + @echo " ${GREEN}${CHECK_MARK} Copy the environment file:${NC} make setup-env" + @echo " ${GREEN}${CHECK_MARK} Start the Docker containers:${NC} make up" + @echo " ${GREEN}${CHECK_MARK} Install Composer dependencies:${NC} make composer-install" + @echo "2. ${YELLOW}Development:${NC}" + @echo " ${GREEN}${CHECK_MARK} Access the PHP container shell:${NC} make shell" + @echo " ${GREEN}${CHECK_MARK} Run a PHP script:${NC} make run-script SCRIPT=\"script_name.php\"" + @echo " ${GREEN}${CHECK_MARK} Run the tests:${NC} make test" + @echo "3. ${YELLOW}Maintenance:${NC}" + @echo " ${GREEN}${CHECK_MARK} Update Composer dependencies:${NC} make composer-update" + @echo " ${GREEN}${CHECK_MARK} Clear the application cache:${NC} make cache-clear" + @echo " ${RED}${WARNING} Stop and remove all Docker containers:${NC} make down" + @echo "\n${GREEN}Available commands:${NC}" + @sed -n 's/^##//p' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ": "}; {printf "${YELLOW}%-30s${NC} %s\n", $$1, $$2}' + +.PHONY: setup-env up down build logs re-build shell composer-install composer-remove composer-update test test-file coverage coverage-html run-script cs-check cs-fix security-check quality help diff --git a/README.md b/README.md new file mode 100644 index 0000000..21dac99 --- /dev/null +++ b/README.md @@ -0,0 +1,344 @@ +# KaririCode Framework: Exception Component + +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) + +![PHP](https://img.shields.io/badge/PHP-777BB4?style=for-the-badge&logo=php&logoColor=white) ![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white) ![PHPUnit](https://img.shields.io/badge/PHPUnit-3776AB?style=for-the-badge&logo=php&logoColor=white) + +A comprehensive and flexible exception handling component for PHP, part of the KaririCode Framework. It provides a structured approach to error management, enhancing the robustness and maintainability of your applications. + +## Table of Contents + +- [Features](#features) +- [Installation](#installation) +- [Usage](#usage) + - [Basic Usage](#basic-usage) + - [Advanced Usage](#advanced-usage) +- [Error Code Range Table](#error-code-range-table) +- [Available Exception Types](#available-exception-types) +- [Integration with Other KaririCode Components](#integration-with-other-kariricode-components) +- [Development and Testing](#development-and-testing) +- [License](#license) +- [Support and Community](#support-and-community) + +## Features + +- Hierarchical exception structure for better error categorization +- Context-aware exceptions for richer error information +- Static factory methods for easy exception creation +- Integration with KaririCode's error handling and logging systems +- Extensible architecture allowing custom exception types +- Comprehensive set of pre-defined exception types for common scenarios + +## Installation + +You can install the Exception component via Composer: + +```bash +composer require kariricode/exception +``` + +### Requirements + +- PHP 8.1 or higher +- Composer + +## Usage + +### Basic Usage + +#### Using Pre-defined Exceptions in Your Code + +The KaririCode Exception component provides a variety of pre-defined exceptions that you can use to handle common error scenarios in a professional and structured manner. Below is an example of how to use these exceptions in an object-oriented context. + +```php +getAttribute('userId'); + + $userData = $this->userService->getUserData($userId); + return $this->responseBuilder($response) + ->setData($userData) + ->setHeader('Content-Type', 'application/json') + ->setStatus(200) + ->build(); + } +} + +// UserService.php +namespace YourApp\Service; + +use YourApp\Repository\UserRepository; +use KaririCode\Contract\Log\Logger; + +class UserService +{ + private UserRepository $userRepository; + private Logger $logger; + + public function __construct(UserRepository $userRepository, Logger $logger) + { + $this->userRepository = $userRepository; + $this->logger = $logger; + } + + public function getUserData(int $userId): array + { + return $this->userRepository->findUserById($userId); + } +} + +// UserRepository.php +namespace YourApp\Repository; + +use KaririCode\Contract\Database\EntityManager; +use KaririCode\Exception\Database\DatabaseException; + +class UserRepository +{ + private EntityManager $entityManager; + + public function __construct(EntityManager $entityManager) + { + $this->entityManager = $entityManager; + } + + public function findUserById(int $userId): array + { + $sql = 'SELECT * FROM users WHERE id = ?'; + $userData = $this->entityManager->query($sql, [$userId]); + + if ($userData === false) { + throw DatabaseException::queryError($sql, $this->entityManager->getLastError()); + } + + return $userData; + } +} + +``` + +### Advanced Usage + +Create custom exceptions by extending the base classes: + +```php +orderRepository->getUserOrderLimit($userId); + + if ($totalAmount > $userOrderLimit) { + $this->logger->warning('Order exceeds user limit', [ + 'userId' => $userId, + 'orderAmount' => $totalAmount, + 'userLimit' => $userOrderLimit, + ]); + + throw OrderException::orderLimitExceeded($totalAmount, $userOrderLimit); + } + + $this->orderRepository->createOrder($userId, $items, $totalAmount); + + } +} +``` + +## Error Code Range Table + +Here is a proposed table for the **error code ranges**. Each range is assigned to a group of related errors, allowing better organization and identification of errors in the system. + +### Error Code Range Table + +| Range | Error Group | Description | +| --------------- | --------------------------- | ----------------------------------------------------- | +| **1000 - 1099** | **Authentication Errors** | Errors related to authentication and login | +| **1100 - 1199** | **Authorization Errors** | Errors related to permissions and roles | +| **1200 - 1299** | **Cache Errors** | Errors related to cache operations | +| **1300 - 1399** | **Configuration Errors** | Errors related to configuration settings | +| **1400 - 1499** | **Container Errors** | Errors related to dependency injection and services | +| **1500 - 1599** | **Database Errors** | Errors related to database connections, queries, etc. | +| **1600 - 1699** | **Event Errors** | Errors related to event handling and dispatching | +| **1700 - 1799** | **External Service Errors** | Errors related to external API calls and services | +| **1800 - 1899** | **File System Errors** | Errors related to file operations (reading, writing) | +| **1900 - 1999** | **Input/Validation Errors** | Errors related to invalid input or validation | +| **2000 - 2099** | **Localization Errors** | Errors related to localization and translations | +| **2100 - 2199** | **Middleware Errors** | Errors related to middleware processing | +| **2200 - 2299** | **Network Errors** | Errors related to network operations | +| **2300 - 2399** | **Queue Errors** | Errors related to queuing systems | +| **2400 - 2499** | **Routing Errors** | Errors related to routing and HTTP methods | +| **2500 - 2599** | **Runtime Errors** | General runtime errors | +| **2600 - 2699** | **Encryption Errors** | Errors related to encryption and decryption | +| **2700 - 2799** | **Security Errors** | Errors related to security, access control, etc. | +| **2800 - 2899** | **Session Errors** | Errors related to session handling | +| **2900 - 2999** | **System Errors** | Errors related to system resources and environment | +| **3000 - 3099** | **Template Errors** | Errors related to template rendering and loading | +| **3100 - 3199** | **Validation Errors** | Errors related to data validation | +| **4000 - 4099** | **Business Logic Errors** | Custom errors for business logic violations | + +### Explanation of Each Range: + +1. **1000 - 1099: Authentication Errors** + + - Errors related to user authentication, such as invalid credentials, locked accounts, or missing two-factor authentication. + +2. **1100 - 1199: Authorization Errors** + + - Errors related to insufficient permissions or missing roles during authorization processes. + +3. **... (Same as previous ranges)** + +4. **3100 - 3199: Validation Errors** + + - Errors related to data validation. + +5. **4000 - 4099: Business Logic Errors** + - Custom error codes for business logic violations specific to your application. + +This structure allows you to easily categorize and expand error codes in the future, keeping the error-handling system organized. + +## Available Exception Types + +Each exception type is designed to handle specific error scenarios. For detailed information on each exception type, please refer to the [documentation](https://kariricode.org/docs/exception). + +## Integration with Other KaririCode Components + +The Exception component is designed to work seamlessly with other KaririCode components: + +- **KaririCode\Logger**: For advanced error logging and reporting. +- **KaririCode\Http**: For handling HTTP-related exceptions. +- **KaririCode\Database**: For database-specific exceptions. + +## Development and Testing + +For development and testing purposes, this package uses Docker and Docker Compose to ensure consistency across different environments. A Makefile is provided for convenience. + +### Prerequisites + +- Docker +- Docker Compose +- Make (optional, but recommended for easier command execution) + +### Development Setup + +1. Clone the repository: + + ```bash + git clone https://github.com/KaririCode-Framework/kariricode-exception.git + cd kariricode-exception + ``` + +2. Set up the environment: + + ```bash + make setup-env + ``` + +3. Start the Docker containers: + + ```bash + make up + ``` + +4. Install dependencies: + + ```bash + make composer-install + ``` + +### Available Make Commands + +- `make up`: Start all services in the background +- `make down`: Stop and remove all containers +- `make build`: Build Docker images +- `make shell`: Access the PHP container shell +- `make test`: Run tests +- `make coverage`: Run test coverage with visual formatting +- `make cs-fix`: Run PHP CS Fixer to fix code style +- `make quality`: Run all quality commands (cs-check, test, security-check) + +For a full list of available commands, run: + +```bash +make help +``` + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. + +## Support and Community + +- **Documentation**: [https://kariricode.org/docs/exception](https://kariricode.org/docs/exception) +- **Issue Tracker**: [GitHub Issues](https://github.com/KaririCode-Framework/kariricode-exception/issues) +- **Community**: [KaririCode Club Community](https://kariricode.club) + +--- + +Built with ❤️ by the KaririCode team. Empowering developers to handle errors effectively and build more resilient PHP applications. diff --git a/README.pt-br.md b/README.pt-br.md new file mode 100644 index 0000000..f5bfd30 --- /dev/null +++ b/README.pt-br.md @@ -0,0 +1,693 @@ +# KaririCode Framework: Exception Component + +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) + +![PHP](https://img.shields.io/badge/PHP-777BB4?style=for-the-badge&logo=php&logoColor=white) ![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white) ![PHPUnit](https://img.shields.io/badge/PHPUnit-3776AB?style=for-the-badge&logo=php&logoColor=white) + +Um componente abrangente e flexível de tratamento de exceções para PHP, parte do KaririCode Framework. Ele fornece uma abordagem estruturada para o gerenciamento de erros, melhorando a robustez e a manutenção das suas aplicações. + +## Índice + +- [Funcionalidades](#funcionalidades) +- [Instalação](#instalação) +- [Uso](#uso) + - [Uso Básico](#uso-básico) + - [Uso Avançado](#uso-avançado) +- [Tabela de Faixas de Código de Erro](#tabela-de-faixas-de-código-de-erro) +- [Tipos de Exceção Disponíveis](#tipos-de-exceção-disponíveis) +- [Integração com Outros Componentes do KaririCode](#integração-com-outros-componentes-do-kariricode) +- [Desenvolvimento e Testes](#desenvolvimento-e-testes) +- [Licença](#licença) +- [Suporte e Comunidade](#suporte-e-comunidade) + +## Funcionalidades + +- Estrutura hierárquica de exceções para melhor categorização de erros +- Exceções conscientes de contexto para informações de erro mais ricas +- Métodos de fábrica estáticos para fácil criação de exceções +- Integração com os sistemas de tratamento de erros e logs do KaririCode +- Arquitetura extensível permitindo tipos de exceção personalizados +- Conjunto abrangente de tipos de exceção pré-definidos para cenários comuns + +## Instalação + +Você pode instalar o componente de Exceção via Composer: + +```bash +composer require kariricode/exception +``` + +### Requisitos + +- PHP 8.1 ou superior +- Composer + +## Uso + +### Uso Básico + +#### Usando Exceções Pré-definidas no Seu Código + +O componente KaririCode Exception oferece uma variedade de exceções pré-definidas que você pode usar para lidar com cenários comuns de erro de maneira profissional e estruturada. Abaixo está um exemplo de como usar essas exceções em um contexto orientado a objetos. + +```php +getAttribute('userId'); + + $userData = $this->userService->getUserData($userId); + return $this->responseBuilder($response) + ->setData($userData) + ->setHeader('Content-Type', 'application/json') + ->setStatus(200) + ->build(); + } +} + +// UserService.php +namespace YourApp\Service; + +use YourApp\Repository\UserRepository; +use KaririCode\Contract\Log\Logger; + +class UserService +{ + private UserRepository $userRepository; + private Logger $logger; + + public function __construct(UserRepository $userRepository, Logger $logger) + { + $this->userRepository = $userRepository; + $this->logger = $logger; + } + + public function getUserData(int $userId): array + { + return $this->userRepository->findUserById($userId); + } +} + +// UserRepository.php +namespace YourApp\Repository; + +use KaririCode\Contract\Database\EntityManager; +use KaririCode\Exception\Database\DatabaseException; + +class UserRepository +{ + private EntityManager $entityManager; + + public function __construct(EntityManager $entityManager) + { + $this->entityManager = $entityManager; + } + + public function findUserById(int $userId): array + { + $sql = 'SELECT * FROM users WHERE id = ?'; + $userData = $this->entityManager->query($sql, [$userId]); + + if ($userData === false) { + throw DatabaseException::queryError($sql, $this->entityManager->getLastError()); + } + + return $userData; + } +} + +``` + +### Uso Avançado + +Crie exceções personalizadas estendendo as classes base: + +```php +orderRepository->getUserOrderLimit($userId); + + if ($totalAmount > $userOrderLimit) { + $this->logger->warning('Pedido excede o limite do usuário', [ + 'userId' => $userId, + 'orderAmount' => $totalAmount, + 'userLimit' => $userOrderLimit, + ]); + + throw OrderException::orderLimitExceeded($totalAmount, $userOrderLimit); + } + + $this->orderRepository->createOrder($userId, $items, $totalAmount); + + } +} +``` + +## Tabela de Faixas de Código de Erro + +Aqui está uma tabela proposta para as **faixas de código de erro**. Cada faixa é atribuída a um grupo de erros relacionados, permitindo melhor organização e identificação de erros no sistema. + +### Tabela de Faixas de Código de Erro + +| Faixa | Grupo de Erro | Descrição | +| --------------- | -------------------------------- | ------------------------------------------------------- | +| **1000 - 1099** | **Erros de Autenticação** | Erros relacionados à autenticação e login | +| **1100 - 1199** | **Erros de Autorização** | Erros relacionados a permissões e funções | +| **1200 - 1299** | **Erros de Cache** | Erros relacionados a operações de cache | +| **1300 - 1399** | **Erros de Configuração** | Erros relacionados a configurações | +| **1400 - 1499** | **Erros de Container** | Erros relacionados à injeção de dependências e serviços | +| **1500 - 1599** | **Erros de Banco de Dados** | Erros relacionados a conexões, consultas, etc. | +| **1600 - 1699** | **Erros de Evento** | Erros relacionados ao manuseio e despacho de eventos | +| **1700 - 1799** | **Erros de Serviços Externos** | Erros relacionados a chamadas e serviços externos | +| **1800 - 1899** | **Erros de Sistema de Arquivos** | Erros relacionados a operações de arquivos | +| **1900 - 1999** | **Erros de Validação/Entrada** | Erros relacionados a validação ou entrada inválida | +| **2000 - 2099** | **Erros de Localização** | Erros relacionados à localização e traduções | +| **2100 - 2199** | **Erros de Middleware** | Erros relacionados ao processamento de middleware | +| **2200 - 2299** | **Erros de Rede** | Erros relacionados a operações de rede | +| **2300 - 2399** | **Erros de Fila** | Erros relacionados a sistemas de fila | +| **2400 - 2499** | **Erros de Roteamento** | Erros relacionados a roteamento e métodos HTTP | + +| **2500 - 2599** | **Erros de Tempo de Execução** | Erros gerais de tempo de execução | +| **2600 - 2699** | **Erros de Criptografia** | Erros relacionados a criptografia e descriptografia | +| **2700 - 2799** | **Erros de Segurança** | Erros relacionados à segurança e controle de acesso | +| **2800 - 2899** | **Erros de Sessão** | Erros relacionados ao gerenciamento de sessões | +| **2900 - 2999** | **Erros de Sistema** | Erros relacionados a recursos do sistema e ambiente | +| **3000 - 3099** | **Erros de Template** | Erros relacionados a renderização e carregamento de templates | +| **3100 - 3199** | **Erros de Validação** | Erros relacionados à validação de dados | +| **4000 - 4099** | **Erros de Lógica de Negócios** | Erros personalizados para violações de lógica de negócios | + +### Explicação de Cada Faixa: + +1. **1000 - 1099: Erros de Autenticação** + + - Erros relacionados à autenticação do usuário, como credenciais inválidas, contas bloqueadas ou autenticação de dois fatores ausente. + +2. **1100 - 1199: Erros de Autorização** + + - Erros relacionados a permissões insuficientes ou funções ausentes durante processos de autorização. + +3. **... (Mesma descrição das faixas anteriores)** + +4. **3100 - 3199: Erros de Validação** + + - Erros relacionados à validação de dados. + +5. **4000 - 4099: Erros de Lógica de Negócios** + - Códigos de erro personalizados para violações de lógica de negócios específicas da sua aplicação. + +Essa estrutura permite que você categorize e expanda facilmente os códigos de erro no futuro, mantendo o sistema de tratamento de erros organizado. + +## Tipos de Exceção Disponíveis + +Cada tipo de exceção é projetado para lidar com cenários específicos de erro. Para informações detalhadas sobre cada tipo de exceção, consulte a [documentação](https://kariricode.org/docs/exception). + +## Integração com Outros Componentes do KaririCode + +O componente de Exceção foi projetado para funcionar perfeitamente com outros componentes do KaririCode: + +- **KaririCode\Logger**: Para logs e relatórios de erros avançados. +- **KaririCode\Http**: Para tratamento de exceções relacionadas a HTTP. +- **KaririCode\Database**: Para exceções específicas de banco de dados. + +## Desenvolvimento e Testes + +Para fins de desenvolvimento e testes, este pacote utiliza Docker e Docker Compose para garantir consistência entre diferentes ambientes. Um Makefile é fornecido para conveniência. + +### Pré-requisitos + +- Docker +- Docker Compose +- Make (opcional, mas recomendado para facilitar a execução de comandos) + +### Configuração de Desenvolvimento + +1. Clone o repositório: + + ```bash + git clone https://github.com/KaririCode-Framework/kariricode-exception.git + cd kariricode-exception + ``` + +2. Configure o ambiente: + + ```bash + make setup-env + ``` + +3. Inicie os containers do Docker: + + ```bash + make up + ``` + +4. Instale as dependências: + + ```bash + make composer-install + ``` + +### Comandos Make Disponíveis + +- `make up`: Inicia todos os serviços em segundo plano +- `make down`: Para e remove todos os containers +- `make build`: Constrói as imagens Docker +- `make shell`: Acessa o shell do container PHP +- `make test`: Executa os testes +- `make coverage`: Executa a cobertura dos testes com formatação visual +- `make cs-fix`: Executa o PHP CS Fixer para corrigir o estilo do código +- `make quality`: Executa todos os comandos de qualidade (cs-check, test, security-check) + +Para uma lista completa de comandos disponíveis, execute: + +```bash +make help +``` + +## Licença + +Este projeto é licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para mais detalhes. + +## Suporte e Comunidade + +- **Documentação**: [https://kariricode.org/docs/exception](https://kariricode.org/docs/exception) +- **Rastreador de Problemas**: [GitHub Issues](https://github.com/KaririCode-Framework/kariricode-exception/issues) +- **Comunidade**: [KaririCode Club Community](https://kariricode.club) + +--- + +Desenvolvido com ❤️ pela equipe KaririCode. Capacitando desenvolvedores a lidar com erros de forma eficaz e construir aplicações PHP mais resilientes.Aqui está o README traduzido para o português: + +--- + +# KaririCode Framework: Componente de Exceções + +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![pt-br](https://img.shields.io/badge/lang-pt--br-green.svg)](README.pt-br.md) + +![PHP](https://img.shields.io/badge/PHP-777BB4?style=for-the-badge&logo=php&logoColor=white) ![Docker](https://img.shields.io/badge/Docker-2496ED?style=for-the-badge&logo=docker&logoColor=white) ![PHPUnit](https://img.shields.io/badge/PHPUnit-3776AB?style=for-the-badge&logo=php&logoColor=white) + +Um componente abrangente e flexível de tratamento de exceções para PHP, parte do KaririCode Framework. Ele fornece uma abordagem estruturada para o gerenciamento de erros, melhorando a robustez e a manutenção das suas aplicações. + +## Índice + +- [Funcionalidades](#funcionalidades) +- [Instalação](#instalação) +- [Uso](#uso) + - [Uso Básico](#uso-básico) + - [Uso Avançado](#uso-avançado) +- [Tabela de Faixas de Código de Erro](#tabela-de-faixas-de-código-de-erro) +- [Tipos de Exceção Disponíveis](#tipos-de-exceção-disponíveis) +- [Integração com Outros Componentes do KaririCode](#integração-com-outros-componentes-do-kariricode) +- [Desenvolvimento e Testes](#desenvolvimento-e-testes) +- [Licença](#licença) +- [Suporte e Comunidade](#suporte-e-comunidade) + +## Funcionalidades + +- Estrutura hierárquica de exceções para melhor categorização de erros +- Exceções conscientes de contexto para informações de erro mais ricas +- Métodos de fábrica estáticos para fácil criação de exceções +- Integração com os sistemas de tratamento de erros e logs do KaririCode +- Arquitetura extensível permitindo tipos de exceção personalizados +- Conjunto abrangente de tipos de exceção pré-definidos para cenários comuns + +## Instalação + +Você pode instalar o componente de Exceção via Composer: + +```bash +composer require kariricode/exception +``` + +### Requisitos + +- PHP 8.1 ou superior +- Composer + +## Uso + +### Uso Básico + +#### Usando Exceções Pré-definidas no Seu Código + +O componente KaririCode Exception oferece uma variedade de exceções pré-definidas que você pode usar para lidar com cenários comuns de erro de maneira profissional e estruturada. Abaixo está um exemplo de como usar essas exceções em um contexto orientado a objetos. + +```php +getAttribute('userId'); + + $userData = $this->userService->getUserData($userId); + return $this->responseBuilder($response) + ->setData($userData) + ->setHeader('Content-Type', 'application/json') + ->setStatus(200) + ->build(); + } +} + +// UserService.php +namespace YourApp\Service; + +use YourApp\Repository\UserRepository; +use KaririCode\Contract\Log\Logger; + +class UserService +{ + private UserRepository $userRepository; + private Logger $logger; + + public function __construct(UserRepository $userRepository, Logger $logger) + { + $this->userRepository = $userRepository; + $this->logger = $logger; + } + + public function getUserData(int $userId): array + { + return $this->userRepository->findUserById($userId); + } +} + +// UserRepository.php +namespace YourApp\Repository; + +use KaririCode\Contract\Database\EntityManager; +use KaririCode\Exception\Database\DatabaseException; + +class UserRepository +{ + private EntityManager $entityManager; + + public function __construct(EntityManager $entityManager) + { + $this->entityManager = $entityManager; + } + + public function findUserById(int $userId): array + { + $sql = 'SELECT * FROM users WHERE id = ?'; + $userData = $this->entityManager->query($sql, [$userId]); + + if ($userData === false) { + throw DatabaseException::queryError($sql, $this->entityManager->getLastError()); + } + + return $userData; + } +} + +``` + +### Uso Avançado + +Crie exceções personalizadas estendendo as classes base: + +```php +orderRepository->getUserOrderLimit($userId); + + if ($totalAmount > $userOrderLimit) { + $this->logger->warning('Pedido excede o limite do usuário', [ + 'userId' => $userId, + 'orderAmount' => $totalAmount, + 'userLimit' => $userOrderLimit, + ]); + + throw OrderException::orderLimitExceeded($totalAmount, $userOrderLimit); + } + + $this->orderRepository->createOrder($userId, $items, $totalAmount); + + } +} +``` + +## Tabela de Faixas de Código de Erro + +Aqui está uma tabela proposta para as **faixas de código de erro**. Cada faixa é atribuída a um grupo de erros relacionados, permitindo melhor organização e identificação de erros no sistema. + +### Tabela de Faixas de Código de Erro + +| Faixa | Grupo de Erro | Descrição | +| --------------- | -------------------------------- | ------------------------------------------------------- | +| **1000 - 1099** | **Erros de Autenticação** | Erros relacionados à autenticação e login | +| **1100 - 1199** | **Erros de Autorização** | Erros relacionados a permissões e funções | +| **1200 - 1299** | **Erros de Cache** | Erros relacionados a operações de cache | +| **1300 - 1399** | **Erros de Configuração** | Erros relacionados a configurações | +| **1400 - 1499** | **Erros de Container** | Erros relacionados à injeção de dependências e serviços | +| **1500 - 1599** | **Erros de Banco de Dados** | Erros relacionados a conexões, consultas, etc. | +| **1600 - 1699** | **Erros de Evento** | Erros relacionados ao manuseio e despacho de eventos | +| **1700 - 1799** | **Erros de Serviços Externos** | Erros relacionados a chamadas e serviços externos | +| **1800 - 1899** | **Erros de Sistema de Arquivos** | Erros relacionados a operações de arquivos | +| **1900 - 1999** | **Erros de Validação/Entrada** | Erros relacionados a validação ou entrada inválida | +| **2000 - 2099** | **Erros de Localização** | Erros relacionados à localização e traduções | +| **2100 - 2199** | **Erros de Middleware** | Erros relacionados ao processamento de middleware | +| **2200 - 2299** | **Erros de Rede** | Erros relacionados a operações de rede | +| **2300 - 2399** | **Erros de Fila** | Erros relacionados a sistemas de fila | +| **2400 - 2499** | **Erros de Roteamento** | Erros relacionados a roteamento e métodos HTTP | + +| **2500 - 2599** | **Erros de Tempo de Execução** | Erros gerais de tempo de execução | +| **2600 - 2699** | **Erros de Criptografia** | Erros relacionados a criptografia e descriptografia | +| **2700 - 2799** | **Erros de Segurança** | Erros relacionados à segurança e controle de acesso | +| **2800 - 2899** | **Erros de Sessão** | Erros relacionados ao gerenciamento de sessões | +| **2900 - 2999** | **Erros de Sistema** | Erros relacionados a recursos do sistema e ambiente | +| **3000 - 3099** | **Erros de Template** | Erros relacionados a renderização e carregamento de templates | +| **3100 - 3199** | **Erros de Validação** | Erros relacionados à validação de dados | +| **4000 - 4099** | **Erros de Lógica de Negócios** | Erros personalizados para violações de lógica de negócios | + +### Explicação de Cada Faixa: + +1. **1000 - 1099: Erros de Autenticação** + + - Erros relacionados à autenticação do usuário, como credenciais inválidas, contas bloqueadas ou autenticação de dois fatores ausente. + +2. **1100 - 1199: Erros de Autorização** + + - Erros relacionados a permissões insuficientes ou funções ausentes durante processos de autorização. + +3. **... (Mesma descrição das faixas anteriores)** + +4. **3100 - 3199: Erros de Validação** + + - Erros relacionados à validação de dados. + +5. **4000 - 4099: Erros de Lógica de Negócios** + - Códigos de erro personalizados para violações de lógica de negócios específicas da sua aplicação. + +Essa estrutura permite que você categorize e expanda facilmente os códigos de erro no futuro, mantendo o sistema de tratamento de erros organizado. + +## Tipos de Exceção Disponíveis + +Cada tipo de exceção é projetado para lidar com cenários específicos de erro. Para informações detalhadas sobre cada tipo de exceção, consulte a [documentação](https://kariricode.org/docs/exception). + +## Integração com Outros Componentes do KaririCode + +O componente de Exceção foi projetado para funcionar perfeitamente com outros componentes do KaririCode: + +- **KaririCode\Logger**: Para logs e relatórios de erros avançados. +- **KaririCode\Http**: Para tratamento de exceções relacionadas a HTTP. +- **KaririCode\Database**: Para exceções específicas de banco de dados. + +## Desenvolvimento e Testes + +Para fins de desenvolvimento e testes, este pacote utiliza Docker e Docker Compose para garantir consistência entre diferentes ambientes. Um Makefile é fornecido para conveniência. + +### Pré-requisitos + +- Docker +- Docker Compose +- Make (opcional, mas recomendado para facilitar a execução de comandos) + +### Configuração de Desenvolvimento + +1. Clone o repositório: + + ```bash + git clone https://github.com/KaririCode-Framework/kariricode-exception.git + cd kariricode-exception + ``` + +2. Configure o ambiente: + + ```bash + make setup-env + ``` + +3. Inicie os containers do Docker: + + ```bash + make up + ``` + +4. Instale as dependências: + + ```bash + make composer-install + ``` + +### Comandos Make Disponíveis + +- `make up`: Inicia todos os serviços em segundo plano +- `make down`: Para e remove todos os containers +- `make build`: Constrói as imagens Docker +- `make shell`: Acessa o shell do container PHP +- `make test`: Executa os testes +- `make coverage`: Executa a cobertura dos testes com formatação visual +- `make cs-fix`: Executa o PHP CS Fixer para corrigir o estilo do código +- `make quality`: Executa todos os comandos de qualidade (cs-check, test, security-check) + +Para uma lista completa de comandos disponíveis, execute: + +```bash +make help +``` + +## Licença + +Este projeto é licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para mais detalhes. + +## Suporte e Comunidade + +- **Documentação**: [https://kariricode.org/docs/exception](https://kariricode.org/docs/exception) +- **Rastreador de Problemas**: [GitHub Issues](https://github.com/KaririCode-Framework/kariricode-exception/issues) +- **Comunidade**: [KaririCode Club Community](https://kariricode.club) + +--- + +Desenvolvido com ❤️ pela equipe KaririCode. Capacitando desenvolvedores a lidar com erros de forma eficaz e construir aplicações PHP mais resilientes. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5a4595e --- /dev/null +++ b/composer.json @@ -0,0 +1,46 @@ +{ + "name": "kariricode/exception", + "description": "KaririCode Exception provides a robust and modular exception handling system for the KaririCode Framework, enabling seamless error management across various application domains.", + "keywords": [ + "kariri-code", + "framework", + "exception-handling", + "error-management", + "php-framework", + "modular-exceptions", + "php-exceptions" + ], + "homepage": "https://kariricode.org", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Walmir Silva", + "email": "community@kariricode.org" + } + ], + "require": { + "php": "^8.3" + }, + "autoload": { + "psr-4": { + "KaririCode\\Exception\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "KaririCode\\Exception\\Tests\\": "tests/" + } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.51", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^11.0", + "squizlabs/php_codesniffer": "^3.9", + "enlightn/security-checker": "^2.0" + }, + "support": { + "issues": "https://github.com/KaririCode-Framework/kariricode-exception/issues", + "source": "https://github.com/KaririCode-Framework/kariricode-exception" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..b09d292 --- /dev/null +++ b/composer.lock @@ -0,0 +1,4921 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2067995ac608af769ccf68461bd91e53", + "packages": [], + "packages-dev": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.11.10", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.1" + }, + "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-08-27T18:44:43+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "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": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "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": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "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" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "enlightn/security-checker", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/enlightn/security-checker.git", + "reference": "d495ab07639388c7c770c5223aa0d42fee1d2604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/enlightn/security-checker/zipball/d495ab07639388c7c770c5223aa0d42fee1d2604", + "reference": "d495ab07639388c7c770c5223aa0d42fee1d2604", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^6.3|^7.0", + "php": ">=8.2", + "symfony/console": "^7", + "symfony/finder": "^3|^4|^5|^6|^7", + "symfony/process": "^3.4|^4|^5|^6|^7", + "symfony/yaml": "^3.4|^4|^5|^6|^7" + }, + "require-dev": { + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^2.18|^3.0", + "phpunit/phpunit": "^5.5|^6|^7|^8|^9" + }, + "bin": [ + "security-checker" + ], + "type": "library", + "autoload": { + "psr-4": { + "Enlightn\\SecurityChecker\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paras Malhotra", + "email": "paras@laravel-enlightn.com" + }, + { + "name": "Miguel Piedrafita", + "email": "soy@miguelpiedrafita.com" + } + ], + "description": "A PHP dependency vulnerabilities scanner based on the Security Advisories Database.", + "keywords": [ + "package", + "php", + "scanner", + "security", + "security advisories", + "vulnerability scanner" + ], + "support": { + "issues": "https://github.com/enlightn/security-checker/issues", + "source": "https://github.com/enlightn/security-checker/tree/v2.0.0" + }, + "time": "2023-12-10T07:17:09+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "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", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.64.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "58dd9c931c785a79739310aef5178928305ffa67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67", + "reference": "58dd9c931c785a79739310aef5178928305ffa67", + "shasum": "" + }, + "require": { + "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.0", + "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": { + "facile-it/paraunit": "^1.3 || ^2.3", + "infection/infection": "^0.29.5", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "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.19 || ^10.5.21 || ^11.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-08-30T23:09:38+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "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" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "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": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2024-07-24T11:22:20+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "reference": "6ea8dd08867a2a42619d65c3deb2c0fcbf81c8f8", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "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": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2024-07-18T10:29:17+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.7.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2024-07-18T11:15:46+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "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", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-06-12T14:39:25+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + }, + "time": "2024-10-08T18:51:32+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": "phpstan/phpstan", + "version": "1.12.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc4d2f145a88ea7141ae698effd64d9df46527ae", + "reference": "dc4d2f145a88ea7141ae698effd64d9df46527ae", + "shasum": "" + }, + "require": { + "php": "^7.2|^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-10-06T15:03:59+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "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.4.1" + }, + "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.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T06:21:38+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.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7875627f15f4da7e7f0823d1f323f7295a77334e", + "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.6", + "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.1.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.4-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.4.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-10-08T15:38:37+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/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+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": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+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.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "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": "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:44:28+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "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.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d", + "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^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": "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.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-11T15:42:56+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.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.2" + }, + "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.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:56:19+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/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "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": "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/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.10.3", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "62d32998e820bddc40f99f8251958aed187a5c9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/62d32998e820bddc40f99f8251958aed187a5c9c", + "reference": "62d32998e820bddc40f99f8251958aed187a5c9c", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-09-18T10:38:58+00:00" + }, + { + "name": "symfony/console", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee", + "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": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "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.1.5" + }, + "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-20T08:28:38+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.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-04-18T09:32:20+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7", + "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.1.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-05-31T14:57:53+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "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": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.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-04-18T09:32:20+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a", + "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a", + "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": { + "source": "https://github.com/symfony/filesystem/tree/v7.1.5" + }, + "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-17T09:16:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.1.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", + "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.1.4" + }, + "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-08-13T14:28:19+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "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 an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.1.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-05-31T14:57:53+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.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-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "5c03ee6369281177f07f7c68252a280beccba847" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847", + "reference": "5c03ee6369281177f07f7c68252a280beccba847", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.1.5" + }, + "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-19T21:48:23+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.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-04-18T09:32:20+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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 a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.1.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-05-31T14:57:53+00:00" + }, + { + "name": "symfony/string", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306", + "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306", + "shasum": "" + }, + "require": { + "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": { + "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", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "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": { + "source": "https://github.com/symfony/string/tree/v7.1.5" + }, + "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-20T08:28:38+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4", + "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.1.5" + }, + "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-17T12:49:58+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "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" + } + ], + "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.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^8.3" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7dc18f1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + php: + container_name: kariricode-exception + build: + context: . + dockerfile: .docker/php/Dockerfile + args: + PHP_VERSION: ${KARIRI_PHP_VERSION} + environment: + XDEBUG_MODE: coverage + volumes: + - .:/app + working_dir: /app + ports: + - "${KARIRI_PHP_PORT}:9003" diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..07143a4 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + src/ + tests/ + + + vendor/* + config/* + tests/bootstrap.php + tests/object-manager.php + + diff --git a/phpinsights.php b/phpinsights.php new file mode 100644 index 0000000..5df088e --- /dev/null +++ b/phpinsights.php @@ -0,0 +1,60 @@ + 'symfony', + 'exclude' => [ + 'src/Migrations', + 'src/Kernel.php', + ], + 'add' => [], + 'remove' => [ + \PHP_CodeSniffer\Standards\Generic\Sniffs\Formatting\SpaceAfterNotSniff::class, + \NunoMaduro\PhpInsights\Domain\Sniffs\ForbiddenSetterSniff::class, + \SlevomatCodingStandard\Sniffs\Commenting\UselessFunctionDocCommentSniff::class, + \SlevomatCodingStandard\Sniffs\Commenting\DocCommentSpacingSniff::class, + \SlevomatCodingStandard\Sniffs\Classes\SuperfluousInterfaceNamingSniff::class, + \SlevomatCodingStandard\Sniffs\Classes\SuperfluousExceptionNamingSniff::class, + \SlevomatCodingStandard\Sniffs\ControlStructures\DisallowYodaComparisonSniff::class, + \NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits::class, + \NunoMaduro\PhpInsights\Domain\Insights\ForbiddenNormalClasses::class, + \SlevomatCodingStandard\Sniffs\Classes\SuperfluousTraitNamingSniff::class, + \SlevomatCodingStandard\Sniffs\Classes\ForbiddenPublicPropertySniff::class, + \NunoMaduro\PhpInsights\Domain\Insights\CyclomaticComplexityIsHigh::class, + \NunoMaduro\PhpInsights\Domain\Insights\ForbiddenDefineFunctions::class, + \NunoMaduro\PhpInsights\Domain\Insights\ForbiddenFinalClasses::class, + \NunoMaduro\PhpInsights\Domain\Insights\ForbiddenGlobals::class, + \PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\FunctionCommentSniff::class, + \SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSniff::class, + \SlevomatCodingStandard\Sniffs\Commenting\InlineDocCommentDeclarationSniff::class, + \SlevomatCodingStandard\Sniffs\Classes\ModernClassNameReferenceSniff::class, + \PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\UselessOverridingMethodSniff::class, + \SlevomatCodingStandard\Sniffs\TypeHints\DeclareStrictTypesSniff::class, + \SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff::class, + \SlevomatCodingStandard\Sniffs\TypeHints\PropertyTypeHintSniff::class, + \SlevomatCodingStandard\Sniffs\Arrays\TrailingArrayCommaSniff::class + ], + 'config' => [ + \PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff::class => [ + 'lineLimit' => 120, + 'absoluteLineLimit' => 160, + ], + \SlevomatCodingStandard\Sniffs\Commenting\InlineDocCommentDeclarationSniff::class => [ + 'exclude' => [ + 'src/Exception/BaseException.php', + ], + ], + \SlevomatCodingStandard\Sniffs\ControlStructures\AssignmentInConditionSniff::class => [ + 'enabled' => false, + ], + ], + 'requirements' => [ + 'min-quality' => 80, + 'min-complexity' => 50, + 'min-architecture' => 75, + 'min-style' => 95, + 'disable-security-check' => false, + ], + 'threads' => null +]; diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..c3392e9 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,7 @@ +parameters: + level: max + paths: + - src + - tests + ignoreErrors: + - '#Method .* has parameter \$.* with no value type specified in iterable type array.#' diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..ba8e7af --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + tests + + + + + + src + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..f0c90a3 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/script.php b/script.php new file mode 100644 index 0000000..6db59dd --- /dev/null +++ b/script.php @@ -0,0 +1,142 @@ +createForNewestSupportedVersion(); + + try { + $ast = $parser->parse($code); + } catch (Error $error) { + echo "Erro ao analisar o arquivo {$filePath}: {$error->getMessage()}\n"; + return; + } + + $traverser = new NodeTraverser(); + + // Adicionar NameResolver + $traverser->addVisitor(new NameResolver()); + + // Adicionar ParentConnectingVisitor + $traverser->addVisitor(new ParentConnectingVisitor()); + + $visitor = new class ($codeMapping) extends NodeVisitorAbstract { + private $codeMapping; + private $currentClass; + private $classNode; + + public function __construct(array $codeMapping) + { + $this->codeMapping = $codeMapping; + } + + public function enterNode(Node $node) + { + if ($node instanceof Node\Stmt\Class_) { + if (isset($node->namespacedName)) { + $this->currentClass = $node->namespacedName->toString(); + } else { + $this->currentClass = $node->name->toString(); + } + $this->classNode = $node; + } + + if ($node instanceof Node\Stmt\ClassMethod && $node->isStatic()) { + if ($this->currentClass && isset($this->codeMapping[$this->currentClass])) { + $methodName = $node->name->toString(); + if (isset($this->codeMapping[$this->currentClass][$methodName])) { + $codeInt = $this->codeMapping[$this->currentClass][$methodName]; + + // Adicionar a constante de código inteiro na classe, se ainda não existir + $constName = 'CODE_' . strtoupper($methodName); + + // Verificar se a constante já existe + $constExists = false; + foreach ($this->classNode->stmts as $stmt) { + if ($stmt instanceof Node\Stmt\ClassConst) { + foreach ($stmt->consts as $const) { + if ($const->name->toString() === $constName) { + $constExists = true; + break 2; + } + } + } + } + + if (!$constExists) { + $const = new Node\Stmt\ClassConst( + [ + new Node\Const_( + new Node\Identifier($constName), + new Int_($codeInt) + ) + ], + Modifiers::PRIVATE + ); + + // Inserir a constante no início dos statements da classe + array_unshift($this->classNode->stmts, $const); + } + } + } + } + } + }; + + $traverser->addVisitor($visitor); + $modifiedAst = $traverser->traverse($ast); + + // Converter o AST de volta para código PHP + $prettyPrinter = new PrettyPrinter\Standard(); + $modifiedCode = $prettyPrinter->prettyPrintFile($modifiedAst); + + // Salvar o código modificado de volta no arquivo + file_put_contents($filePath, $modifiedCode); + echo "Arquivo atualizado: {$filePath}\n"; +} + +// Iniciar o processo de varredura +scanDirectory($baseDir, $codeMapping); + +echo "Atualização concluída.\n"; diff --git a/src/AbstractException.php b/src/AbstractException.php new file mode 100644 index 0000000..2a1de1f --- /dev/null +++ b/src/AbstractException.php @@ -0,0 +1,39 @@ +errorCode = $errorMessage->getErrorCode(); + $this->context = array_merge(['code' => $this->errorCode], $context); + + parent::__construct($errorMessage->getMessage(), $errorMessage->getCode(), $previous); + } + + public function getContext(): array + { + return $this->context; + } + + public function getErrorCode(): string + { + return $this->errorCode; + } + + protected function addContext(string $key, mixed $value): self + { + $this->context[$key] = $value; + + return $this; + } +} diff --git a/src/Auth/AuthenticationException.php b/src/Auth/AuthenticationException.php new file mode 100644 index 0000000..33a2383 --- /dev/null +++ b/src/Auth/AuthenticationException.php @@ -0,0 +1,42 @@ +code; + } + + public function getErrorCode(): string + { + return $this->errorCode; + } + + public function getMessage(): string + { + return $this->message; + } +} diff --git a/src/ExternalService/ExternalServiceException.php b/src/ExternalService/ExternalServiceException.php new file mode 100644 index 0000000..c7d9bed --- /dev/null +++ b/src/ExternalService/ExternalServiceException.php @@ -0,0 +1,42 @@ +validationErrors[$field][] = $errorMessage; + + return $this; + } + + public function getValidationErrors(): array + { + return $this->validationErrors; + } +} diff --git a/tests/AbstractExceptionTest.php b/tests/AbstractExceptionTest.php new file mode 100644 index 0000000..82d9d49 --- /dev/null +++ b/tests/AbstractExceptionTest.php @@ -0,0 +1,76 @@ +exception = new ConcreteTestException($errorMessage); + } + + public function testExceptionCreation(): void + { + $this->assertSame('Test message', $this->exception->getMessage()); + $this->assertSame(['code' => 'TEST_CODE'], $this->exception->getContext()); + $this->assertSame('TEST_CODE', $this->exception->getErrorCode()); + $this->assertSame(9999, $this->exception->getCode()); + } + + public function testExceptionWithContext(): void + { + $errorMessage = new ExceptionMessage(9999, 'TEST_CODE', 'Test message'); + $context = ['key' => 'value']; + $exception = new ConcreteTestException($errorMessage, null, $context); + + $this->assertSame(['code' => 'TEST_CODE', 'key' => 'value'], $exception->getContext()); + $this->assertSame('TEST_CODE', $exception->getErrorCode()); + $this->assertSame(9999, $exception->getCode()); + } + + public function testAddContext(): void + { + $this->exception->addTestContext('newKey', 'newValue'); + + $expectedContext = ['code' => 'TEST_CODE', 'newKey' => 'newValue']; + $this->assertSame($expectedContext, $this->exception->getContext()); + } + + public function testExceptionWithPrevious(): void + { + $previousException = new \Exception('Previous exception'); + $errorMessage = new ExceptionMessage(9999, 'TEST_CODE', 'Test message'); + $exception = new ConcreteTestException($errorMessage, $previousException); + + $this->assertSame($previousException, $exception->getPrevious()); + $this->assertSame(9999, $exception->getCode()); + } + + protected function assertExceptionStructure(AbstractException $exception, string $expectedErrorCode, string $expectedMessage, int $expectedCode): void + { + $this->assertInstanceOf(AbstractException::class, $exception); + $this->assertSame($expectedMessage, $exception->getMessage()); + $this->assertArrayHasKey('code', $exception->getContext()); + $this->assertSame($expectedErrorCode, $exception->getContext()['code']); + $this->assertSame($expectedErrorCode, $exception->getErrorCode()); + $this->assertSame($expectedCode, $exception->getCode()); + } +} + +// Implementação concreta de AbstractException para teste +final class ConcreteTestException extends AbstractException +{ + public function addTestContext(string $key, mixed $value): self + { + return $this->addContext($key, $value); + } +} diff --git a/tests/Auth/AuthenticationExceptionTest.php b/tests/Auth/AuthenticationExceptionTest.php new file mode 100644 index 0000000..ebd30d2 --- /dev/null +++ b/tests/Auth/AuthenticationExceptionTest.php @@ -0,0 +1,29 @@ +assertExceptionStructure($exception, 'INVALID_CREDENTIALS', 'Invalid credentials provided', 1001); + } + + public function testAccountLocked(): void + { + $exception = AuthenticationException::accountLocked(); + $this->assertExceptionStructure($exception, 'ACCOUNT_LOCKED', 'Account is locked', 1002); + } + + public function testTwoFactorRequired(): void + { + $exception = AuthenticationException::twoFactorRequired(); + $this->assertExceptionStructure($exception, 'TWO_FACTOR_REQUIRED', 'Two-factor authentication is required', 1003); + } +} diff --git a/tests/Auth/AuthorizationExceptionTest.php b/tests/Auth/AuthorizationExceptionTest.php new file mode 100644 index 0000000..da2077b --- /dev/null +++ b/tests/Auth/AuthorizationExceptionTest.php @@ -0,0 +1,25 @@ +assertExceptionStructure($exception, 'INSUFFICIENT_PERMISSIONS', "Insufficient permissions for action: {$action}", 1101); + } + + public function testRoleRequired(): void + { + $role = 'admin'; + $exception = AuthorizationException::roleRequired($role); + $this->assertExceptionStructure($exception, 'ROLE_REQUIRED', "Required role not present: {$role}", 1102); + } +} diff --git a/tests/Cache/CacheExceptionTest.php b/tests/Cache/CacheExceptionTest.php new file mode 100644 index 0000000..bbab713 --- /dev/null +++ b/tests/Cache/CacheExceptionTest.php @@ -0,0 +1,32 @@ +assertExceptionStructure($exception, 'CACHE_ITEM_NOT_FOUND', "Cache item not found: {$key}", 1201); + } + + public function testStorageError(): void + { + $details = 'Redis connection failed'; + $exception = CacheException::storageError($details); + $this->assertExceptionStructure($exception, 'CACHE_STORAGE_ERROR', "Cache storage error: {$details}", 1202); + } + + public function testInvalidTtl(): void + { + $ttl = -1; + $exception = CacheException::invalidTtl($ttl); + $this->assertExceptionStructure($exception, 'INVALID_TTL', "Invalid TTL value: {$ttl}", 1203); + } +} diff --git a/tests/Config/ConfigurationExceptionTest.php b/tests/Config/ConfigurationExceptionTest.php new file mode 100644 index 0000000..1ea0741 --- /dev/null +++ b/tests/Config/ConfigurationExceptionTest.php @@ -0,0 +1,33 @@ +assertExceptionStructure($exception, 'MISSING_CONFIG_KEY', "Missing configuration key: {$key}", 1301); + } + + public function testInvalidValue(): void + { + $key = 'app.debug'; + $value = 'not_a_boolean'; + $exception = ConfigurationException::invalidValue($key, $value); + $this->assertExceptionStructure($exception, 'INVALID_CONFIG_VALUE', "Invalid configuration value for key '{$key}': " . var_export($value, true), 1302); + } + + public function testEnvironmentNotSet(): void + { + $envVar = 'APP_KEY'; + $exception = ConfigurationException::environmentNotSet($envVar); + $this->assertExceptionStructure($exception, 'ENVIRONMENT_NOT_SET', "Environment variable not set: {$envVar}", 1303); + } +} diff --git a/tests/Container/ContainerExceptionTest.php b/tests/Container/ContainerExceptionTest.php new file mode 100644 index 0000000..1827c3a --- /dev/null +++ b/tests/Container/ContainerExceptionTest.php @@ -0,0 +1,25 @@ +assertExceptionStructure($exception, 'SERVICE_NOT_FOUND', "Service not found in container: {$serviceId}", 1401); + } + + public function testCircularDependency(): void + { + $serviceId = 'App\Service\UserService'; + $exception = ContainerException::circularDependency($serviceId); + $this->assertExceptionStructure($exception, 'CIRCULAR_DEPENDENCY', "Circular dependency detected for service: {$serviceId}", 1402); + } +} diff --git a/tests/Database/DatabaseExceptionTest.php b/tests/Database/DatabaseExceptionTest.php new file mode 100644 index 0000000..7ed92a8 --- /dev/null +++ b/tests/Database/DatabaseExceptionTest.php @@ -0,0 +1,32 @@ +assertExceptionStructure($exception, 'DB_CONNECTION_ERROR', "Database connection error: {$details}", 1501); + } + + public function testQueryError(): void + { + $query = 'SELECT * FROM users'; + $error = 'Table "users" not found'; + $exception = DatabaseException::queryError($query, $error); + $this->assertExceptionStructure($exception, 'DB_QUERY_ERROR', "Database query error: {$error}", 1502); + } + + public function testDeadlockDetected(): void + { + $exception = DatabaseException::deadlockDetected(); + $this->assertExceptionStructure($exception, 'DB_DEADLOCK', 'Database deadlock detected', 1503); + } +} diff --git a/tests/Event/EventExceptionTest.php b/tests/Event/EventExceptionTest.php new file mode 100644 index 0000000..d68689f --- /dev/null +++ b/tests/Event/EventExceptionTest.php @@ -0,0 +1,25 @@ +assertExceptionStructure($exception, 'LISTENER_NOT_CALLABLE', "Event listener is not callable for event: {$eventName}", 1601); + } + + public function testEventDispatchFailed(): void + { + $eventName = 'email.sent'; + $exception = EventException::eventDispatchFailed($eventName); + $this->assertExceptionStructure($exception, 'EVENT_DISPATCH_FAILED', "Failed to dispatch event: {$eventName}", 1602); + } +} diff --git a/tests/ExceptionMessageTest.php b/tests/ExceptionMessageTest.php new file mode 100644 index 0000000..fcd5453 --- /dev/null +++ b/tests/ExceptionMessageTest.php @@ -0,0 +1,32 @@ +assertSame($code, $exceptionMessage->getCode()); + $this->assertSame($errorCode, $exceptionMessage->getErrorCode()); + $this->assertSame($message, $exceptionMessage->getMessage()); + } + + public function testExceptionMessageImmutability(): void + { + $exceptionMessage = new ExceptionMessage(9999, 'CODE', 'Message'); + + $this->expectException(\Error::class); + $reflectionProperty = new \ReflectionProperty($exceptionMessage, 'code'); + $reflectionProperty->setValue($exceptionMessage, 1234); + } +} diff --git a/tests/ExternalService/ExternalServiceExceptionTest.php b/tests/ExternalService/ExternalServiceExceptionTest.php new file mode 100644 index 0000000..2b74546 --- /dev/null +++ b/tests/ExternalService/ExternalServiceExceptionTest.php @@ -0,0 +1,48 @@ +assertExceptionStructure( + $exception, + 'API_ERROR', + "Error from external service '{$service}': {$error}", + 1701 + ); + } + + public function testServiceUnavailable(): void + { + $service = 'EmailService'; + $exception = ExternalServiceException::serviceUnavailable($service); + $this->assertExceptionStructure( + $exception, + 'SERVICE_UNAVAILABLE', + "External service unavailable: {$service}", + 1702 + ); + } + + public function testInvalidResponse(): void + { + $service = 'WeatherAPI'; + $exception = ExternalServiceException::invalidResponse($service); + $this->assertExceptionStructure( + $exception, + 'INVALID_RESPONSE', + "Invalid response from external service: {$service}", + 1703 + ); + } +} diff --git a/tests/File/FileExceptionTest.php b/tests/File/FileExceptionTest.php new file mode 100644 index 0000000..86178e2 --- /dev/null +++ b/tests/File/FileExceptionTest.php @@ -0,0 +1,39 @@ +assertExceptionStructure($exception, 'FILE_NOT_FOUND', "File not found: {$path}", 1801); + } + + public function testPermissionDenied(): void + { + $path = '/path/to/file.txt'; + $exception = FileException::permissionDenied($path); + $this->assertExceptionStructure($exception, 'PERMISSION_DENIED', "Permission denied for file: {$path}", 1802); + } + + public function testUnreadable(): void + { + $path = '/path/to/file.txt'; + $exception = FileException::unreadable($path); + $this->assertExceptionStructure($exception, 'FILE_UNREADABLE', "File is not readable: {$path}", 1803); + } + + public function testUploadFailed(): void + { + $filename = 'upload.txt'; + $exception = FileException::uploadFailed($filename); + $this->assertExceptionStructure($exception, 'UPLOAD_FAILED', "Failed to upload file: {$filename}", 1804); + } +} diff --git a/tests/Input/InputExceptionTest.php b/tests/Input/InputExceptionTest.php new file mode 100644 index 0000000..7ad2498 --- /dev/null +++ b/tests/Input/InputExceptionTest.php @@ -0,0 +1,48 @@ +assertExceptionStructure( + $exception, + 'INVALID_FORMAT', + "Invalid format for field: {$field}", + 1901 + ); + } + + public function testMissingRequired(): void + { + $field = 'username'; + $exception = InputException::missingRequired($field); + $this->assertExceptionStructure( + $exception, + 'MISSING_REQUIRED', + "Missing required field: {$field}", + 1902 + ); + } + + public function testExceedsMaxLength(): void + { + $field = 'description'; + $maxLength = 255; + $exception = InputException::exceedsMaxLength($field, $maxLength); + $this->assertExceptionStructure( + $exception, + 'EXCEEDS_MAX_LENGTH', + "Field '{$field}' exceeds maximum length of {$maxLength}", + 1903 + ); + } +} diff --git a/tests/Localization/LocalizationExceptionTest.php b/tests/Localization/LocalizationExceptionTest.php new file mode 100644 index 0000000..207e44c --- /dev/null +++ b/tests/Localization/LocalizationExceptionTest.php @@ -0,0 +1,36 @@ +assertExceptionStructure( + $exception, + 'MISSING_TRANSLATION', + "Missing translation for key '{$key}' in locale '{$locale}'", + 2001 + ); + } + + public function testInvalidLocale(): void + { + $locale = 'invalid_locale'; + $exception = LocalizationException::invalidLocale($locale); + $this->assertExceptionStructure( + $exception, + 'INVALID_LOCALE', + "Invalid locale: {$locale}", + 2002 + ); + } +} diff --git a/tests/Middleware/MiddlewareExceptionTest.php b/tests/Middleware/MiddlewareExceptionTest.php new file mode 100644 index 0000000..e58d423 --- /dev/null +++ b/tests/Middleware/MiddlewareExceptionTest.php @@ -0,0 +1,35 @@ +assertExceptionStructure( + $exception, + 'INVALID_MIDDLEWARE', + "Invalid middleware: {$middlewareName}", + 2101 + ); + } + + public function testMiddlewareExecutionFailed(): void + { + $middlewareName = 'RateLimitMiddleware'; + $exception = MiddlewareException::middlewareExecutionFailed($middlewareName); + $this->assertExceptionStructure( + $exception, + 'MIDDLEWARE_EXECUTION_FAILED', + "Execution failed for middleware: {$middlewareName}", + 2102 + ); + } +} diff --git a/tests/Network/HttpExceptionTest.php b/tests/Network/HttpExceptionTest.php new file mode 100644 index 0000000..0df11fd --- /dev/null +++ b/tests/Network/HttpExceptionTest.php @@ -0,0 +1,35 @@ +assertExceptionStructure( + $exception, + 'HTTP_CLIENT_ERROR', + "HTTP client error with status code: {$statusCode}", + 2203 + ); + } + + public function testServerError(): void + { + $statusCode = 500; + $exception = HttpException::serverError($statusCode); + $this->assertExceptionStructure( + $exception, + 'HTTP_SERVER_ERROR', + "HTTP server error with status code: {$statusCode}", + 2204 + ); + } +} diff --git a/tests/Network/NetworkExceptionTest.php b/tests/Network/NetworkExceptionTest.php new file mode 100644 index 0000000..e5acc0c --- /dev/null +++ b/tests/Network/NetworkExceptionTest.php @@ -0,0 +1,35 @@ +assertExceptionStructure( + $exception, + 'CONNECTION_FAILED', + "Failed to connect to host: {$host}", + 2201 + ); + } + + public function testTimeout(): void + { + $operation = 'HTTP request'; + $exception = NetworkException::timeout($operation); + $this->assertExceptionStructure( + $exception, + 'TIMEOUT', + "Network operation timed out: {$operation}", + 2202 + ); + } +} diff --git a/tests/Queue/QueueExceptionTest.php b/tests/Queue/QueueExceptionTest.php new file mode 100644 index 0000000..d244833 --- /dev/null +++ b/tests/Queue/QueueExceptionTest.php @@ -0,0 +1,47 @@ +assertExceptionStructure( + $exception, + 'JOB_PUSH_FAILED', + "Failed to push job to queue: {$jobClass}", + 2301 + ); + } + + public function testJobProcessingFailed(): void + { + $jobId = 'job_123456'; + $exception = QueueException::jobProcessingFailed($jobId); + $this->assertExceptionStructure( + $exception, + 'JOB_PROCESSING_FAILED', + "Failed to process job: {$jobId}", + 2302 + ); + } + + public function testQueueConnectionFailed(): void + { + $connection = 'redis'; + $exception = QueueException::queueConnectionFailed($connection); + $this->assertExceptionStructure( + $exception, + 'QUEUE_CONNECTION_FAILED', + "Failed to connect to queue: {$connection}", + 2303 + ); + } +} diff --git a/tests/Routing/RoutingExceptionTest.php b/tests/Routing/RoutingExceptionTest.php new file mode 100644 index 0000000..00025a9 --- /dev/null +++ b/tests/Routing/RoutingExceptionTest.php @@ -0,0 +1,36 @@ +assertExceptionStructure( + $exception, + 'ROUTE_NOT_FOUND', + "Route not found for URI: {$uri}", + 2401 + ); + } + + public function testMethodNotAllowed(): void + { + $method = 'POST'; + $uri = '/get-only-path'; + $exception = RoutingException::methodNotAllowed($method, $uri); + $this->assertExceptionStructure( + $exception, + 'METHOD_NOT_ALLOWED', + "Method {$method} not allowed for URI: {$uri}", + 2402 + ); + } +} diff --git a/tests/Runtime/RuntimeExceptionTest.php b/tests/Runtime/RuntimeExceptionTest.php new file mode 100644 index 0000000..c6ce5d0 --- /dev/null +++ b/tests/Runtime/RuntimeExceptionTest.php @@ -0,0 +1,46 @@ +assertExceptionStructure( + $exception, + 'UNEXPECTED_VALUE', + "Unexpected value: {$details}", + 2501 + ); + } + + public function testOutOfMemory(): void + { + $exception = RuntimeException::outOfMemory(); + $this->assertExceptionStructure( + $exception, + 'OUT_OF_MEMORY', + 'Out of memory error', + 2502 + ); + } + + public function testClassNotFound(): void + { + $className = 'App\NonExistentClass'; + $exception = RuntimeException::classNotFound($className); + $this->assertExceptionStructure( + $exception, + 'CLASS_NOT_FOUND', + "Class not found: {$className}", + 2503 + ); + } +} diff --git a/tests/Security/EncryptionExceptionTest.php b/tests/Security/EncryptionExceptionTest.php new file mode 100644 index 0000000..bfd8135 --- /dev/null +++ b/tests/Security/EncryptionExceptionTest.php @@ -0,0 +1,33 @@ +assertExceptionStructure( + $exception, + 'ENCRYPTION_FAILED', + 'Encryption operation failed', + 2601 + ); + } + + public function testDecryptionFailed(): void + { + $exception = EncryptionException::decryptionFailed(); + $this->assertExceptionStructure( + $exception, + 'DECRYPTION_FAILED', + 'Decryption operation failed', + 2602 + ); + } +} diff --git a/tests/Security/SecurityExceptionTest.php b/tests/Security/SecurityExceptionTest.php new file mode 100644 index 0000000..d99c750 --- /dev/null +++ b/tests/Security/SecurityExceptionTest.php @@ -0,0 +1,44 @@ +assertExceptionStructure( + $exception, + 'UNAUTHORIZED', + 'Unauthorized access', + 2701 + ); + } + + public function testCsrfTokenMismatch(): void + { + $exception = SecurityException::csrfTokenMismatch(); + $this->assertExceptionStructure( + $exception, + 'CSRF_TOKEN_MISMATCH', + 'CSRF token mismatch', + 2702 + ); + } + + public function testRateLimitExceeded(): void + { + $exception = SecurityException::rateLimitExceeded(); + $this->assertExceptionStructure( + $exception, + 'RATE_LIMIT_EXCEEDED', + 'Rate limit exceeded', + 2703 + ); + } +} diff --git a/tests/Session/SessionExceptionTest.php b/tests/Session/SessionExceptionTest.php new file mode 100644 index 0000000..96635c4 --- /dev/null +++ b/tests/Session/SessionExceptionTest.php @@ -0,0 +1,33 @@ +assertExceptionStructure( + $exception, + 'SESSION_START_FAILED', + 'Failed to start session', + 2801 + ); + } + + public function testInvalidSessionId(): void + { + $exception = SessionException::invalidSessionId(); + $this->assertExceptionStructure( + $exception, + 'INVALID_SESSION_ID', + 'Invalid session ID', + 2802 + ); + } +} diff --git a/tests/System/SystemExceptionTest.php b/tests/System/SystemExceptionTest.php new file mode 100644 index 0000000..36b318d --- /dev/null +++ b/tests/System/SystemExceptionTest.php @@ -0,0 +1,47 @@ +assertExceptionStructure( + $exception, + 'RESOURCE_UNAVAILABLE', + "System resource unavailable: {$resource}", + 2901 + ); + } + + public function testEnvironmentError(): void + { + $details = 'Missing .env file'; + $exception = SystemException::environmentError($details); + $this->assertExceptionStructure( + $exception, + 'ENVIRONMENT_ERROR', + "Environment error: {$details}", + 2902 + ); + } + + public function testExtensionNotLoaded(): void + { + $extension = 'gd'; + $exception = SystemException::extensionNotLoaded($extension); + $this->assertExceptionStructure( + $exception, + 'EXTENSION_NOT_LOADED', + "PHP extension not loaded: {$extension}", + 2903 + ); + } +} diff --git a/tests/Template/TemplateExceptionTest.php b/tests/Template/TemplateExceptionTest.php new file mode 100644 index 0000000..24de2c6 --- /dev/null +++ b/tests/Template/TemplateExceptionTest.php @@ -0,0 +1,35 @@ +assertExceptionStructure( + $exception, + 'TEMPLATE_NOT_FOUND', + "Template not found: {$templateName}", + 3001 + ); + } + + public function testRenderingFailed(): void + { + $templateName = 'email/welcome.html.twig'; + $exception = TemplateException::renderingFailed($templateName); + $this->assertExceptionStructure( + $exception, + 'RENDERING_FAILED', + "Failed to render template: {$templateName}", + 3002 + ); + } +} diff --git a/tests/Validation/RuleViolationExceptionTest.php b/tests/Validation/RuleViolationExceptionTest.php new file mode 100644 index 0000000..1f9a4aa --- /dev/null +++ b/tests/Validation/RuleViolationExceptionTest.php @@ -0,0 +1,24 @@ +assertExceptionStructure( + $exception, + 'RULE_VIOLATION', + "Validation rule '{$rule}' violated for field '{$field}'", + 3102 + ); + } +} diff --git a/tests/Validation/ValidationExceptionTest.php b/tests/Validation/ValidationExceptionTest.php new file mode 100644 index 0000000..828b729 --- /dev/null +++ b/tests/Validation/ValidationExceptionTest.php @@ -0,0 +1,39 @@ +assertExceptionStructure( + $exception, + 'VALIDATION_FAILED', + 'Validation failed', + 3101 + ); + } + + public function testAddValidationError(): void + { + $exception = ValidationException::create(); + $errorMessage = new ExceptionMessage( + 3103, + 'FIELD_ERROR', + 'Field has an error' + ); + $exception->addError('field_name', $errorMessage); + + $errors = $exception->getValidationErrors(); + $this->assertArrayHasKey('field_name', $errors); + $this->assertCount(1, $errors['field_name']); + $this->assertSame($errorMessage, $errors['field_name'][0]); + } +}