diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6537ca4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d28e4fc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,13 @@ +* text=auto + +/.github export-ignore +/tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.php-cs-fixer.dist.php export-ignore +phpstan.neon.dist export-ignore +phpunit.xml.dist export-ignore +CHANGELOG.md export-ignore +CONTRIBUTING.md export-ignore +CODE_OF_CONDUCT.md export-ignore +README.md export-ignore \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3320acd --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: AlvinCoded \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3eb2e3f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Ask a Question + url: https://github.com/AlvinCoded/laravel-mtn-momo-ai/discussions + about: Ask questions and discuss with other community members diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..9e575aa --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ +## Description +Please include a summary of the change and which issue is fixed. + +Fixes # (issue) + +## Type of change +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) + +## Checklist: +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..bbc8ab5 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,11 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 1.x | :white_check_mark: | + +## Reporting a Vulnerability + +If you discover a security vulnerability, please send an email to panfordalvin@gmail.com or use the issue tracker. All security vulnerabilities will be promptly addressed. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..02cdb0c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "automerge" + versioning-strategy: "increase" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "automerge" diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml new file mode 100644 index 0000000..3c4658e --- /dev/null +++ b/.github/workflows/php-cs-fixer.yml @@ -0,0 +1,29 @@ +# Code Style Checking +name: Code Style + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + php-cs-fixer: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: json, dom, curl, libxml, mbstring + coverage: none + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + # - name: Check code style + # run: vendor/bin/php-cs-fixer fix --dry-run --diff diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..650d710 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +# Automated Release Management +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: | + LICENSE.md + README.md + body_path: ${{ github.workspace }}/CHANGELOG.md + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..feabd13 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,29 @@ +# Security Scanning +name: Security Scan + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + schedule: + - cron: '0 0 * * 0' + +jobs: + security: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Security Check + uses: symfonycorp/security-checker-action@v5 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..11f9b2f --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,61 @@ +name: Tests + +on: ['push', 'pull_request'] + +jobs: + ci: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest, windows-latest] + php: [8.2, 8.3, 8.4] + laravel: [11.*, 10.*, 9.*] + dependency-version: [prefer-lowest, prefer-stable] + include: + - php: 8.1 + laravel: 9.* + - php: 8.1 + laravel: 10.* + exclude: + - php: 8.1 + laravel: 11.* + + + name: Tests P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.os }} - ${{ matrix.dependency-version }} + steps: + + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.composer/cache/files + key: dependencies-php-${{ matrix.php }}-L${{ matrix.laravel }}-${{ matrix.dependency-version }}-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, mbstring, zip, fileinfo + coverage: none + + - name: Require Laravel Version + run: > + composer require + "laravel/framework:${{ matrix.laravel }}" + --no-interaction --no-update + + - name: Install Composer dependencies + run: composer update --${{ matrix.dependency-version }} --no-interaction --prefer-dist + + - name: Integration Tests + run: php ./vendor/bin/pest + + - name: Run tests and collect coverage + run: vendor/bin/phpunit --coverage-clover coverage.xml . + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml new file mode 100644 index 0000000..28fc47a --- /dev/null +++ b/.github/workflows/update-changelog.yml @@ -0,0 +1,34 @@ +# Changelog +name: Update Changelog + +on: + release: + types: [released] + +permissions: + contents: write + +jobs: + update: + name: Update + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: main + + - name: Update Changelog + uses: stefanzweifel/changelog-updater-action@v1 + with: + latest-version: ${{ github.event.release.name }} + release-notes: ${{ github.event.release.body }} + + - name: Commit updated CHANGELOG + uses: stefanzweifel/git-auto-commit-action@v5 + with: + branch: main + commit_message: Update CHANGELOG + file_pattern: CHANGELOG.md diff --git a/.gitignore b/.gitignore index a725465..408e8fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ -vendor/ \ No newline at end of file +/.phpunit.cache +/.php-cs-fixer.cache +/.php-cs-fixer.php +/composer.lock +/phpunit.xml +/vendor/ +*.swp +*.swo \ No newline at end of file diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..9056129 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,36 @@ +in([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PSR12' => true, + 'array_syntax' => ['syntax' => 'short'], + 'ordered_imports' => ['sort_algorithm' => 'alpha'], + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'trailing_comma_in_multiline' => true, + 'phpdoc_scalar' => true, + 'unary_operator_spaces' => true, + 'binary_operator_spaces' => true, + 'blank_line_before_statement' => [ + 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], + ], + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_var_without_name' => true, + 'class_attributes_separation' => [ + 'elements' => [ + 'method' => 'one', + ], + ], + 'method_argument_space' => [ + 'on_multiline' => 'ensure_fully_multiline', + 'keep_multiple_spaces_after_comma' => true, + ], + 'single_trait_insert_per_statement' => true, + ]) + ->setFinder($finder); diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d686ca..8cbe0be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to `laravel-mtn-momo-ai` will be documented in this file. -## 1.0.0 - 2024-01-07 +## 1.0.1 - 2025-01-10 -Initial Release \ No newline at end of file +### Fixed +- minor bug fixes + +## 1.0.0 - 2025-01-08 + +Initial Release โœจ \ No newline at end of file diff --git a/README.md b/README.md index 86b0e15..c12fa20 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # Laravel MTN MOMO AI -[![Latest Version on Packagist](https://img.shields.io/packagist/v/AlvinCoded/laravel-mtn-momo-ai.svg?style=flat-square)](https://packagist.org/packages/alvincoded/laravel-mtn-momo-ai) -[![Total Downloads](https://img.shields.io/packagist/dt/AlvinCoded/laravel-mtn-momo-ai.svg?style=flat-square)](https://packagist.org/packages/alvincoded/laravel-mtn-momo-ai) -[![License](https://img.shields.io/packagist/l/AlvinCoded/laravel-mtn-momo-ai.svg?style=flat-square)](https://packagist.org/packages/alvincoded/laravel-mtn-momo-ai) +[![Latest Version on Packagist](https://img.shields.io/packagist/v/alvincoded/laravel-mtn-momo-ai.svg?style=flat-square)](https://packagist.org/packages/alvincoded/laravel-mtn-momo-ai) +[![Total Downloads](https://img.shields.io/packagist/dt/alvincoded/laravel-mtn-momo-ai.svg?style=flat-square)](https://packagist.org/packages/alvincoded/laravel-mtn-momo-ai) +[![Tests](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/tests.yml/badge.svg)](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/tests.yml) +[![Code Style](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/php-cs-fixer.yml) +[![Security](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/security.yml/badge.svg)](https://github.com/alvincoded/laravel-mtn-momo-ai/actions/workflows/security.yml) + -A powerful Laravel package that integrates MTN Mobile Money API with AI capabilities, providing intelligent transaction analysis, fraud detection, and more! +A powerful Laravel package that integrates [MTN Mobile Money API](https://momodeveloper.mtn.com/) with AI capabilities, providing intelligent transaction analysis, fraud detection, and more! ## Features ๐ŸŒŸ @@ -20,7 +23,7 @@ A powerful Laravel package that integrates MTN Mobile Money API with AI capabili - ๐Ÿšจ Anomaly detection in transactions - ๐Ÿ”ง API call optimization -## Prerequisites ๐Ÿ”‘ +## Prerequisites Before getting started with the MTN MOMO AI package, you'll need: @@ -88,12 +91,13 @@ Key configurations include: ```bash # MTN MOMO API Configuration -MTN_MOMO_API_USER=your_api_user +MTN_MOMO_API_USER=your_api_user_id # Randomly generated UUID MTN_MOMO_API_KEY=your_api_key MTN_MOMO_SUBSCRIPTION_KEY=your_subscription_key +MTN_MOMO_PROVIDER_CALLBACK_HOST=http://localhost MTN_MOMO_BASE_URL=https://sandbox.momodeveloper.mtn.com MTN_MOMO_ENVIRONMENT=sandbox -MTN_MOMO_DEFAULT_CURRENCY=USD +MTN_MOMO_DEFAULT_CURRENCY=EUR # AI Model API Keys OPENAI_API_KEY=your_openai_key @@ -120,13 +124,13 @@ use AlvinCoded\MtnMomoAi\Facades\MtnMomoAi; $analysis = MtnMomoAi::analyzeTransaction('transaction123'); // Request to pay -$result = MtnMomoAi::requestToPay(100, 'GHS', 'ext123', 'party123', 'Payment', 'Note'); +$result = MtnMomoAi::requestToPay(100, 'EUR', 'ext123', 'party123', 'Payment', 'Note'); // Transfer (Disbursement) -$result = MtnMomoAi::transfer(100, 'GHS', 'ext123', 'party123', 'Payment', 'Note'); +$result = MtnMomoAi::transfer(100, 'EUR', 'ext123', 'party123', 'Payment', 'Note'); // Remittance -$result = MtnMomoAi::remit(100, 'GHS', 'ext123', 'party123', 'Payment', 'Note'); +$result = MtnMomoAi::remit(100, 'EUR', 'ext123', 'party123', 'Payment', 'Note'); ``` ### AI-Enhanced Features @@ -139,7 +143,7 @@ $fraudAnalysis = MtnMomoAi::detectFraud($transactionData); $forecast = MtnMomoAi::forecastCashFlow('1month'); // Parse natural language command -$result = MtnMomoAi::parseNaturalLanguageCommand('Send 100 GHS to John Doe'); +$result = MtnMomoAi::parseNaturalLanguageCommand('Send 100 EUR to John Doe'); // Generate report $report = MtnMomoAi::generateReport($startDate, $endDate); @@ -155,7 +159,7 @@ $anomalies = MtnMomoAi::monitorTransactions(); MtnMomoAi::scheduleDisbursement(100, 'recipient123'); // Specifying a different currency -MtnMomoAi::scheduleDisbursement(100, 'recipient123', 'GHS'); +MtnMomoAi::scheduleDisbursement(100, 'recipient123', 'EUR'); ``` ### Transaction Analysis @@ -168,7 +172,7 @@ $analysis = MtnMomoAi::analyzeTransaction('transaction123'); // Fraud detection with custom parameters $fraudAnalysis = MtnMomoAi::detectFraud([ 'amount' => 1000, - 'currency' => 'GHS', + 'currency' => 'EUR', 'recipient' => 'user123', 'timestamp' => now(), 'location' => 'GH' @@ -182,7 +186,7 @@ $fraudAnalysis = MtnMomoAi::detectFraud([ $retryResult = MtnMomoAi::smartRetry([ 'product' => 'collection', 'amount' => 100, - 'currency' => 'GHS', + 'currency' => 'EUR', 'externalId' => 'ext123', 'partyId' => 'party123', 'payerMessage' => 'Payment', @@ -196,7 +200,7 @@ The package includes comprehensive error handling: ```php try { - $result = MtnMomoAi::requestToPay(100, 'GHS', 'ext123', 'party123', 'Payment', 'Note'); + $result = MtnMomoAi::requestToPay(100, 'EUR', 'ext123', 'party123', 'Payment', 'Note'); } catch (\AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException $e) { // Handle API-specific errors $errorDetails = $e->getResponseBody(); @@ -265,15 +269,13 @@ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for det ## Security ๐Ÿ”’ -If you discover any security-related issues, don't hesitate to use the issue tracker. +Please review [our security policy](../../security/policy) on how to report security vulnerabilities. ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. ## Credits ๐Ÿ‘ - -- Author: [Alvin Panford](https://github.com/AlvinCoded) - OpenAI PHP by [Nuno Maduro](https://github.com/openai-php/laravel) - Anthropic Laravel by [Mozex](https://github.com/mozex/anthropic-laravel) - **Gemini PHP** for Laravel by [Fatih AYDIN](https://github.com/google-gemini-php/laravel) diff --git a/composer.json b/composer.json index 81b313f..68bb71b 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,29 @@ { "name": "alvincoded/laravel-mtn-momo-ai", "description": "A Laravel package for integrating MTN Mobile Money API with AI capabilities", - "keywords": ["laravel", "ai", "artificial intelligence", "gpt", "claude", "gemini", "MTN", "mobile-money", "api"], + "keywords": ["laravel", "ai", "artificial-intelligence", "gpt", "claude", "gemini", "MTN", "mobile-money", "api"], "type": "library", "license": "MIT", "authors": [ { "name": "Alvin Panford", - "email": "panfordalvin@gmail.com" + "email": "panfordalvin@gmail.com", + "role": "Developer" + } + ], + "homepage": "https://github.com/alvincoded/laravel-mtn-momo-ai", + "support": { + "issues": "https://github.com/alvincoded/laravel-mtn-momo-ai/issues", + "source": "https://github.com/alvincoded/laravel-mtn-momo-ai" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/alvincoded" } ], "require": { - "php": "^8.1", + "php": "^8.1|^8.2", "illuminate/support": "^9.0|^10.0|^11.0", "laravel/framework": "^9.46.0|^10.34.2|^11.23.5", "guzzlehttp/guzzle": "^7.0", @@ -21,8 +33,14 @@ }, "require-dev": { "mockery/mockery": "^1.6", - "orchestra/testbench": "^9.0|^10.0|^11.0", - "phpunit/phpunit": "^9.0|^10.0" + "orchestra/testbench": "7.0|^8.0|^9.0|^10.0|^11.0", + "phpunit/phpunit": "^9.0|^10.0", + "friendsofphp/php-cs-fixer": "^3.0", + "phpstan/phpstan": "^1.10", + "nunomaduro/larastan": "^2.0", + "symfony/var-dumper": "^6.0|^7.0", + "vimeo/psalm": "^5.0", + "rector/rector": "^0.19" }, "autoload": { "psr-4": { @@ -53,11 +71,40 @@ "config": { "sort-packages": true, "allow-plugins": { - "php-http/discovery": true + "php-http/discovery": true, + "pestphp/pest-plugin": true } }, "scripts": { - "test": "phpunit" + "post-autoload-dump": [ + "@php ./vendor/bin/testbench package:discover --ansi" + ], + "analyse": "vendor/bin/phpstan analyse", + "baseline": "vendor/bin/phpstan analyse --generate-baseline", + "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes", + "test": "vendor/bin/phpunit", + "test-coverage": "vendor/bin/phpunit --coverage-html coverage", + "psalm": "vendor/bin/psalm", + "rector": "vendor/bin/rector process", + "check-style": "vendor/bin/php-cs-fixer fix --dry-run --diff", + "fix-style": "vendor/bin/php-cs-fixer fix", + "clear": [ + "@php vendor/bin/testbench package:purge-skeleton --ansi", + "rm -rf vendor", + "rm -rf composer.lock" + ] + }, + "scripts-descriptions": { + "analyse": "Run static analysis", + "baseline": "Generate baseline for static analysis", + "format": "Format code using PHP CS Fixer", + "test": "Run PHPUnit tests", + "test-coverage": "Run PHPUnit tests with coverage report", + "psalm": "Run Psalm static analysis", + "rector": "Run Rector to upgrade code", + "check-style": "Check code style", + "fix-style": "Fix code style", + "clear": "Clear all generated files" }, "minimum-stability": "dev", "prefer-stable": true diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 1adf65a..0000000 --- a/composer.lock +++ /dev/null @@ -1,8930 +0,0 @@ -{ - "_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": "730025b6ea82f44f1904448166e53a16", - "packages": [ - { - "name": "brick/math", - "version": "0.12.1", - "source": { - "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", - "reference": "f510c0a40911935b77b86859eb5223d58d660df1", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^10.1", - "vimeo/psalm": "5.16.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Brick\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Arbitrary-precision arithmetic library", - "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "bignumber", - "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" - ], - "support": { - "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.12.1" - }, - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ], - "time": "2023-11-29T23:19:16+00:00" - }, - { - "name": "carbonphp/carbon-doctrine-types", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/dbal": "<4.0.0 || >=5.0.0" - }, - "require-dev": { - "doctrine/dbal": "^4.0.0", - "nesbot/carbon": "^2.71.0 || ^3.0.0", - "phpunit/phpunit": "^10.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "KyleKatarn", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Types to use Carbon in Doctrine", - "keywords": [ - "carbon", - "date", - "datetime", - "doctrine", - "time" - ], - "support": { - "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" - }, - { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", - "type": "tidelift" - } - ], - "time": "2024-02-09T16:56:22+00:00" - }, - { - "name": "dflydev/dot-access-data", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", - "scrutinizer/ocular": "1.6.0", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Dflydev\\DotAccessData\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" - }, - { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" - }, - { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" - }, - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com" - } - ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", - "keywords": [ - "access", - "data", - "dot", - "notation" - ], - "support": { - "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" - }, - "time": "2024-07-08T12:26:09+00:00" - }, - { - "name": "doctrine/inflector", - "version": "2.0.10", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", - "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^11.0", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25 || ^5.4" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", - "homepage": "https://www.doctrine-project.org/projects/inflector.html", - "keywords": [ - "inflection", - "inflector", - "lowercase", - "manipulation", - "php", - "plural", - "singular", - "strings", - "uppercase", - "words" - ], - "support": { - "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.10" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", - "type": "tidelift" - } - ], - "time": "2024-02-18T20:23:39+00:00" - }, - { - "name": "doctrine/lexer", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2024-02-05T11:56:58+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.4.0", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "8c784d071debd117328803d86b2097615b457500" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", - "reference": "8c784d071debd117328803d86b2097615b457500", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2024-10-09T13:47:03+00:00" - }, - { - "name": "egulias/email-validator", - "version": "4.0.3", - "source": { - "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "b115554301161fa21467629f1e1391c1936de517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", - "reference": "b115554301161fa21467629f1e1391c1936de517", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2.0 || ^3.0", - "php": ">=8.1", - "symfony/polyfill-intl-idn": "^1.26" - }, - "require-dev": { - "phpunit/phpunit": "^10.2", - "vimeo/psalm": "^5.12" - }, - "suggest": { - "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Egulias\\EmailValidator\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eduardo Gulias Davis" - } - ], - "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", - "keywords": [ - "email", - "emailvalidation", - "emailvalidator", - "validation", - "validator" - ], - "support": { - "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" - }, - "funding": [ - { - "url": "https://github.com/egulias", - "type": "github" - } - ], - "time": "2024-12-27T00:36:43+00:00" - }, - { - "name": "fruitcake/php-cors", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", - "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", - "shasum": "" - }, - "require": { - "php": "^7.4|^8.0", - "symfony/http-foundation": "^4.4|^5.4|^6|^7" - }, - "require-dev": { - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "Fruitcake\\Cors\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barryvdh", - "email": "barryvdh@gmail.com" - } - ], - "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", - "homepage": "https://github.com/fruitcake/php-cors", - "keywords": [ - "cors", - "laravel", - "symfony" - ], - "support": { - "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" - }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2023-10-12T05:21:21+00:00" - }, - { - "name": "google-gemini-php/client", - "version": "1.0.15", - "source": { - "type": "git", - "url": "https://github.com/google-gemini-php/client.git", - "reference": "6dca9a5e6a6de39b230fe4593a8d041efd02e34e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/google-gemini-php/client/zipball/6dca9a5e6a6de39b230fe4593a8d041efd02e34e", - "reference": "6dca9a5e6a6de39b230fe4593a8d041efd02e34e", - "shasum": "" - }, - "require": { - "php": "^8.1.0", - "php-http/discovery": "^1.19.2" - }, - "require-dev": { - "guzzlehttp/guzzle": "^7.8.1", - "guzzlehttp/psr7": "^2.6.2", - "laravel/pint": "^1.18.1", - "mockery/mockery": "^1.6.7", - "pestphp/pest": "^2.30", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "autoload": { - "files": [ - "src/Gemini.php" - ], - "psr-4": { - "Gemini\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fatih AYDIN", - "email": "aydinfatih52@gmail.com" - } - ], - "description": "Gemini API is a supercharged PHP API client that allows you to interact with the Gemini API", - "keywords": [ - "Gemini", - "client", - "gemini-pro", - "language", - "natural", - "nlp", - "php", - "processing", - "sdk" - ], - "support": { - "issues": "https://github.com/google-gemini-php/client/issues", - "source": "https://github.com/google-gemini-php/client/tree/1.0.15" - }, - "time": "2024-12-29T12:53:49+00:00" - }, - { - "name": "google-gemini-php/laravel", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/google-gemini-php/laravel.git", - "reference": "ac83a7a3f5c438c1823af0ce939f3d17d61441ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/google-gemini-php/laravel/zipball/ac83a7a3f5c438c1823af0ce939f3d17d61441ae", - "reference": "ac83a7a3f5c438c1823af0ce939f3d17d61441ae", - "shasum": "" - }, - "require": { - "google-gemini-php/client": "^1.0", - "laravel/framework": "^9.0|^10.0|^11.0", - "php": "^8.1.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^7.8.1", - "laravel/pint": "^1.13.6", - "pestphp/pest": "^2.27.0", - "pestphp/pest-plugin-arch": "^2.4.1", - "phpstan/phpstan": "^1.10.47", - "symfony/var-dumper": "^6.4.0|^7.0.1" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Gemini\\Laravel\\ServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Gemini\\Laravel\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fatih AYDIN", - "email": "aydinfatih52@gmail.com" - } - ], - "description": "Google Gemini PHP for Laravel is a supercharged PHP API client that allows you to interact with the Google Gemini AI API", - "keywords": [ - "Gemini", - "api", - "client", - "language", - "laravel", - "natural", - "php", - "processing", - "sdk" - ], - "support": { - "issues": "https://github.com/google-gemini-php/laravel/issues", - "source": "https://github.com/google-gemini-php/laravel/tree/1.0.1" - }, - "time": "2024-02-11T17:25:44+00:00" - }, - { - "name": "graham-campbell/result-type", - "version": "v1.1.3", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", - "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" - }, - "type": "library", - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2024-07-20T21:45:45+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.4", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", - "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", - "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.4" - }, - "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-10-17T10:06:22+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": "guzzlehttp/uri-template", - "version": "v1.0.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/uri-template.git", - "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", - "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", - "uri-template/tests": "1.0.0" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\UriTemplate\\": "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" - } - ], - "description": "A polyfill class for uri_template of PHP", - "keywords": [ - "guzzlehttp", - "uri-template" - ], - "support": { - "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.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/uri-template", - "type": "tidelift" - } - ], - "time": "2023-12-03T19:50:20+00:00" - }, - { - "name": "laravel/framework", - "version": "v11.37.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "6cb103d2024b087eae207654b3f4b26646119ba5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6cb103d2024b087eae207654b3f4b26646119ba5", - "reference": "6cb103d2024b087eae207654b3f4b26646119ba5", - "shasum": "" - }, - "require": { - "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", - "composer-runtime-api": "^2.2", - "doctrine/inflector": "^2.0.5", - "dragonmantank/cron-expression": "^3.4", - "egulias/email-validator": "^3.2.1|^4.0", - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "ext-session": "*", - "ext-tokenizer": "*", - "fruitcake/php-cors": "^1.3", - "guzzlehttp/guzzle": "^7.8.2", - "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", - "laravel/serializable-closure": "^1.3|^2.0", - "league/commonmark": "^2.6", - "league/flysystem": "^3.25.1", - "league/flysystem-local": "^3.25.1", - "league/uri": "^7.5.1", - "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.72.2|^3.4", - "nunomaduro/termwind": "^2.0", - "php": "^8.2", - "psr/container": "^1.1.1|^2.0.1", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", - "ramsey/uuid": "^4.7", - "symfony/console": "^7.0.3", - "symfony/error-handler": "^7.0.3", - "symfony/finder": "^7.0.3", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.0.3", - "symfony/mailer": "^7.0.3", - "symfony/mime": "^7.0.3", - "symfony/polyfill-php83": "^1.31", - "symfony/process": "^7.0.3", - "symfony/routing": "^7.0.3", - "symfony/uid": "^7.0.3", - "symfony/var-dumper": "^7.0.3", - "tijsverkoyen/css-to-inline-styles": "^2.2.5", - "vlucas/phpdotenv": "^5.6.1", - "voku/portable-ascii": "^2.0.2" - }, - "conflict": { - "tightenco/collect": "<5.5.33" - }, - "provide": { - "psr/container-implementation": "1.1|2.0", - "psr/log-implementation": "1.0|2.0|3.0", - "psr/simple-cache-implementation": "1.0|2.0|3.0" - }, - "replace": { - "illuminate/auth": "self.version", - "illuminate/broadcasting": "self.version", - "illuminate/bus": "self.version", - "illuminate/cache": "self.version", - "illuminate/collections": "self.version", - "illuminate/concurrency": "self.version", - "illuminate/conditionable": "self.version", - "illuminate/config": "self.version", - "illuminate/console": "self.version", - "illuminate/container": "self.version", - "illuminate/contracts": "self.version", - "illuminate/cookie": "self.version", - "illuminate/database": "self.version", - "illuminate/encryption": "self.version", - "illuminate/events": "self.version", - "illuminate/filesystem": "self.version", - "illuminate/hashing": "self.version", - "illuminate/http": "self.version", - "illuminate/log": "self.version", - "illuminate/macroable": "self.version", - "illuminate/mail": "self.version", - "illuminate/notifications": "self.version", - "illuminate/pagination": "self.version", - "illuminate/pipeline": "self.version", - "illuminate/process": "self.version", - "illuminate/queue": "self.version", - "illuminate/redis": "self.version", - "illuminate/routing": "self.version", - "illuminate/session": "self.version", - "illuminate/support": "self.version", - "illuminate/testing": "self.version", - "illuminate/translation": "self.version", - "illuminate/validation": "self.version", - "illuminate/view": "self.version", - "spatie/once": "*" - }, - "require-dev": { - "ably/ably-php": "^1.0", - "aws/aws-sdk-php": "^3.322.9", - "ext-gmp": "*", - "fakerphp/faker": "^1.24", - "guzzlehttp/promises": "^2.0.3", - "guzzlehttp/psr7": "^2.4", - "league/flysystem-aws-s3-v3": "^3.25.1", - "league/flysystem-ftp": "^3.25.1", - "league/flysystem-path-prefixing": "^3.25.1", - "league/flysystem-read-only": "^3.25.1", - "league/flysystem-sftp-v3": "^3.25.1", - "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^9.6", - "pda/pheanstalk": "^5.0.6", - "php-http/discovery": "^1.15", - "phpstan/phpstan": "^1.11.5", - "phpunit/phpunit": "^10.5.35|^11.3.6", - "predis/predis": "^2.3", - "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.0.3", - "symfony/http-client": "^7.0.3", - "symfony/psr-http-message-bridge": "^7.0.3", - "symfony/translation": "^7.0.3" - }, - "suggest": { - "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", - "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", - "ext-apcu": "Required to use the APC cache driver.", - "ext-fileinfo": "Required to use the Filesystem class.", - "ext-ftp": "Required to use the Flysystem FTP driver.", - "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "ext-memcached": "Required to use the memcache cache driver.", - "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", - "ext-pdo": "Required to use all database features.", - "ext-posix": "Required to use all features of the queue worker.", - "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "laravel/tinker": "Required to use the tinker console command (^2.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", - "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", - "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", - "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", - "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", - "mockery/mockery": "Required to use mocking (^1.6).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", - "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", - "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", - "predis/predis": "Required to use the predis connector (^2.3).", - "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "11.x-dev" - } - }, - "autoload": { - "files": [ - "src/Illuminate/Collections/functions.php", - "src/Illuminate/Collections/helpers.php", - "src/Illuminate/Events/functions.php", - "src/Illuminate/Filesystem/functions.php", - "src/Illuminate/Foundation/helpers.php", - "src/Illuminate/Log/functions.php", - "src/Illuminate/Support/functions.php", - "src/Illuminate/Support/helpers.php" - ], - "psr-4": { - "Illuminate\\": "src/Illuminate/", - "Illuminate\\Support\\": [ - "src/Illuminate/Macroable/", - "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Laravel Framework.", - "homepage": "https://laravel.com", - "keywords": [ - "framework", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2025-01-02T20:10:21+00:00" - }, - { - "name": "laravel/prompts", - "version": "v0.3.2", - "source": { - "type": "git", - "url": "https://github.com/laravel/prompts.git", - "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/0e0535747c6b8d6d10adca8b68293cf4517abb0f", - "reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "ext-mbstring": "*", - "php": "^8.1", - "symfony/console": "^6.2|^7.0" - }, - "conflict": { - "illuminate/console": ">=10.17.0 <10.25.0", - "laravel/framework": ">=10.17.0 <10.25.0" - }, - "require-dev": { - "illuminate/collections": "^10.0|^11.0", - "mockery/mockery": "^1.5", - "pestphp/pest": "^2.3|^3.4", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-mockery": "^1.1" - }, - "suggest": { - "ext-pcntl": "Required for the spinner to be animated." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "0.3.x-dev" - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Laravel\\Prompts\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Add beautiful and user-friendly forms to your command-line applications.", - "support": { - "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.2" - }, - "time": "2024-11-12T14:59:47+00:00" - }, - { - "name": "laravel/serializable-closure", - "version": "v2.0.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/serializable-closure.git", - "reference": "613b2d4998f85564d40497e05e89cb6d9bd1cbe8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/613b2d4998f85564d40497e05e89cb6d9bd1cbe8", - "reference": "613b2d4998f85564d40497e05e89cb6d9bd1cbe8", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "illuminate/support": "^10.0|^11.0", - "nesbot/carbon": "^2.67|^3.0", - "pestphp/pest": "^2.36", - "phpstan/phpstan": "^2.0", - "symfony/var-dumper": "^6.2.0|^7.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\SerializableClosure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Nuno Maduro", - "email": "nuno@laravel.com" - } - ], - "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", - "keywords": [ - "closure", - "laravel", - "serializable" - ], - "support": { - "issues": "https://github.com/laravel/serializable-closure/issues", - "source": "https://github.com/laravel/serializable-closure" - }, - "time": "2024-12-16T15:26:28+00:00" - }, - { - "name": "league/commonmark", - "version": "2.6.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "league/config": "^1.1.1", - "php": "^7.4 || ^8.0", - "psr/event-dispatcher": "^1.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "cebe/markdown": "^1.0", - "commonmark/cmark": "0.31.1", - "commonmark/commonmark.js": "0.31.1", - "composer/package-versions-deprecated": "^1.8", - "embed/embed": "^4.4", - "erusev/parsedown": "^1.0", - "ext-json": "*", - "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4 || ^2.0", - "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", - "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 | ^7.0", - "symfony/process": "^5.4 | ^6.0 | ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", - "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0" - }, - "suggest": { - "symfony/yaml": "v2.3+ required if using the Front Matter extension" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "League\\CommonMark\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", - "homepage": "https://commonmark.thephpleague.com", - "keywords": [ - "commonmark", - "flavored", - "gfm", - "github", - "github-flavored", - "markdown", - "md", - "parser" - ], - "support": { - "docs": "https://commonmark.thephpleague.com/", - "forum": "https://github.com/thephpleague/commonmark/discussions", - "issues": "https://github.com/thephpleague/commonmark/issues", - "rss": "https://github.com/thephpleague/commonmark/releases.atom", - "source": "https://github.com/thephpleague/commonmark" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/commonmark", - "type": "tidelift" - } - ], - "time": "2024-12-29T14:10:59+00:00" - }, - { - "name": "league/config", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/config.git", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "shasum": "" - }, - "require": { - "dflydev/dot-access-data": "^3.0.1", - "nette/schema": "^1.2", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.5", - "scrutinizer/ocular": "^1.8.1", - "unleashedtech/php-coding-standard": "^3.1", - "vimeo/psalm": "^4.7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.2-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Config\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" - } - ], - "description": "Define configuration arrays with strict schemas and access values with dot notation", - "homepage": "https://config.thephpleague.com", - "keywords": [ - "array", - "config", - "configuration", - "dot", - "dot-access", - "nested", - "schema" - ], - "support": { - "docs": "https://config.thephpleague.com/", - "issues": "https://github.com/thephpleague/config/issues", - "rss": "https://github.com/thephpleague/config/releases.atom", - "source": "https://github.com/thephpleague/config" - }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - } - ], - "time": "2022-12-11T20:36:23+00:00" - }, - { - "name": "league/flysystem", - "version": "3.29.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/edc1bb7c86fab0776c3287dbd19b5fa278347319", - "reference": "edc1bb7c86fab0776c3287dbd19b5fa278347319", - "shasum": "" - }, - "require": { - "league/flysystem-local": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" - }, - "conflict": { - "async-aws/core": "<1.19.0", - "async-aws/s3": "<1.14.0", - "aws/aws-sdk-php": "3.209.31 || 3.210.0", - "guzzlehttp/guzzle": "<7.0", - "guzzlehttp/ringphp": "<1.1.1", - "phpseclib/phpseclib": "3.0.15", - "symfony/http-client": "<5.2" - }, - "require-dev": { - "async-aws/s3": "^1.5 || ^2.0", - "async-aws/simple-s3": "^1.1 || ^2.0", - "aws/aws-sdk-php": "^3.295.10", - "composer/semver": "^3.0", - "ext-fileinfo": "*", - "ext-ftp": "*", - "ext-mongodb": "^1.3", - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.5", - "google/cloud-storage": "^1.23", - "guzzlehttp/psr7": "^2.6", - "microsoft/azure-storage-blob": "^1.1", - "mongodb/mongodb": "^1.2", - "phpseclib/phpseclib": "^3.0.36", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5.11|^10.0", - "sabre/dav": "^4.6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "File storage abstraction for PHP", - "keywords": [ - "WebDAV", - "aws", - "cloud", - "file", - "files", - "filesystem", - "filesystems", - "ftp", - "s3", - "sftp", - "storage" - ], - "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.29.1" - }, - "time": "2024-10-08T08:58:34+00:00" - }, - { - "name": "league/flysystem-local", - "version": "3.29.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/e0e8d52ce4b2ed154148453d321e97c8e931bd27", - "reference": "e0e8d52ce4b2ed154148453d321e97c8e931bd27", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "league/flysystem": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\Flysystem\\Local\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Local filesystem adapter for Flysystem.", - "keywords": [ - "Flysystem", - "file", - "files", - "filesystem", - "local" - ], - "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.29.0" - }, - "time": "2024-08-09T21:24:39+00:00" - }, - { - "name": "league/mime-type-detection", - "version": "1.16.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" - } - ], - "description": "Mime-type detection for Flysystem", - "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" - }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2024-09-21T08:32:55+00:00" - }, - { - "name": "league/uri", - "version": "7.5.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", - "shasum": "" - }, - "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" - }, - "conflict": { - "league/uri-schemes": "^1.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-fileinfo": "to create Data URI from file contennts", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "URI manipulation library", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "middleware", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "uri-template", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:40:02+00:00" - }, - { - "name": "league/uri-interfaces", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^8.1", - "psr/http-factory": "^1", - "psr/http-message": "^1.1 || ^2.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "php-64bit": "to improve IPV4 host parsing", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Uri\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "Common interfaces and classes for URI representation and interaction", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2024-12-08T08:18:47+00:00" - }, - { - "name": "monolog/monolog", - "version": "3.8.1", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/log": "^2.0 || ^3.0" - }, - "provide": { - "psr/log-implementation": "3.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^3.0", - "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^7 || ^8", - "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2.0", - "guzzlehttp/guzzle": "^7.4.5", - "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4 || ^3", - "php-console/php-console": "^3.1.8", - "phpstan/phpstan": "^2", - "phpstan/phpstan-deprecation-rules": "^2", - "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "^10.5.17 || ^11.0.7", - "predis/predis": "^1.1 || ^2", - "rollbar/rollbar": "^4.0", - "ruflin/elastica": "^7 || ^8", - "symfony/mailer": "^5.4 || ^6", - "symfony/mime": "^5.4 || ^6" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", - "ext-mbstring": "Allow to work properly with unicode symbols", - "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", - "ext-openssl": "Required to send log messages using SSL", - "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "https://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "https://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "support": { - "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.8.1" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ], - "time": "2024-12-05T17:15:07+00:00" - }, - { - "name": "mozex/anthropic-laravel", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/mozex/anthropic-laravel.git", - "reference": "85c39f1ab6bdc8d53ebb2eb38c9a0a27f226f0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mozex/anthropic-laravel/zipball/85c39f1ab6bdc8d53ebb2eb38c9a0a27f226f0b2", - "reference": "85c39f1ab6bdc8d53ebb2eb38c9a0a27f226f0b2", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^7.9.2", - "laravel/framework": "^9.46.0|^10.34.2|^11.23.5", - "mozex/anthropic-php": "^v1.1.0", - "php": "^8.1.0" - }, - "require-dev": { - "laravel/pint": "^1.17.3", - "pestphp/pest": "^2.35.1|^3.0.0", - "pestphp/pest-plugin-arch": "^2.7.0|^3.0.0", - "phpstan/phpstan": "^1.12.4", - "spatie/ray": "^1.41", - "symfony/var-dumper": "^6.4.0|^7.1.4" - }, - "type": "library", - "extra": { - "COV": "0.10.2", - "laravel": { - "providers": [ - "Anthropic\\Laravel\\ServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Anthropic\\Laravel\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mozex", - "email": "mozex@alphorld.com" - } - ], - "description": "Anthropic PHP for Laravel is a supercharged PHP API client that allows you to interact with the Anthropic API", - "keywords": [ - "Claude-3-Haiku", - "Claude-3-Opus", - "Claude-3-Sonnet", - "anthropic", - "api", - "claude", - "client", - "language", - "laravel", - "natural", - "php", - "processing", - "sdk" - ], - "support": { - "issues": "https://github.com/mozex/anthropic-laravel/issues", - "source": "https://github.com/mozex/anthropic-laravel/tree/1.1.0" - }, - "funding": [ - { - "url": "https://github.com/mozex", - "type": "github" - } - ], - "time": "2024-12-21T12:37:11+00:00" - }, - { - "name": "mozex/anthropic-php", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/mozex/anthropic-php.git", - "reference": "5f9c9c74f2d3d97aab36a2604bf93f1b7aa4c84c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mozex/anthropic-php/zipball/5f9c9c74f2d3d97aab36a2604bf93f1b7aa4c84c", - "reference": "5f9c9c74f2d3d97aab36a2604bf93f1b7aa4c84c", - "shasum": "" - }, - "require": { - "php": "^8.1.0", - "php-http/discovery": "^1.20.0", - "php-http/multipart-stream-builder": "^1.4.2", - "psr/http-client": "^1.0.3", - "psr/http-client-implementation": "^1.0.1", - "psr/http-factory-implementation": "*", - "psr/http-message": "^1.1.0|^2.0.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^7.9.2", - "guzzlehttp/psr7": "^2.7.0", - "laravel/pint": "^1.18.1", - "mockery/mockery": "^1.6.12", - "nunomaduro/collision": "^7.11.0|^8.5.0", - "pestphp/pest": "^2.36.0|^3.5.0", - "pestphp/pest-plugin-arch": "^2.7|^3.0", - "pestphp/pest-plugin-type-coverage": "^2.8.7|^3.1.0", - "phpstan/phpstan": "^1.12.7", - "spatie/ray": "^1.41", - "symfony/var-dumper": "^6.4.11|^7.1.5" - }, - "type": "library", - "extra": { - "COV": "0.10.3" - }, - "autoload": { - "files": [ - "src/Anthropic.php" - ], - "psr-4": { - "Anthropic\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mozex", - "email": "mozex@alphorld.com" - } - ], - "description": "Anthropic PHP is a supercharged community-maintained PHP API client that allows you to interact with Anthropic API.", - "keywords": [ - "Claude-3-Haiku", - "Claude-3-Opus", - "Claude-3-Sonnet", - "anthropic", - "api", - "claude", - "client", - "language", - "natural", - "php", - "processing", - "sdk" - ], - "support": { - "issues": "https://github.com/mozex/anthropic-php/issues", - "source": "https://github.com/mozex/anthropic-php/tree/1.1.0" - }, - "funding": [ - { - "url": "https://github.com/mozex", - "type": "github" - } - ], - "time": "2024-12-21T11:04:52+00:00" - }, - { - "name": "nesbot/carbon", - "version": "3.8.4", - "source": { - "type": "git", - "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "129700ed449b1f02d70272d2ac802357c8c30c58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58", - "reference": "129700ed449b1f02d70272d2ac802357c8c30c58", - "shasum": "" - }, - "require": { - "carbonphp/carbon-doctrine-types": "<100.0", - "ext-json": "*", - "php": "^8.1", - "psr/clock": "^1.0", - "symfony/clock": "^6.3 || ^7.0", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "require-dev": { - "doctrine/dbal": "^3.6.3 || ^4.0", - "doctrine/orm": "^2.15.2 || ^3.0", - "friendsofphp/php-cs-fixer": "^3.57.2", - "kylekatarnls/multi-tester": "^2.5.3", - "ondrejmirtes/better-reflection": "^6.25.0.4", - "phpmd/phpmd": "^2.15.0", - "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan": "^1.11.2", - "phpunit/phpunit": "^10.5.20", - "squizlabs/php_codesniffer": "^3.9.0" - }, - "bin": [ - "bin/carbon" - ], - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Carbon\\Laravel\\ServiceProvider" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev", - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Carbon\\": "src/Carbon/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "https://markido.com" - }, - { - "name": "kylekatarnls", - "homepage": "https://github.com/kylekatarnls" - } - ], - "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbon.nesbot.com", - "keywords": [ - "date", - "datetime", - "time" - ], - "support": { - "docs": "https://carbon.nesbot.com/docs", - "issues": "https://github.com/briannesbitt/Carbon/issues", - "source": "https://github.com/briannesbitt/Carbon" - }, - "funding": [ - { - "url": "https://github.com/sponsors/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon#sponsor", - "type": "opencollective" - }, - { - "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", - "type": "tidelift" - } - ], - "time": "2024-12-27T09:25:35+00:00" - }, - { - "name": "nette/schema", - "version": "v1.3.2", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", - "reference": "da801d52f0354f70a638673c4a0f04e16529431d", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.4" - }, - "require-dev": { - "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^1.0", - "tracy/tracy": "^2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "๐Ÿ“ Nette Schema: validating data structures against a given Schema.", - "homepage": "https://nette.org", - "keywords": [ - "config", - "nette" - ], - "support": { - "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.2" - }, - "time": "2024-10-06T23:10:23+00:00" - }, - { - "name": "nette/utils", - "version": "v4.0.5", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", - "shasum": "" - }, - "require": { - "php": "8.0 - 8.4" - }, - "conflict": { - "nette/finder": "<3", - "nette/schema": "<1.2.2" - }, - "require-dev": { - "jetbrains/phpstorm-attributes": "dev-master", - "nette/tester": "^2.5", - "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.9" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "๐Ÿ›  Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" - ], - "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.5" - }, - "time": "2024-08-07T15:39:19+00:00" - }, - { - "name": "nunomaduro/termwind", - "version": "v2.3.0", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/termwind.git", - "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", - "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^8.2", - "symfony/console": "^7.1.8" - }, - "require-dev": { - "illuminate/console": "^11.33.2", - "laravel/pint": "^1.18.2", - "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0", - "phpstan/phpstan": "^1.12.11", - "phpstan/phpstan-strict-rules": "^1.6.1", - "symfony/var-dumper": "^7.1.8", - "thecodingmachine/phpstan-strict-rules": "^1.0.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Termwind\\Laravel\\TermwindServiceProvider" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "files": [ - "src/Functions.php" - ], - "psr-4": { - "Termwind\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Its like Tailwind CSS, but for the console.", - "keywords": [ - "cli", - "console", - "css", - "package", - "php", - "style" - ], - "support": { - "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/xiCO2k", - "type": "github" - } - ], - "time": "2024-11-21T10:39:51+00:00" - }, - { - "name": "openai-php/client", - "version": "v0.5.3", - "source": { - "type": "git", - "url": "https://github.com/openai-php/client.git", - "reference": "a0ca38da78f7420a0b381e4274e416abbf6e563d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/openai-php/client/zipball/a0ca38da78f7420a0b381e4274e416abbf6e563d", - "reference": "a0ca38da78f7420a0b381e4274e416abbf6e563d", - "shasum": "" - }, - "require": { - "php": "^8.1.0", - "php-http/discovery": "^1.18.1", - "php-http/multipart-stream-builder": "^1.3.0", - "psr/http-client": "^1.0.2", - "psr/http-client-implementation": "^1.0.1", - "psr/http-factory-implementation": "*", - "psr/http-message": "^1.1.0|^2.0.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^7.7.0", - "guzzlehttp/psr7": "^2.5.0", - "laravel/pint": "^1.10.0", - "nunomaduro/collision": "^7.5.2", - "pestphp/pest": "dev-develop as 2.6.2", - "pestphp/pest-plugin-arch": "^2.2.0", - "pestphp/pest-plugin-mock": "^2.0.0", - "pestphp/pest-plugin-type-coverage": "^2.0.0", - "phpstan/phpstan": "^1.10.15", - "rector/rector": "^0.16.0", - "symfony/var-dumper": "^6.3.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/OpenAI.php" - ], - "psr-4": { - "OpenAI\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - }, - { - "name": "Sandro Gehri" - } - ], - "description": "OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API", - "keywords": [ - "GPT-3", - "api", - "client", - "codex", - "dall-e", - "language", - "natural", - "openai", - "php", - "processing", - "sdk" - ], - "support": { - "issues": "https://github.com/openai-php/client/issues", - "source": "https://github.com/openai-php/client/tree/v0.5.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/gehrisandro", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2023-06-07T16:17:31+00:00" - }, - { - "name": "php-http/discovery", - "version": "1.20.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/discovery.git", - "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", - "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0|^2.0", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "nyholm/psr7": "<1.0", - "zendframework/zend-diactoros": "*" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "*", - "psr/http-factory-implementation": "*", - "psr/http-message-implementation": "*" - }, - "require-dev": { - "composer/composer": "^1.0.2|^2.0", - "graham-campbell/phpspec-skip-example-extension": "^5.0", - "php-http/httplug": "^1.0 || ^2.0", - "php-http/message-factory": "^1.0", - "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", - "sebastian/comparator": "^3.0.5 || ^4.0.8", - "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" - }, - "type": "composer-plugin", - "extra": { - "class": "Http\\Discovery\\Composer\\Plugin", - "plugin-optional": true - }, - "autoload": { - "psr-4": { - "Http\\Discovery\\": "src/" - }, - "exclude-from-classmap": [ - "src/Composer/Plugin.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mรกrk Sรกgi-Kazรกr", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", - "homepage": "http://php-http.org", - "keywords": [ - "adapter", - "client", - "discovery", - "factory", - "http", - "message", - "psr17", - "psr7" - ], - "support": { - "issues": "https://github.com/php-http/discovery/issues", - "source": "https://github.com/php-http/discovery/tree/1.20.0" - }, - "time": "2024-10-02T11:20:13+00:00" - }, - { - "name": "php-http/multipart-stream-builder", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/php-http/multipart-stream-builder.git", - "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/10086e6de6f53489cca5ecc45b6f468604d3460e", - "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "php-http/discovery": "^1.15", - "psr/http-factory-implementation": "^1.0" - }, - "require-dev": { - "nyholm/psr7": "^1.0", - "php-http/message": "^1.5", - "php-http/message-factory": "^1.0.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Http\\Message\\MultipartStream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com" - } - ], - "description": "A builder class that help you create a multipart stream", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "multipart stream", - "stream" - ], - "support": { - "issues": "https://github.com/php-http/multipart-stream-builder/issues", - "source": "https://github.com/php-http/multipart-stream-builder/tree/1.4.2" - }, - "time": "2024-09-04T13:22:54+00:00" - }, - { - "name": "phpoption/phpoption", - "version": "1.9.3", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", - "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", - "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 || ^10.5.28" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2024-07-20T21:41:07+00:00" - }, - { - "name": "psr/clock", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/clock.git", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Clock\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for reading the clock.", - "homepage": "https://github.com/php-fig/clock", - "keywords": [ - "clock", - "now", - "psr", - "psr-20", - "time" - ], - "support": { - "issues": "https://github.com/php-fig/clock/issues", - "source": "https://github.com/php-fig/clock/tree/1.0.0" - }, - "time": "2022-11-25T14:36:26+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": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, - { - "name": "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": "ramsey/collection", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/ramsey/collection.git", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.28.3", - "fakerphp/faker": "^1.21", - "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^1.0", - "mockery/mockery": "^1.5", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcsstandards/phpcsutils": "^1.0.0-rc1", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5", - "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18.4", - "ramsey/coding-standard": "^2.0.3", - "ramsey/conventional-commits": "^1.3", - "vimeo/psalm": "^5.4" - }, - "type": "library", - "extra": { - "captainhook": { - "force-install": true - }, - "ramsey/conventional-commits": { - "configFile": "conventional-commits.json" - } - }, - "autoload": { - "psr-4": { - "Ramsey\\Collection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "A PHP library for representing and manipulating collections.", - "keywords": [ - "array", - "collection", - "hash", - "map", - "queue", - "set" - ], - "support": { - "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", - "type": "tidelift" - } - ], - "time": "2022-12-31T21:50:55+00:00" - }, - { - "name": "ramsey/uuid", - "version": "4.7.6", - "source": { - "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", - "reference": "91039bc1faa45ba123c4328958e620d382ec7088", - "shasum": "" - }, - "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", - "ext-json": "*", - "php": "^8.0", - "ramsey/collection": "^1.2 || ^2.0" - }, - "replace": { - "rhumsaa/uuid": "self.version" - }, - "require-dev": { - "captainhook/captainhook": "^5.10", - "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.8", - "ergebnis/composer-normalize": "^2.15", - "mockery/mockery": "^1.3", - "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.2", - "php-mock/php-mock-mockery": "^1.3", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9", - "ramsey/composer-repl": "^1.4", - "slevomat/coding-standard": "^8.4", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.9" - }, - "suggest": { - "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", - "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", - "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", - "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." - }, - "type": "library", - "extra": { - "captainhook": { - "force-install": true - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Ramsey\\Uuid\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "keywords": [ - "guid", - "identifier", - "uuid" - ], - "support": { - "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.7.6" - }, - "funding": [ - { - "url": "https://github.com/ramsey", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", - "type": "tidelift" - } - ], - "time": "2024-04-27T21:32:50+00:00" - }, - { - "name": "symfony/clock", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", - "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/clock": "^1.0", - "symfony/polyfill-php83": "^1.28" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/now.php" - ], - "psr-4": { - "Symfony\\Component\\Clock\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Decouples applications from the system clock", - "homepage": "https://symfony.com", - "keywords": [ - "clock", - "psr20", - "time" - ], - "support": { - "source": "https://github.com/symfony/clock/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/console", - "version": "v7.2.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "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.2.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-12-11T03:49:26+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-Franรงois Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Converts CSS selectors to XPath expressions", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "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.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { - "name": "symfony/error-handler", - "version": "v7.2.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "6150b89186573046167796fa5f3f76601d5145f8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", - "reference": "6150b89186573046167796fa5f3f76601d5145f8", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^6.4|^7.0" - }, - "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" - }, - "require-dev": { - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/patch-type-declarations" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" - }, - "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 to manage errors and ease debugging PHP code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.2.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-12-07T08:50:44+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "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.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { - "name": "symfony/finder", - "version": "v7.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb", - "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.2.2" - }, - "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-12-30T19:00:17+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v7.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/62d1a43796ca3fea3f83a8470dfe63a4af3bc588", - "reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" - }, - "conflict": { - "doctrine/dbal": "<3.6", - "symfony/cache": "<6.4.12|>=7.0,<7.1.5" - }, - "require-dev": { - "doctrine/dbal": "^3.6|^4", - "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "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": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.2.2" - }, - "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-12-30T19:00:17+00:00" - }, - { - "name": "symfony/http-kernel", - "version": "v7.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3c432966bd8c7ec7429663105f5a02d7e75b4306", - "reference": "3c432966bd8c7ec7429663105f5a02d7e75b4306", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/browser-kit": "<6.4", - "symfony/cache": "<6.4", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<6.4", - "symfony/form": "<6.4", - "symfony/http-client": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<6.4", - "symfony/messenger": "<6.4", - "symfony/translation": "<6.4", - "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<6.4", - "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.4", - "twig/twig": "<3.12" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" - }, - "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^7.1", - "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^7.1", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0", - "symfony/var-exporter": "^6.4|^7.0", - "twig/twig": "^3.12" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "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 structured process for converting a Request into a Response", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.2.2" - }, - "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-12-31T14:59:40+00:00" - }, - { - "name": "symfony/mailer", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/mailer.git", - "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/e4d358702fb66e4c8a2af08e90e7271a62de39cc", - "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc", - "shasum": "" - }, - "require": { - "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.2", - "psr/event-dispatcher": "^1", - "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/mime": "^7.2", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/messenger": "<6.4", - "symfony/mime": "<6.4", - "symfony/twig-bridge": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/twig-bridge": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mailer\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Helps sending emails", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/mailer/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-25T15:21:05+00:00" - }, - { - "name": "symfony/mime", - "version": "v7.2.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283", - "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<6.4", - "symfony/serializer": "<6.4.3|>7.0,<7.0.3" - }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/serializer": "^6.4.3|^7.0.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mime\\": "" - }, - "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": "Allows manipulating MIME messages", - "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" - ], - "support": { - "source": "https://github.com/symfony/mime/tree/v7.2.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-12-07T08:50:44+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": { - "url": "https://github.com/symfony/polyfill", - "name": "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": { - "url": "https://github.com/symfony/polyfill", - "name": "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-idn", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", - "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", - "shasum": "" - }, - "require": { - "php": ">=7.2", - "symfony/polyfill-intl-normalizer": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "idn", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/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": { - "url": "https://github.com/symfony/polyfill", - "name": "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": { - "url": "https://github.com/symfony/polyfill", - "name": "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": { - "url": "https://github.com/symfony/polyfill", - "name": "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-php83", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" - }, - "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.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php83/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-uuid", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-uuid": "*" - }, - "suggest": { - "ext-uuid": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Uuid\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Grรฉgoire Pineau", - "email": "lyrixx@lyrixx.info" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for uuid functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "uuid" - ], - "support": { - "source": "https://github.com/symfony/polyfill-uuid/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.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", - "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", - "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.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-06T14:24:19+00:00" - }, - { - "name": "symfony/routing", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", - "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/config": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/yaml": "<6.4" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Routing\\": "" - }, - "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": "Maps an HTTP request to a set of configuration variables", - "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], - "support": { - "source": "https://github.com/symfony/routing/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-25T11:08:51+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { - "name": "symfony/string", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", - "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.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-13T13:31:26+00:00" - }, - { - "name": "symfony/translation", - "version": "v7.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923", - "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5|^3.0" - }, - "conflict": { - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<6.4", - "symfony/yaml": "<6.4" - }, - "provide": { - "symfony/translation-implementation": "2.3|3.0" - }, - "require-dev": { - "nikic/php-parser": "^4.18|^5.0", - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "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 to internationalize your application", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/translation/tree/v7.2.2" - }, - "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-12-07T08:18:10+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v3.5.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", - "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.5-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Translation\\": "" - }, - "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 translation", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" - }, - { - "name": "symfony/uid", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/uid.git", - "reference": "2d294d0c48df244c71c105a169d0190bfb080426" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", - "reference": "2d294d0c48df244c71c105a169d0190bfb080426", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-uuid": "^1.15" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Uid\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Grรฉgoire Pineau", - "email": "lyrixx@lyrixx.info" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an object-oriented API to generate and represent UIDs", - "homepage": "https://symfony.com", - "keywords": [ - "UID", - "ulid", - "uuid" - ], - "support": { - "source": "https://github.com/symfony/uid/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:21:43+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", - "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "ext-iconv": "*", - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", - "twig/twig": "^3.12" - }, - "bin": [ - "Resources/bin/var-dump-server" - ], - "type": "library", - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "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 mechanisms for walking through any arbitrary PHP variable", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-08T15:48:14+00:00" - }, - { - "name": "tijsverkoyen/css-to-inline-styles", - "version": "v2.3.0", - "source": { - "type": "git", - "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d", - "reference": "0d72ac1c00084279c1816675284073c5a337c20d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "php": "^7.4 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.0 || ^7.0" - }, - "require-dev": { - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^8.5.21 || ^9.5.10" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "TijsVerkoyen\\CssToInlineStyles\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Tijs Verkoyen", - "email": "css_to_inline_styles@verkoyen.eu", - "role": "Developer" - } - ], - "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", - "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", - "support": { - "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0" - }, - "time": "2024-12-21T16:25:41+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.1", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.3", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.3", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2024-07-20T21:52:34+00:00" - }, - { - "name": "voku/portable-ascii", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/voku/portable-ascii.git", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "shasum": "" - }, - "require": { - "php": ">=7.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" - }, - "suggest": { - "ext-intl": "Use Intl for transliterator_transliterate() support" - }, - "type": "library", - "autoload": { - "psr-4": { - "voku\\": "src/voku/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Lars Moelleken", - "homepage": "https://www.moelleken.org/" - } - ], - "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", - "homepage": "https://github.com/voku/portable-ascii", - "keywords": [ - "ascii", - "clean", - "php" - ], - "support": { - "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.3" - }, - "funding": [ - { - "url": "https://www.paypal.me/moelleken", - "type": "custom" - }, - { - "url": "https://github.com/voku", - "type": "github" - }, - { - "url": "https://opencollective.com/portable-ascii", - "type": "open_collective" - }, - { - "url": "https://www.patreon.com/voku", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", - "type": "tidelift" - } - ], - "time": "2024-11-21T01:49:47+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "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": "fakerphp/faker", - "version": "v1.24.1", - "source": { - "type": "git", - "url": "https://github.com/FakerPHP/Faker.git", - "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", - "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "conflict": { - "fzaninotto/faker": "*" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "doctrine/persistence": "^1.3 || ^2.0", - "ext-intl": "*", - "phpunit/phpunit": "^9.5.26", - "symfony/phpunit-bridge": "^5.4.16" - }, - "suggest": { - "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", - "ext-curl": "Required by Faker\\Provider\\Image to download images.", - "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", - "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", - "ext-mbstring": "Required for multibyte Unicode string functionality." - }, - "type": "library", - "autoload": { - "psr-4": { - "Faker\\": "src/Faker/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franรงois Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "support": { - "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" - }, - "time": "2024-11-21T13:46:39+00:00" - }, - { - "name": "filp/whoops", - "version": "2.16.0", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.16.0" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2024-09-25T12:00:00+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "shasum": "" - }, - "require": { - "php": "^5.3|^7.0|^8.0" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "hamcrest" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "support": { - "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" - }, - "time": "2020-07-09T08:09:16+00:00" - }, - { - "name": "laravel/pail", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/pail.git", - "reference": "353ac12134b98e2e7c3333d916bd3e523931e583" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/353ac12134b98e2e7c3333d916bd3e523931e583", - "reference": "353ac12134b98e2e7c3333d916bd3e523931e583", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "illuminate/console": "^10.24|^11.0", - "illuminate/contracts": "^10.24|^11.0", - "illuminate/log": "^10.24|^11.0", - "illuminate/process": "^10.24|^11.0", - "illuminate/support": "^10.24|^11.0", - "nunomaduro/termwind": "^1.15|^2.0", - "php": "^8.2", - "symfony/console": "^6.0|^7.0" - }, - "require-dev": { - "laravel/framework": "^10.24|^11.0", - "laravel/pint": "^1.13", - "orchestra/testbench-core": "^8.12|^9.0", - "pestphp/pest": "^2.20", - "pestphp/pest-plugin-type-coverage": "^2.3", - "phpstan/phpstan": "^1.10", - "symfony/var-dumper": "^6.3|^7.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Pail\\PailServiceProvider" - ] - }, - "branch-alias": { - "dev-main": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Pail\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Easily delve into your Laravel application's log files directly from the command line.", - "homepage": "https://github.com/laravel/pail", - "keywords": [ - "laravel", - "logs", - "php", - "tail" - ], - "support": { - "issues": "https://github.com/laravel/pail/issues", - "source": "https://github.com/laravel/pail" - }, - "time": "2024-10-23T12:56:23+00:00" - }, - { - "name": "laravel/tinker", - "version": "v2.10.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/tinker.git", - "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/ba4d51eb56de7711b3a37d63aa0643e99a339ae5", - "reference": "ba4d51eb56de7711b3a37d63aa0643e99a339ae5", - "shasum": "" - }, - "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", - "php": "^7.2.5|^8.0", - "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" - }, - "require-dev": { - "mockery/mockery": "~1.3.3|^1.4.2", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.8|^9.3.3" - }, - "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Tinker\\TinkerServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Tinker\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Powerful REPL for the Laravel framework.", - "keywords": [ - "REPL", - "Tinker", - "laravel", - "psysh" - ], - "support": { - "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.10.0" - }, - "time": "2024-09-23T13:32:56+00:00" - }, - { - "name": "mockery/mockery", - "version": "1.6.12", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", - "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "^2.0.1", - "lib-pcre": ">=7.0", - "php": ">=7.3" - }, - "conflict": { - "phpunit/phpunit": "<8.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.6.17", - "symplify/easy-coding-standard": "^12.1.14" - }, - "type": "library", - "autoload": { - "files": [ - "library/helpers.php", - "library/Mockery.php" - ], - "psr-4": { - "Mockery\\": "library/Mockery" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pรกdraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "https://github.com/padraic", - "role": "Author" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "https://davedevelopment.co.uk", - "role": "Developer" - }, - { - "name": "Nathanael Esayeas", - "email": "nathanael.esayeas@protonmail.com", - "homepage": "https://github.com/ghostwriter", - "role": "Lead Developer" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework", - "homepage": "https://github.com/mockery/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "support": { - "docs": "https://docs.mockery.io/", - "issues": "https://github.com/mockery/mockery/issues", - "rss": "https://github.com/mockery/mockery/releases.atom", - "security": "https://github.com/mockery/mockery/security/advisories", - "source": "https://github.com/mockery/mockery" - }, - "time": "2024-05-16T03:13:13+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.12.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", - "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.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2024-11-08T17:47:46+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.4.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", - "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.4.0" - }, - "time": "2024-12-30T11:07:19+00:00" - }, - { - "name": "nunomaduro/collision", - "version": "v8.5.0", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "f5c101b929c958e849a633283adff296ed5f38f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", - "reference": "f5c101b929c958e849a633283adff296ed5f38f5", - "shasum": "" - }, - "require": { - "filp/whoops": "^2.16.0", - "nunomaduro/termwind": "^2.1.0", - "php": "^8.2.0", - "symfony/console": "^7.1.5" - }, - "conflict": { - "laravel/framework": "<11.0.0 || >=12.0.0", - "phpunit/phpunit": "<10.5.1 || >=12.0.0" - }, - "require-dev": { - "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.28.0", - "laravel/pint": "^1.18.1", - "laravel/sail": "^1.36.0", - "laravel/sanctum": "^4.0.3", - "laravel/tinker": "^2.10.0", - "orchestra/testbench-core": "^9.5.3", - "pestphp/pest": "^2.36.0 || ^3.4.0", - "sebastian/environment": "^6.1.0 || ^7.2.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - }, - "branch-alias": { - "dev-8.x": "8.x-dev" - } - }, - "autoload": { - "files": [ - "./src/Adapters/Phpunit/Autoload.php" - ], - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2024-10-15T16:06:32+00:00" - }, - { - "name": "orchestra/canvas", - "version": "v9.2.0", - "source": { - "type": "git", - "url": "https://github.com/orchestral/canvas.git", - "reference": "b7156c011d780ee1e09a66eb73a38bfa23db759a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas/zipball/b7156c011d780ee1e09a66eb73a38bfa23db759a", - "reference": "b7156c011d780ee1e09a66eb73a38bfa23db759a", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "composer/semver": "^3.0", - "illuminate/console": "^11.35", - "illuminate/database": "^11.35", - "illuminate/filesystem": "^11.35", - "illuminate/support": "^11.35", - "orchestra/canvas-core": "^9.0", - "orchestra/testbench-core": "^9.7", - "php": "^8.2", - "symfony/polyfill-php83": "^1.31", - "symfony/yaml": "^7.0.3" - }, - "require-dev": { - "laravel/framework": "^11.35", - "laravel/pint": "^1.17", - "mockery/mockery": "^1.6.10", - "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "^11.3.6", - "spatie/laravel-ray": "^1.35" - }, - "bin": [ - "canvas" - ], - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Orchestra\\Canvas\\LaravelServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Orchestra\\Canvas\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Mior Muhammad Zaki", - "email": "crynobone@gmail.com" - } - ], - "description": "Code Generators for Laravel Applications and Packages", - "support": { - "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas/tree/v9.2.0" - }, - "time": "2024-11-30T15:48:36+00:00" - }, - { - "name": "orchestra/canvas-core", - "version": "v9.0.0", - "source": { - "type": "git", - "url": "https://github.com/orchestral/canvas-core.git", - "reference": "3a29eecf324fe02e3e5628e422314b5cd1a80e48" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/3a29eecf324fe02e3e5628e422314b5cd1a80e48", - "reference": "3a29eecf324fe02e3e5628e422314b5cd1a80e48", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "composer/semver": "^3.0", - "illuminate/console": "^11.0", - "illuminate/filesystem": "^11.0", - "php": "^8.2", - "symfony/polyfill-php83": "^1.28" - }, - "require-dev": { - "laravel/framework": "^11.0", - "laravel/pint": "^1.6", - "mockery/mockery": "^1.5.1", - "orchestra/testbench-core": "^9.0", - "phpstan/phpstan": "^1.10.6", - "phpunit/phpunit": "^10.1", - "symfony/yaml": "^7.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Orchestra\\Canvas\\Core\\LaravelServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "9.0-dev" - } - }, - "autoload": { - "psr-4": { - "Orchestra\\Canvas\\Core\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Mior Muhammad Zaki", - "email": "crynobone@gmail.com" - } - ], - "description": "Code Generators Builder for Laravel Applications and Packages", - "support": { - "issues": "https://github.com/orchestral/canvas/issues", - "source": "https://github.com/orchestral/canvas-core/tree/v9.0.0" - }, - "time": "2024-03-06T10:00:21+00:00" - }, - { - "name": "orchestra/testbench", - "version": "v9.9.0", - "source": { - "type": "git", - "url": "https://github.com/orchestral/testbench.git", - "reference": "2f3e8c687ca5c0bd4d8bc91c4448983d046ba32b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/2f3e8c687ca5c0bd4d8bc91c4448983d046ba32b", - "reference": "2f3e8c687ca5c0bd4d8bc91c4448983d046ba32b", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "fakerphp/faker": "^1.23", - "laravel/framework": "^11.35.0", - "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^9.9.0", - "orchestra/workbench": "^9.13.0", - "php": "^8.2", - "phpunit/phpunit": "^10.5.35 || ^11.3.6", - "symfony/process": "^7.0.3", - "symfony/yaml": "^7.0.3", - "vlucas/phpdotenv": "^5.6.1" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mior Muhammad Zaki", - "email": "crynobone@gmail.com", - "homepage": "https://github.com/crynobone" - } - ], - "description": "Laravel Testing Helper for Packages Development", - "homepage": "https://packages.tools/testbench/", - "keywords": [ - "BDD", - "TDD", - "dev", - "laravel", - "laravel-packages", - "testing" - ], - "support": { - "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench/tree/v9.9.0" - }, - "time": "2024-12-25T23:40:19+00:00" - }, - { - "name": "orchestra/testbench-core", - "version": "v9.9.1", - "source": { - "type": "git", - "url": "https://github.com/orchestral/testbench-core.git", - "reference": "ad211dc59c830a987eb34c18742f9c7875178eae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/ad211dc59c830a987eb34c18742f9c7875178eae", - "reference": "ad211dc59c830a987eb34c18742f9c7875178eae", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "php": "^8.2", - "symfony/polyfill-php83": "^1.31", - "symfony/polyfill-php84": "^1.31" - }, - "conflict": { - "brianium/paratest": "<7.3.0 || >=8.0.0", - "laravel/framework": "<11.35.0 || >=12.0.0", - "laravel/serializable-closure": "<1.3.0 || >=3.0.0", - "nunomaduro/collision": "<8.0.0 || >=9.0.0", - "orchestra/testbench-dusk": "<9.10.0 || >=10.0.0", - "phpunit/phpunit": "<10.5.35 || >=11.0.0 <11.3.6 || >=11.6.0" - }, - "require-dev": { - "fakerphp/faker": "^1.24", - "laravel/framework": "^11.35.0", - "laravel/pint": "^1.17", - "laravel/serializable-closure": "^1.3 || ^2.0", - "mockery/mockery": "^1.6.10", - "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^10.5.35 || ^11.3.6", - "spatie/laravel-ray": "^1.39", - "symfony/process": "^7.0.3", - "symfony/yaml": "^7.0.3", - "vlucas/phpdotenv": "^5.6.1" - }, - "suggest": { - "brianium/paratest": "Allow using parallel testing (^7.3).", - "ext-pcntl": "Required to use all features of the console signal trapping.", - "fakerphp/faker": "Allow using Faker for testing (^1.23).", - "laravel/framework": "Required for testing (^11.35.0).", - "mockery/mockery": "Allow using Mockery for testing (^1.6).", - "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^8.0).", - "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^9.0).", - "phpunit/phpunit": "Allow using PHPUnit for testing (^10.5 || ^11.0).", - "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^7.0).", - "symfony/yaml": "Required for Testbench CLI (^7.0).", - "vlucas/phpdotenv": "Required for Testbench CLI (^5.4.1)." - }, - "bin": [ - "testbench" - ], - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Orchestra\\Testbench\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mior Muhammad Zaki", - "email": "crynobone@gmail.com", - "homepage": "https://github.com/crynobone" - } - ], - "description": "Testing Helper for Laravel Development", - "homepage": "https://packages.tools/testbench", - "keywords": [ - "BDD", - "TDD", - "dev", - "laravel", - "laravel-packages", - "testing" - ], - "support": { - "issues": "https://github.com/orchestral/testbench/issues", - "source": "https://github.com/orchestral/testbench-core" - }, - "time": "2025-01-07T02:00:47+00:00" - }, - { - "name": "orchestra/workbench", - "version": "v9.13.0", - "source": { - "type": "git", - "url": "https://github.com/orchestral/workbench.git", - "reference": "9c9a42060735bfb49b1298c39dba392f936de372" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/orchestral/workbench/zipball/9c9a42060735bfb49b1298c39dba392f936de372", - "reference": "9c9a42060735bfb49b1298c39dba392f936de372", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.2", - "fakerphp/faker": "^1.23", - "laravel/framework": "^11.35", - "laravel/pail": "^1.2", - "laravel/tinker": "^2.9", - "nunomaduro/collision": "^8.0", - "orchestra/canvas": "^9.1", - "orchestra/testbench-core": "^9.9.0", - "php": "^8.2", - "symfony/polyfill-php83": "^1.31", - "symfony/polyfill-php84": "^1.31", - "symfony/process": "^7.0.3", - "symfony/yaml": "^7.0.3" - }, - "require-dev": { - "laravel/pint": "^1.17", - "mockery/mockery": "^1.6.10", - "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^10.5.35 || ^11.3.6", - "spatie/laravel-ray": "^1.39" - }, - "suggest": { - "ext-pcntl": "Required to use all features of the console signal trapping." - }, - "type": "library", - "autoload": { - "psr-4": { - "Orchestra\\Workbench\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mior Muhammad Zaki", - "email": "crynobone@gmail.com" - } - ], - "description": "Workbench Companion for Laravel Packages Development", - "keywords": [ - "dev", - "laravel", - "laravel-packages", - "testing" - ], - "support": { - "issues": "https://github.com/orchestral/workbench/issues", - "source": "https://github.com/orchestral/workbench/tree/v9.13.0" - }, - "time": "2024-12-24T11:40:02+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": "phpunit/php-code-coverage", - "version": "10.1.16", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", - "theseer/tokenizer": "^1.2.3" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "10.1.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/10.1.16" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-08-22T04:31:57+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "4.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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/4.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T06:24:48+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "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": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:56:09+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-08-31T14:07:24+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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", - "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", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:57:52+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "10.5.40", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6ddda95af52f69c1e0c7b4f977cccb58048798c", - "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "10.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.40" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2024-12-21T05:49:06+00:00" - }, - { - "name": "psy/psysh", - "version": "v0.12.7", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", - "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-tokenizer": "*", - "nikic/php-parser": "^5.0 || ^4.0", - "php": "^8.0 || ^7.4", - "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", - "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" - }, - "conflict": { - "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.2" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." - }, - "bin": [ - "bin/psysh" - ], - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": false, - "forward-command": false - }, - "branch-alias": { - "dev-main": "0.12.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Psy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", - "keywords": [ - "REPL", - "console", - "interactive", - "shell" - ], - "support": { - "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.7" - }, - "time": "2024-12-10T01:58:33+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:12:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:59:15+00:00" - }, - { - "name": "sebastian/comparator", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.5" - }, - "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" - }, - { - "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-10-18T14:56:07+00:00" - }, - { - "name": "sebastian/complexity", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.2-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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-21T08:37:17+00:00" - }, - { - "name": "sebastian/diff", - "version": "5.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" - }, - "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" - }, - { - "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/5.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:15:17+00:00" - }, - { - "name": "sebastian/environment", - "version": "6.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "suggest": { - "ext-posix": "*" - }, - "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" - } - ], - "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/6.1.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-23T08:47:14+00:00" - }, - { - "name": "sebastian/exporter", - "version": "5.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "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" - }, - { - "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/5.1.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:17:12+00:00" - }, - { - "name": "sebastian/global-state", - "version": "6.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^10.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": "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/6.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:19:19+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.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/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-12-21T08:38:20+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "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", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:08:32+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:06:18+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - }, - { - "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", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:05:40+00:00" - }, - { - "name": "sebastian/type", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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": "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", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T07:10:45+00:00" - }, - { - "name": "sebastian/version", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "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 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", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "symfony/polyfill-php84", - "version": "v1.31.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/e5493eb51311ab0b1cc2243416613f06ed8f18bd", - "reference": "e5493eb51311ab0b1cc2243416613f06ed8f18bd", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php84\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.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-09T12:04:04+00:00" - }, - { - "name": "symfony/yaml", - "version": "v7.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "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.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-10-23T06:56:12+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": "dev", - "stability-flags": [], - "prefer-stable": true, - "prefer-lowest": false, - "platform": { - "php": "^8.1" - }, - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/config/mtn-momo-ai.php b/config/mtn-momo-ai.php index f2bf1a1..000cde3 100644 --- a/config/mtn-momo-ai.php +++ b/config/mtn-momo-ai.php @@ -5,12 +5,62 @@ |-------------------------------------------------------------------------- | MTN MOMO API Configuration |-------------------------------------------------------------------------- + | + | This section contains the core configuration for the MTN Mobile Money API. + | These settings are essential for authenticating and interacting with the + | MTN MOMO API services including Collections, Disbursements, and Remittances. + | */ - 'api_user' => env('MTN_MOMO_API_USER'), - 'api_key' => env('MTN_MOMO_API_KEY'), - 'subscription_key' => env('MTN_MOMO_SUBSCRIPTION_KEY'), + + /** + * The API User ID (UUID v4) used to identify your application. + * This is automatically generated during installation and used + * for authentication with the MTN MOMO API. + * Format: UUID v4 (e.g., '0a60b622-d1a5-4306-8f6b-8551779bf811') + */ + 'api_user' => env('MTN_MOMO_API_USER', null), + + /** + * The API Key generated for your API User. + * This is automatically created when setting up your API User + * and is used for API authentication. + * Keep this value secure and never expose it publicly. + */ + 'api_key' => env('MTN_MOMO_API_KEY', null), + + /** + * Your MTN MOMO API Subscription Key. + * This key is provided when you subscribe to MTN MOMO API products + * (Collections, Disbursements, or Remittances) in the MTN Developer Portal. + * Required for all API calls. + */ + 'subscription_key' => env('MTN_MOMO_SUBSCRIPTION_KEY', null), + + /** + * The base URL for the MTN MOMO API. + * - Sandbox: 'https://sandbox.momodeveloper.mtn.com' + * - Production: 'https://momodeveloper.mtn.com' + */ 'base_url' => env('MTN_MOMO_BASE_URL', 'https://sandbox.momodeveloper.mtn.com'), + + /** + * The callback host for your application. + * This URL will receive webhook notifications for transactions. + * Must be a publicly accessible HTTPS URL in production. + */ + 'callback_host' => env('MTN_MOMO_PROVIDER_CALLBACK_HOST', 'http://localhost'), + + /** + * The default currency for transactions. + * This setting determines the default currency used when not explicitly specified. + * Must be one of the supported currencies listed below. + */ 'default_currency' => env('MTN_MOMO_DEFAULT_CURRENCY', 'EUR'), + + /** + * List of supported currencies for MTN MOMO transactions. + * Each currency must be supported by the MTN MOMO API in your region. + */ 'supported_currencies' => [ 'EUR' => 'Euro', 'USD' => 'US Dollar', @@ -19,29 +69,65 @@ 'XAF' => 'Central African CFA Franc', 'XOF' => 'West African CFA Franc', ], + + /** + * The API environment (sandbox or production). + * - 'sandbox': For development and testing + * - 'production': For live transactions + */ 'environment' => env('MTN_MOMO_ENVIRONMENT', 'sandbox'), + + /** + * The API version to use. + * Currently supported version is 'v1_0'. + * Future versions will be added as they become available. + */ 'version' => env('MTN_MOMO_API_VERSION', 'v1_0'), + + /** + * The timeout for API requests in seconds. + * Adjust based on your needs, but keep in mind MTN MOMO API's own timeout limits. + */ 'timeout' => env('MTN_MOMO_TIMEOUT', 30), /* |-------------------------------------------------------------------------- | AI Models Configuration |-------------------------------------------------------------------------- + | + | Configuration for various AI models used to enhance MTN MOMO operations. + | Each model can be used for transaction analysis, fraud detection, + | and other AI-powered features. + | */ + + /** + * The default AI model to use when none is specified. + * Options: 'ChatGPT', 'Claude', 'Gemini' + */ 'default_llm' => env('DEFAULT_LLM', 'ChatGPT'), + /** + * OpenAI (ChatGPT) Configuration + */ 'chatgpt' => [ 'api_key' => env('OPENAI_API_KEY'), 'organization' => env('OPENAI_ORGANIZATION'), 'model' => env('OPENAI_MODEL', 'gpt-3.5-turbo'), ], + /** + * Anthropic (Claude) Configuration + */ 'claude' => [ 'api_key' => env('ANTHROPIC_API_KEY'), 'model' => env('ANTHROPIC_MODEL', 'claude-3-opus-20240229'), 'request_timeout' => env('ANTHROPIC_REQUEST_TIMEOUT', 30), ], + /** + * Google (Gemini) Configuration + */ 'gemini' => [ 'api_key' => env('GEMINI_API_KEY'), 'model' => env('GEMINI_MODEL', 'gemini-pro'), @@ -51,13 +137,30 @@ |-------------------------------------------------------------------------- | AI Feature Configuration |-------------------------------------------------------------------------- + | + | Settings for AI-enhanced features and reporting capabilities. + | */ + + /** + * The preferred AI model for generating reports. + * This model will be used specifically for report generation tasks. + */ 'reporting_llm' => env('REPORTING_LLM', 'ChatGPT'), /* |-------------------------------------------------------------------------- | Alerting Configuration |-------------------------------------------------------------------------- + | + | Configuration for the package's alerting system, including + | anomaly detection and notification settings. + | */ + + /** + * The email address that will receive alerts about anomalies, + * potential fraud, and other important notifications. + */ 'alert_email' => env('MTN_MOMO_ALERT_EMAIL'), ]; diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..b6cc728 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,12 @@ +parameters: + level: 8 + paths: + - src + - tests + excludePaths: + - vendor/* + ignoreErrors: + - '#PHPDoc tag @var#' + - '#Call to an undefined method#' + reportUnmatchedIgnoredErrors: false + treatPhpDocTypesAsCertain: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2bcb9f7 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,43 @@ + + + + + tests + + + + + ./src + + + + + + + + + + + + + + + diff --git a/src/AI/Interfaces/LLMInterface.php b/src/AI/Interfaces/LLMInterface.php index 4a06462..a81deb0 100644 --- a/src/AI/Interfaces/LLMInterface.php +++ b/src/AI/Interfaces/LLMInterface.php @@ -4,14 +4,85 @@ interface LLMInterface { + /** + * Analyze transaction data and provide insights + * + * @param array $data Transaction data containing details like amount, currency, parties involved + * @return string Detailed analysis of the transaction + */ public function analyze($data); + + /** + * Detect potential fraudulent activity in transaction data + * + * @param array $data Transaction data to analyze for fraud patterns + * @return array Fraud analysis results with risk level and explanations + */ public function detectFraud($data); + + /** + * Suggest optimal retry strategy for failed transactions + * + * @param array $data Failed transaction data including error details + * @return array Retry strategy with timing and modified parameters + */ public function suggestRetryStrategy($data); + + /** + * Forecast cash flow based on historical transaction data + * + * @param array $data Historical transaction data + * @return array Projected cash flow with trends and predictions + */ public function forecastCashFlow($data); + + /** + * Parse natural language commands into structured transaction data + * + * @param string $command Natural language command (e.g., "Send 100 USD to John") + * @return array Structured command data with action and parameters + */ public function parseCommand($command); + + /** + * Generate comprehensive transaction report + * + * @param array $data Transaction data for the reporting period + * @return array Formatted report with insights and statistics + */ public function generateReport($data); + + /** + * Suggest optimal disbursement timing based on various factors + * + * @param float $amount Amount to be disbursed + * @param string $recipient Recipient identifier + * @return string Suggested optimal time for disbursement + */ public function suggestDisbursementTime($amount, $recipient); + + /** + * Detect anomalies in transaction patterns + * + * @param array $data Transaction data to analyze for anomalies + * @return array Detected anomalies with severity levels and descriptions + */ public function detectAnomalies($data); + + /** + * Suggest optimal API call timing based on usage patterns + * + * @param array $data API usage data and patterns + * @return array Suggested optimal call times with reasoning + */ public function suggestOptimalCallTimes($data); + + /** + * Provide detailed explanation of error codes in context + * + * @param string $errorCode The error code to explain + * @param array $context Additional context about the error + * @return array Detailed error explanation with suggested solutions + */ public function explainError($errorCode, $context); } diff --git a/src/AI/LLMFactory.php b/src/AI/LLMFactory.php index 5b86d7b..f440c77 100644 --- a/src/AI/LLMFactory.php +++ b/src/AI/LLMFactory.php @@ -8,15 +8,52 @@ use AlvinCoded\MtnMomoAi\AI\Interfaces\LLMInterface; use InvalidArgumentException; +/** + * Factory class for creating Language Learning Model (LLM) instances. + * + * This factory provides a centralized way to create instances of different + * AI models (ChatGPT, Claude, Gemini) that implement the LLMInterface. + * Each model is configured using the settings provided in the config file. + */ class LLMFactory { + /** + * Configuration array containing settings for all supported LLM models. + * + * @var array + */ protected $config; + /** + * Initialize the LLM Factory with configuration settings. + * + * The config array should contain separate configurations for each + * supported model (chatgpt, claude, gemini) with their respective + * API keys and model-specific settings. + * + * @param array $config Configuration array from config/mtn-momo-ai.php + */ public function __construct(array $config) { $this->config = $config; } + /** + * Create and return an instance of the specified LLM model. + * + * This method instantiates the appropriate AI model based on the + * provided model name. Each model is initialized with its specific + * configuration from the config array. + * + * Supported models: + * - ChatGPT: OpenAI's GPT model for general analysis and text generation + * - Claude: Anthropic's Claude model for complex reasoning + * - Gemini: Google's Gemini model for natural language processing + * + * @param string $model The name of the LLM model to create ('ChatGPT', 'Claude', or 'Gemini') + * @return LLMInterface An instance of the requested LLM model + * @throws InvalidArgumentException If an unsupported model is requested + */ public function create(string $model): LLMInterface { switch ($model) { diff --git a/src/AI/Models/ChatGPT.php b/src/AI/Models/ChatGPT.php index 360519c..b6d85c8 100644 --- a/src/AI/Models/ChatGPT.php +++ b/src/AI/Models/ChatGPT.php @@ -5,93 +5,174 @@ use AlvinCoded\MtnMomoAi\AI\Interfaces\LLMInterface; use OpenAI\Factory as OpenAIFactory; +/** + * ChatGPT AI Model Implementation for MTN MOMO API + * + * This class implements the LLMInterface to provide AI-powered analysis and insights + * for MTN Mobile Money transactions using OpenAI's GPT models. + */ class ChatGPT implements LLMInterface { + /** @var \OpenAI\Client OpenAI API client instance */ protected $client; + + /** @var array Configuration settings for the ChatGPT model */ protected $config; + /** + * Initialize ChatGPT client with configuration + * + * @param array $config Configuration array containing api_key, organization, and model settings + */ public function __construct(array $config) { $this->config = $config; - - // Initialize the OpenAI client using the Factory pattern $factory = new OpenAIFactory(); - - // Optionally set the organization if available - if (! empty($config['organization'])) { + + if (!empty($config['organization'])) { $factory->withOrganization($config['organization']); } - - // Build the final OpenAI client instance + $this->client = $factory->withApiKey($config['api_key'])->make(); } + /** + * Analyze transaction data across all MOMO services + * + * @param array $data Transaction data including status, amounts, and patterns + * @return string Analysis results and insights + */ public function analyze($data) { - $prompt = "Analyze the following transaction data and provide insights:\n\n" . json_encode($data); + $prompt = "Analyze this MTN MOMO transaction data across collections, disbursements, and remittances. Consider transaction status, amounts, and patterns:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Detect potential fraud in transaction data + * + * @param array $data Transaction data to evaluate for fraud indicators + * @return string Fraud analysis results and risk assessment + */ public function detectFraud($data) { - $prompt = "Evaluate the following transaction for potential fraud:\n\n" . json_encode($data); + $prompt = "Evaluate this MTN MOMO transaction for potential fraud indicators. Consider transaction type (collection/disbursement/remittance), amount patterns, and account holder behavior:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Suggest retry strategy for failed transactions + * + * @param array $data Failed transaction data including error codes and history + * @return string Recommended retry strategy + */ public function suggestRetryStrategy($data) { - $prompt = "Suggest a retry strategy for the following failed transaction:\n\n" . json_encode($data); + $prompt = "Based on this failed MTN MOMO transaction data, suggest an optimal retry strategy considering the transaction type, error codes, and historical success patterns:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Forecast cash flow based on historical data + * + * @param array $data Historical transaction data + * @return string Cash flow forecast and trends analysis + */ public function forecastCashFlow($data) { - $prompt = "Forecast cash flow based on the following historical data:\n\n" . json_encode($data); + $prompt = "Analyze this MTN MOMO historical transaction data across collections, disbursements, and remittances to forecast future cash flow patterns and trends:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Parse natural language commands into API requests + * + * @param string $command Natural language command to parse + * @return array|string Structured API request parameters + */ public function parseCommand($command) { - $prompt = "Parse the following natural language command into structured data:\n\n" . $command; + $prompt = "Parse this natural language command into a structured MTN MOMO API request format. Consider valid transaction types (collection/disbursement/remittance) and required parameters:\n\n" . $command; return $this->generateResponse($prompt); } + /** + * Generate comprehensive transaction report + * + * @param array $data Transaction data to analyze + * @return string Detailed transaction report + */ public function generateReport($data) { - $prompt = "Generate a comprehensive report based on the following transaction data:\n\n" . json_encode($data); + $prompt = "Generate a comprehensive MTN MOMO transaction report analyzing patterns across collections, disbursements, and remittances. Include transaction volumes, success rates, and notable trends:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Suggest optimal disbursement timing + * + * @param float $amount Amount to disburse + * @param string $recipient Recipient identifier + * @return string Suggested optimal disbursement time + */ public function suggestDisbursementTime($amount, $recipient) { - $prompt = "Suggest an optimal disbursement time for the following transaction:\nAmount: $amount\nRecipient: $recipient"; + $prompt = "Suggest an optimal disbursement time for this MTN MOMO transfer considering amount: $amount, recipient: $recipient. Consider historical transaction patterns and success rates."; return $this->generateResponse($prompt); } + /** + * Detect transaction anomalies + * + * @param array $data Transaction data to analyze for anomalies + * @return array|string Detected anomalies and their details + */ public function detectAnomalies($data) { - $prompt = "Detect any anomalies in the following transaction data:\n\n" . json_encode($data); + $prompt = "Analyze this MTN MOMO transaction data to detect anomalies across collections, disbursements, and remittances. Consider unusual patterns, amounts, frequencies, and account behaviors:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Suggest optimal API call timing + * + * @param array $data API usage data and patterns + * @return string Suggested optimal call times + */ public function suggestOptimalCallTimes($data) { - $prompt = "Suggest optimal API call times based on the following usage data:\n\n" . json_encode($data); + $prompt = "Based on this MTN MOMO API usage data, suggest optimal times for API calls considering success rates, response times, and error patterns:\n\n" . json_encode($data); return $this->generateResponse($prompt); } + /** + * Explain API errors with context + * + * @param string $errorCode The error code to explain + * @param array $context Additional context about the error + * @return string Detailed error explanation and resolution steps + */ public function explainError($errorCode, $context) { - $prompt = "Explain the following error in the context of an MTN MOMO API transaction:\nError Code: $errorCode\nContext: " . json_encode($context); + $prompt = "Explain this MTN MOMO API error in context of the transaction. Provide potential causes and resolution steps:\nError Code: $errorCode\nContext: " . json_encode($context); return $this->generateResponse($prompt); } + /** + * Generate AI response using OpenAI's chat completion + * + * @param string $prompt The prompt to send to the AI model + * @return string Generated response from the AI model + */ protected function generateResponse($prompt) { $response = $this->client->chat()->create([ 'model' => $this->config['model'] ?? 'gpt-3.5-turbo', 'messages' => [ - ['role' => 'system', 'content' => 'You are an AI assistant specialized in analyzing MTN MOMO transactions and providing insights.'], + [ + 'role' => 'system', + 'content' => 'You are an AI assistant specialized in MTN Mobile Money API operations, including collections, disbursements, and remittances. Provide detailed analysis and actionable insights.' + ], ['role' => 'user', 'content' => $prompt], ], 'temperature' => 0.7, diff --git a/src/AI/Models/Claude.php b/src/AI/Models/Claude.php index 7357764..248335f 100644 --- a/src/AI/Models/Claude.php +++ b/src/AI/Models/Claude.php @@ -5,70 +5,160 @@ use AlvinCoded\MtnMomoAi\AI\Interfaces\LLMInterface; use Anthropic\Laravel\Facades\Anthropic; +/** + * Claude AI Model Implementation for MTN MOMO API + * + * This class implements the LLMInterface to provide AI-powered analysis and insights + * for MTN Mobile Money transactions using Anthropic's Claude models. + */ class Claude implements LLMInterface { + /** @var array Configuration settings for the Claude model */ protected $config; + /** + * Initialize Claude with configuration + * + * @param array $config Configuration array containing model settings + */ public function __construct(array $config) { $this->config = $config; } + /** + * Analyze transaction data across all MOMO services + * + * @param array $data Transaction data including status, amounts, and patterns + * @return string Analysis results and insights + */ public function analyze($data) { - return $this->generateResponse("Analyze the following transaction data and provide insights:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO transaction data across collections, disbursements, and remittances. Consider transaction status, amounts, and patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Detect potential fraud in transaction data + * + * @param array $data Transaction data to evaluate for fraud indicators + * @return string Fraud analysis results and risk assessment + */ public function detectFraud($data) { - return $this->generateResponse("Evaluate the following transaction for potential fraud:\n\n" . json_encode($data)); + $prompt = "Evaluate this MTN MOMO transaction for potential fraud indicators. Consider transaction type (collection/disbursement/remittance), amount patterns, and account holder behavior:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest retry strategy for failed transactions + * + * @param array $data Failed transaction data including error codes and history + * @return string Recommended retry strategy + */ public function suggestRetryStrategy($data) { - return $this->generateResponse("Suggest a retry strategy for the following failed transaction:\n\n" . json_encode($data)); + $prompt = "Based on this failed MTN MOMO transaction data, suggest an optimal retry strategy considering the transaction type, error codes, and historical success patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Forecast cash flow based on historical data + * + * @param array $data Historical transaction data + * @return string Cash flow forecast and trends analysis + */ public function forecastCashFlow($data) { - return $this->generateResponse("Forecast cash flow based on the following historical data:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO historical transaction data across collections, disbursements, and remittances to forecast future cash flow patterns and trends:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Parse natural language commands into API requests + * + * @param string $command Natural language command to parse + * @return array|string Structured API request parameters + */ public function parseCommand($command) { - return $this->generateResponse("Parse the following natural language command into structured data:\n\n" . $command); + $prompt = "Parse this natural language command into a structured MTN MOMO API request format. Consider valid transaction types (collection/disbursement/remittance) and required parameters:\n\n" . $command; + return $this->generateResponse($prompt); } + /** + * Generate comprehensive transaction report + * + * @param array $data Transaction data to analyze + * @return string Detailed transaction report + */ public function generateReport($data) { - return $this->generateResponse("Generate a comprehensive report based on the following transaction data:\n\n" . json_encode($data)); + $prompt = "Generate a comprehensive MTN MOMO transaction report analyzing patterns across collections, disbursements, and remittances. Include transaction volumes, success rates, and notable trends:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest optimal disbursement timing + * + * @param float $amount Amount to disburse + * @param string $recipient Recipient identifier + * @return string Suggested optimal disbursement time + */ public function suggestDisbursementTime($amount, $recipient) { - return $this->generateResponse("Suggest an optimal disbursement time for the following transaction:\nAmount: $amount\nRecipient: $recipient"); + $prompt = "Suggest an optimal disbursement time for this MTN MOMO transfer considering amount: $amount, recipient: $recipient. Consider historical transaction patterns and success rates."; + return $this->generateResponse($prompt); } + /** + * Detect transaction anomalies + * + * @param array $data Transaction data to analyze for anomalies + * @return array|string Detected anomalies and their details + */ public function detectAnomalies($data) { - return $this->generateResponse("Detect any anomalies in the following transaction data:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO transaction data to detect anomalies across collections, disbursements, and remittances. Consider unusual patterns, amounts, frequencies, and account behaviors:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest optimal API call timing + * + * @param array $data API usage data and patterns + * @return string Suggested optimal call times + */ public function suggestOptimalCallTimes($data) { - return $this->generateResponse("Suggest optimal API call times based on the following usage data:\n\n" . json_encode($data)); + $prompt = "Based on this MTN MOMO API usage data, suggest optimal times for API calls considering success rates, response times, and error patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Explain API errors with context + * + * @param string $errorCode The error code to explain + * @param array $context Additional context about the error + * @return string Detailed error explanation and resolution steps + */ public function explainError($errorCode, $context) { - return $this->generateResponse("Explain the following error in the context of an MTN MOMO API transaction:\nError Code: $errorCode\nContext: " . json_encode($context)); + $prompt = "Explain this MTN MOMO API error in context of the transaction. Provide potential causes and resolution steps:\nError Code: $errorCode\nContext: " . json_encode($context); + return $this->generateResponse($prompt); } + /** + * Generate AI response using Anthropic's chat completion + * + * @param string $prompt The prompt to send to the AI model + * @return string Generated response from the AI model + */ protected function generateResponse($prompt) { $result = Anthropic::messages()->create([ 'model' => 'claude-3-opus-20240229', - 'max_tokens' => 1024, + 'max_tokens' => 500, 'messages' => [ ['role' => 'user', 'content' => $prompt], ], diff --git a/src/AI/Models/Gemini.php b/src/AI/Models/Gemini.php index cdd324f..33446f4 100644 --- a/src/AI/Models/Gemini.php +++ b/src/AI/Models/Gemini.php @@ -6,65 +6,158 @@ use Gemini\Laravel\Facades\Gemini as GeminiFacade; use Gemini\Resources\GenerativeModel; +/** + * Gemini AI Model Implementation for MTN MOMO API + * + * This class implements the LLMInterface to provide AI-powered analysis and insights + * for MTN Mobile Money transactions using Google's Gemini Pro model. + */ class Gemini implements LLMInterface { + /** @var GenerativeModel Gemini Pro model instance */ protected $model; + /** + * Initialize Gemini Pro model with configuration + * + * @param array $config Configuration array containing API keys and settings + */ public function __construct(array $config) { $this->model = GeminiFacade::geminiPro(); } + /** + * Analyze transaction data across all MOMO services + * + * @param array $data Transaction data including status, amounts, and patterns + * @return string Analysis results and insights + */ public function analyze($data) { - return $this->generateResponse("Analyze the following transaction data and provide insights:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO transaction data across collections, disbursements, and remittances. Consider transaction status, amounts, and patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Detect potential fraud in transaction data + * + * @param array $data Transaction data to evaluate for fraud indicators + * @return string Fraud analysis results and risk assessment + */ public function detectFraud($data) { - return $this->generateResponse("Evaluate the following transaction for potential fraud:\n\n" . json_encode($data)); + $prompt = "Evaluate this MTN MOMO transaction for potential fraud indicators. Consider transaction type (collection/disbursement/remittance), amount patterns, and account holder behavior:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest retry strategy for failed transactions + * + * @param array $data Failed transaction data including error codes and history + * @return string Recommended retry strategy + */ public function suggestRetryStrategy($data) { - return $this->generateResponse("Suggest a retry strategy for the following failed transaction:\n\n" . json_encode($data)); + $prompt = "Based on this failed MTN MOMO transaction data, suggest an optimal retry strategy considering the transaction type, error codes, and historical success patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Forecast cash flow based on historical data + * + * @param array $data Historical transaction data + * @return string Cash flow forecast and trends analysis + */ public function forecastCashFlow($data) { - return $this->generateResponse("Forecast cash flow based on the following historical data:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO historical transaction data across collections, disbursements, and remittances to forecast future cash flow patterns and trends:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Parse natural language commands into API requests + * + * @param string $command Natural language command to parse + * @return array Structured API request parameters + */ public function parseCommand($command) { - return $this->generateResponse("Parse the following natural language command into structured data:\n\n" . $command); + $prompt = "Parse this natural language command into a structured MTN MOMO API request format. Consider valid transaction types (collection/disbursement/remittance) and required parameters:\n\n" . $command; + return $this->generateResponse($prompt); } + /** + * Generate comprehensive transaction report + * + * @param array $data Transaction data to analyze + * @return string Detailed transaction report + */ public function generateReport($data) { - return $this->generateResponse("Generate a comprehensive report based on the following transaction data:\n\n" . json_encode($data)); + $prompt = "Generate a comprehensive MTN MOMO transaction report analyzing patterns across collections, disbursements, and remittances. Include transaction volumes, success rates, and notable trends:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest optimal disbursement timing + * + * @param float $amount Amount to disburse + * @param string $recipient Recipient identifier + * @return string Suggested optimal disbursement time + */ public function suggestDisbursementTime($amount, $recipient) { - return $this->generateResponse("Suggest an optimal disbursement time for the following transaction:\nAmount: $amount\nRecipient: $recipient"); + $prompt = "Suggest an optimal disbursement time for this MTN MOMO transfer considering amount: $amount, recipient: $recipient. Consider historical transaction patterns and success rates."; + return $this->generateResponse($prompt); } + /** + * Detect transaction anomalies + * + * @param array $data Transaction data to analyze for anomalies + * @return array Detected anomalies and their details + */ public function detectAnomalies($data) { - return $this->generateResponse("Detect any anomalies in the following transaction data:\n\n" . json_encode($data)); + $prompt = "Analyze this MTN MOMO transaction data to detect anomalies across collections, disbursements, and remittances. Consider unusual patterns, amounts, frequencies, and account behaviors:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Suggest optimal API call timing + * + * @param array $data API usage data and patterns + * @return string Suggested optimal call times + */ public function suggestOptimalCallTimes($data) { - return $this->generateResponse("Suggest optimal API call times based on the following usage data:\n\n" . json_encode($data)); + $prompt = "Based on this MTN MOMO API usage data, suggest optimal times for API calls considering success rates, response times, and error patterns:\n\n" . json_encode($data); + return $this->generateResponse($prompt); } + /** + * Explain API errors with context + * + * @param string $errorCode The error code to explain + * @param array $context Additional context about the error + * @return string Detailed error explanation and resolution steps + */ public function explainError($errorCode, $context) { - return $this->generateResponse("Explain the following error in the context of an MTN MOMO API transaction:\nError Code: $errorCode\nContext: " . json_encode($context)); + $prompt = "Explain this MTN MOMO API error in context of the transaction. Provide potential causes and resolution steps:\nError Code: $errorCode\nContext: " . json_encode($context); + return $this->generateResponse($prompt); } + /** + * Generate response using Gemini Pro model + * + * Internal method to handle communication with the Gemini API + * and process responses. + * + * @param string $prompt The formatted prompt to send to Gemini + * @return string|array Processed response from the model + */ protected function generateResponse($prompt) { $result = $this->model->generateContent($prompt); diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php index a0021f8..3e6409a 100644 --- a/src/Console/InstallCommand.php +++ b/src/Console/InstallCommand.php @@ -2,46 +2,71 @@ namespace AlvinCoded\MtnMomoAi\Console; +use AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException; +use GuzzleHttp\Client; use Illuminate\Console\Command; use Illuminate\Support\Facades\File; +use Illuminate\Support\Str; +/** + * MTN MOMO AI Package Installation Command + * + * This command handles the installation and configuration of the MTN MOMO AI package, + * including environment setup, API user creation, and configuration publishing. + * + * @package AlvinCoded\MtnMomoAi\Console + */ class InstallCommand extends Command { + /** + * The console command signature. + * + * @var string + */ protected $signature = 'mtn-momo-ai:install'; + + /** + * The console command description. + * + * @var string + */ protected $description = 'Install and configure the MTN MOMO AI package'; + /** + * Execute the console command. + * + * This method initiates the installation process, allowing users to set up + * their environment variables and publish the configuration file. + * + * @return void + */ public function handle() { $this->info('๐Ÿš€ Welcome to the MTN MOMO AI package installer!'); - $this->publishConfig(); - $this->setupEnvironment(); - - $this->info('โœ… Installation complete! Enjoy using MTN MOMO AI!'); - $this->info('๐Ÿ“˜ Remember to review and complete any missing configurations in your .env file.'); - } - - private function publishConfig() - { - if (File::exists(config_path('mtn-momo-ai.php'))) { - if ($this->confirm('๐Ÿ“ The config file already exists. Do you want to overwrite it?')) { - $this->publishConfiguration(); - $this->info('โœจ Configuration file published successfully!'); - } + if ($this->confirm('๐Ÿ”ง Would you like to set up your environment variables now?', true)) { + $this->setupEnvironment(); + $this->publishConfig(); + $this->info('โœ… Installation complete! Enjoy using MTN MOMO AI!'); } else { - $this->publishConfiguration(); - $this->info('โœจ Configuration file published successfully!'); + $this->info('โญ๏ธ Installation skipped. Run this command again when you\'re ready to configure the package.'); + return; } } - private function publishConfiguration() - { - $this->call('vendor:publish', [ - '--provider' => "AlvinCoded\\MtnMomoAi\\MtnMomoAiServiceProvider", - '--tag' => 'config' - ]); - } - + /** + * Set up the environment variables. + * + * Configures all necessary environment variables including: + * - MTN MOMO API credentials + * - Base URL and environment settings + * - Default currency + * - AI model configurations + * - Alert email settings + * + * @return void + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ private function setupEnvironment() { if (!File::exists(base_path('.env'))) { @@ -50,31 +75,29 @@ private function setupEnvironment() $this->info('โœ… .env file created successfully!'); } - if ($this->confirm('๐Ÿ”ง Would you like to set up your environment variables now?', true)) { - $this->updateEnvironmentFile(); - } else { - $this->info('โญ๏ธ You can set up your environment variables later in the .env file.'); - $this->displayRequiredEnvVariables(); - } - } - - private function updateEnvironmentFile() - { $envFile = base_path('.env'); $envContents = File::get($envFile); + // Generate API User UUID + $apiUserId = Str::uuid()->toString(); + $variables = [ - 'MTN_MOMO_API_USER' => $this->ask('๐Ÿ“ฑ What is your MTN MOMO API User?'), - 'MTN_MOMO_API_KEY' => $this->secret('๐Ÿ”‘ What is your MTN MOMO API Key?'), 'MTN_MOMO_SUBSCRIPTION_KEY' => $this->secret('๐Ÿ” What is your MTN MOMO Subscription Key?'), + 'MTN_MOMO_BASE_URL' => $this->choice('๐ŸŒ Which base URL would you like to use?', ['https://sandbox.momodeveloper.mtn.com', 'https://momodeveloper.mtn.com'], 'https://sandbox.momodeveloper.mtn.com'), 'MTN_MOMO_ENVIRONMENT' => $this->choice('๐ŸŒ Which environment are you using?', ['sandbox', 'production'], 'sandbox'), - 'MTN_MOMO_DEFAULT_CURRENCY' => $this->choice('๐Ÿ’ฐ Which currency would you like to use by default?', ['EUR' => 'Euro', 'USD' => 'US Dollar', 'GHS' => 'Ghana Cedi', 'UGX' => 'Ugandan Shilling', 'XAF' => 'Central African CFA Franc', 'XOF' => 'West African CFA Franc'], 'USD'), + 'MTN_MOMO_PROVIDER_CALLBACK_HOST' => $this->ask('๐Ÿ”„ What is your callback host? (e.g., https://your-domain.com)', 'http://localhost'), + 'MTN_MOMO_DEFAULT_CURRENCY' => $this->choice('๐Ÿ’ฐ Which currency would you like to use by default?', ['EUR' => 'Euro', 'USD' => 'US Dollar', 'GHS' => 'Ghana Cedi', 'UGX' => 'Ugandan Shilling', 'XAF' => 'Central African CFA Franc', 'XOF' => 'West African CFA Franc'], 'EUR'), 'DEFAULT_LLM' => $this->choice('๐Ÿค– Which AI model would you like to use by default?', ['ChatGPT', 'Claude', 'Gemini'], 'ChatGPT'), 'OPENAI_API_KEY' => $this->secret('๐Ÿ”‘ What is your OpenAI API Key? (Leave blank if not using)'), 'ANTHROPIC_API_KEY' => $this->secret('๐Ÿ”‘ What is your Anthropic API Key? (Leave blank if not using)'), - 'GEMINI_API_KEY' => $this->secret('๐Ÿ”‘ What is your Gemini API Key? (Leave blank if not using)') + 'GEMINI_API_KEY' => $this->secret('๐Ÿ”‘ What is your Gemini API Key? (Leave blank if not using)'), + 'MTN_MOMO_ALERT_EMAIL' => $this->ask('๐Ÿ“ง What email should receive alerts?'), + 'MTN_MOMO_API_USER' => $apiUserId, ]; + $apiKey = $this->createApiUser($apiUserId, $variables['MTN_MOMO_SUBSCRIPTION_KEY']); + $variables['MTN_MOMO_API_KEY'] = $apiKey; + foreach ($variables as $key => $value) { if (!empty($value)) { if (preg_match("/^$key=.*/m", $envContents)) { @@ -89,17 +112,98 @@ private function updateEnvironmentFile() $this->info('โœ… Environment variables have been set successfully!'); } - private function displayRequiredEnvVariables() + /** + * Create an API user in the MTN MOMO sandbox. + * + * This method performs a three-step process: + * 1. Creates an API user with the provided UUID + * 2. Generates an API key for the created user + * 3. Verifies the user creation by fetching user details + * + * @param string $apiUserId The UUID to be used as the API user identifier + * @param string $subscriptionKey The MTN MOMO subscription key + * @return string The generated API key + * @throws MtnMomoApiException If any step in the API user creation process fails + * @throws \GuzzleHttp\Exception\GuzzleException + */ + private function createApiUser($apiUserId, $subscriptionKey) { - $this->info('๐Ÿ”” Please make sure to set the following environment variables in your .env file:'); - $this->line('MTN_MOMO_API_USER'); - $this->line('MTN_MOMO_API_KEY'); - $this->line('MTN_MOMO_SUBSCRIPTION_KEY'); - $this->line('MTN_MOMO_ENVIRONMENT'); - $this->line('MTN_MOMO_DEFAULT_CURRENCY'); - $this->line('DEFAULT_LLM'); - $this->line('OPENAI_API_KEY (if using ChatGPT)'); - $this->line('ANTHROPIC_API_KEY (if using Claude)'); - $this->line('GEMINI_API_KEY (if using Gemini)'); + $client = new Client(); + + try { + // Step 1 + $createUserResponse = $client->post(config('mtn-momo-ai.base_url') . '/v1_0/apiuser', [ + 'headers' => [ + 'X-Reference-Id' => $apiUserId, + 'Ocp-Apim-Subscription-Key' => $subscriptionKey, + 'Content-Type' => 'application/json' + ], + 'json' => [ + 'providerCallbackHost' => config('mtn-momo-ai.callback_host', 'http://localhost') + ] + ]); + + if ($createUserResponse->getStatusCode() !== 201) { + throw new MtnMomoApiException('Failed to create API user'); + } + + // Step 2 + $createKeyResponse = $client->post( + config('mtn-momo-ai.base_url') . '/v1_0/apiuser/' . $apiUserId . '/apikey', + [ + 'headers' => [ + 'Ocp-Apim-Subscription-Key' => $subscriptionKey, + 'Content-Type' => 'application/json' + ] + ] + ); + + if ($createKeyResponse->getStatusCode() !== 201) { + throw new MtnMomoApiException('Failed to create API key'); + } + + $apiKey = json_decode($createKeyResponse->getBody()->getContents(), true)['apiKey']; + + // Step 3 + $getUserResponse = $client->get( + config('mtn-momo-ai.base_url') . '/v1_0/apiuser/' . $apiUserId, + [ + 'headers' => [ + 'Ocp-Apim-Subscription-Key' => $subscriptionKey, + 'Content-Type' => 'application/json' + ] + ] + ); + + if ($getUserResponse->getStatusCode() !== 200) { + throw new MtnMomoApiException('Failed to verify API user'); + } + + return $apiKey; + + } catch (\GuzzleHttp\Exception\RequestException $e) { + throw new MtnMomoApiException( + 'API User creation failed: ' . $e->getMessage(), + $e->getCode(), + $e->getResponse() ? json_decode($e->getResponse()->getBody()->getContents(), true) : null + ); + } + } + + /** + * Publish the package configuration file. + * + * Publishes the mtn-momo-ai.php configuration file to the application's + * config directory using Laravel's vendor publishing feature. + * + * @return void + */ + private function publishConfig() + { + $this->call('vendor:publish', [ + '--provider' => "AlvinCoded\\MtnMomoAi\\MtnMomoAiServiceProvider", + '--tag' => 'config' + ]); + $this->info('โœจ Configuration file published successfully!'); } -} +} \ No newline at end of file diff --git a/src/Endpoints/Collections.php b/src/Endpoints/Collections.php index 7f67e23..21f478b 100644 --- a/src/Endpoints/Collections.php +++ b/src/Endpoints/Collections.php @@ -4,19 +4,48 @@ use AlvinCoded\MtnMomoAi\Traits\MakesHttpRequests; +/** + * Class Collections + * + * Handles all Collection-related operations for the MTN MOMO API. + * This class provides methods to initiate payments, check transaction status, + * and manage account information. + * + * @package AlvinCoded\MtnMomoAi\Endpoints + */ class Collections { use MakesHttpRequests; + /** @var array Configuration settings for the Collections API */ protected $config; + + /** @var string Base URL for all Collection API endpoints */ protected $baseUrl; + /** + * Initialize a new Collections instance. + * + * @param array $config Configuration array containing base_url and version + */ public function __construct(array $config) { $this->config = $config; $this->baseUrl = $config['base_url'] . '/collection/' . $config['version']; } + /** + * Request a payment from a customer. + * + * @param string $externalId Unique identifier for the transaction + * @param string $partyId The phone number of the customer (MSISDN) + * @param float $amount Amount to be paid + * @param string $currency Currency of the amount (e.g., EUR, USD) + * @param string $payerMessage Message to be displayed to the payer + * @param string $payeeNote Note for the payee's records + * + * @return array Response from the API containing transaction details + */ public function requestToPay($externalId, $partyId, $amount, $currency, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/requesttopay'; @@ -35,30 +64,66 @@ public function requestToPay($externalId, $partyId, $amount, $currency, $payerMe return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a specific transaction. + * + * @param string $referenceId The reference ID of the transaction + * + * @return array Transaction status details + */ public function getTransactionStatus($referenceId) { $endpoint = $this->baseUrl . '/requesttopay/' . $referenceId; return $this->makeRequest('GET', $endpoint); } + /** + * Get the balance of the account. + * + * @return array Account balance information + */ public function getAccountBalance() { $endpoint = $this->baseUrl . '/account/balance'; return $this->makeRequest('GET', $endpoint); } + /** + * Get information about a specific account holder. + * + * @param string $accountHolderId The ID of the account holder + * @param string $accountHolderIdType The type of the ID (e.g., MSISDN) + * + * @return array Account holder information + */ public function getAccountHolder($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Validate the status of an account holder. + * + * @param string $accountHolderId The ID of the account holder + * @param string $accountHolderIdType The type of the ID (e.g., MSISDN) + * + * @return array Account holder status information + */ public function validateAccountHolderStatus($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Send a delivery notification for a request to pay transaction. + * + * @param string $referenceId The reference ID of the transaction + * @param string $notificationMessage The message to be sent in the notification + * + * @return array Notification delivery status + */ public function requestToPayDeliveryNotification($referenceId, $notificationMessage) { $endpoint = $this->baseUrl . '/requesttopay/' . $referenceId . '/deliverynotification'; @@ -68,23 +133,18 @@ public function requestToPayDeliveryNotification($referenceId, $notificationMess return $this->makeRequest('POST', $endpoint, $body); } - public function requestToPayTransaction($amount, $currency, $externalId, $partyId, $payerMessage, $payeeNote) - { - $endpoint = $this->baseUrl . '/requesttopay'; - $body = [ - 'amount' => $amount, - 'currency' => $currency, - 'externalId' => $externalId, - 'payer' => [ - 'partyIdType' => 'MSISDN', - 'partyId' => $partyId - ], - 'payerMessage' => $payerMessage, - 'payeeNote' => $payeeNote - ]; - return $this->makeRequest('POST', $endpoint, $body); - } - + /** + * Initiate a withdrawal request. + * + * @param float $amount Amount to withdraw + * @param string $currency Currency of the amount + * @param string $externalId External transaction ID + * @param array $payee Payee information + * @param string $payerMessage Message for the payer + * @param string $payeeNote Note for the payee + * + * @return array Withdrawal request response + */ public function requestToWithdraw($amount, $currency, $externalId, $payee, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/requesttowithdraw'; @@ -99,12 +159,27 @@ public function requestToWithdraw($amount, $currency, $externalId, $payee, $paye return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a withdrawal transaction. + * + * @param string $referenceId The reference ID of the withdrawal + * + * @return array Withdrawal transaction status + */ public function getWithdrawalTransactionStatus($referenceId) { $endpoint = $this->baseUrl . '/requesttowithdraw/' . $referenceId; return $this->makeRequest('GET', $endpoint); } + /** + * Get BC authorization for an account holder. + * + * @param string $accountHolderMSISDN The MSISDN of the account holder + * @param string $accountHolderUUID The UUID of the account holder + * + * @return array BC authorization response + */ public function getBCAuthorization($accountHolderMSISDN, $accountHolderUUID) { $endpoint = $this->baseUrl . '/bc-authorize'; diff --git a/src/Endpoints/Disbursements.php b/src/Endpoints/Disbursements.php index 582ce9f..f29e757 100644 --- a/src/Endpoints/Disbursements.php +++ b/src/Endpoints/Disbursements.php @@ -4,19 +4,49 @@ use AlvinCoded\MtnMomoAi\Traits\MakesHttpRequests; +/** + * Class Disbursements + * + * Handles all disbursement-related operations for the MTN MOMO API. + * This class provides methods for transferring money, checking transaction status, + * and managing account information. + * + * @package AlvinCoded\MtnMomoAi\Endpoints + */ class Disbursements { use MakesHttpRequests; + /** @var array Configuration settings for the disbursement endpoint */ protected $config; + + /** @var string Base URL for all disbursement API requests */ protected $baseUrl; + /** + * Initialize a new Disbursements instance. + * + * @param array $config Configuration array containing base_url and version + */ public function __construct(array $config) { $this->config = $config; $this->baseUrl = $config['base_url'] . '/disbursement/' . $config['version']; } + /** + * Transfer money to a payee. + * + * @param string $externalId Unique identifier for the transaction + * @param string $partyId The phone number of the payee + * @param float $amount Amount to transfer + * @param string $currency Currency of transfer (e.g., EUR, USD) + * @param string $payerMessage Message for the payer's statement + * @param string $payeeNote Note for the payee + * + * @return array Response from the API + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function transfer($externalId, $partyId, $amount, $currency, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/transfer'; @@ -34,36 +64,89 @@ public function transfer($externalId, $partyId, $amount, $currency, $payerMessag return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a specific transfer transaction. + * + * @param string $referenceId The reference ID of the transfer + * + * @return array Transaction status details + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getTransactionStatus($referenceId) { $endpoint = $this->baseUrl . '/transfer/' . $referenceId; return $this->makeRequest('GET', $endpoint); } + /** + * Get the account balance for the disbursement account. + * + * @return array Account balance information + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getAccountBalance() { $endpoint = $this->baseUrl . '/account/balance'; return $this->makeRequest('GET', $endpoint); } + /** + * Get information about an account holder. + * + * @param string $accountHolderId The ID of the account holder + * @param string $accountHolderIdType The type of the account holder ID (e.g., MSISDN) + * + * @return array Account holder information + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getAccountHolder($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Validate the status of an account holder. + * + * @param string $accountHolderId The ID of the account holder + * @param string $accountHolderIdType The type of the account holder ID + * + * @return array Account holder status + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function validateAccountHolderStatus($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Get basic information about a user by their MSISDN. + * + * @param string $msisdn The phone number of the user + * + * @return array User information + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getBasicUserinfo($msisdn) { $endpoint = $this->baseUrl . '/accountholder/msisdn/' . $msisdn . '/basicuserinfo'; return $this->makeRequest('GET', $endpoint); } + /** + * Initiate a refund for a previous transfer. + * + * @param string $externalId Unique identifier for the refund + * @param float $amount Amount to refund + * @param string $currency Currency of the refund + * @param string $referenceId Reference ID of the original transfer + * @param string $payerMessage Message for the payer's statement + * @param string $payeeNote Note for the payee + * + * @return array Refund response + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function refund($externalId, $amount, $currency, $referenceId, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/refund'; @@ -78,15 +161,31 @@ public function refund($externalId, $amount, $currency, $referenceId, $payerMess return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a refund transaction. + * + * @param string $referenceId The reference ID of the refund + * + * @return array Refund status details + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getRefundStatus($referenceId) { $endpoint = $this->baseUrl . '/refund/' . $referenceId; return $this->makeRequest('GET', $endpoint); } + /** + * Get the status of a deposit transaction. + * + * @param string $referenceId The reference ID of the deposit + * + * @return array Deposit status details + * @throws \AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException + */ public function getDepositStatus($referenceId) { $endpoint = $this->baseUrl . '/deposit/' . $referenceId; return $this->makeRequest('GET', $endpoint); } -} +} \ No newline at end of file diff --git a/src/Endpoints/Remittances.php b/src/Endpoints/Remittances.php index 8161cda..68c94ca 100644 --- a/src/Endpoints/Remittances.php +++ b/src/Endpoints/Remittances.php @@ -4,19 +4,48 @@ use AlvinCoded\MtnMomoAi\Traits\MakesHttpRequests; +/** + * Class Remittances + * + * Handles all remittance-related operations for the MTN MOMO API. + * This class provides methods for transferring money, checking balances, + * and managing remittance transactions. + * + * @package AlvinCoded\MtnMomoAi\Endpoints + */ class Remittances { use MakesHttpRequests; + /** @var array Configuration settings for the remittance endpoint */ protected $config; + + /** @var string Base URL for all remittance API endpoints */ protected $baseUrl; + /** + * Initialize a new Remittances instance. + * + * @param array $config Configuration array containing base_url and version + */ public function __construct(array $config) { $this->config = $config; $this->baseUrl = $config['base_url'] . '/remittance/' . $config['version']; } + /** + * Transfer money to a payee using remittance. + * + * @param string $externalId Unique identifier for the transaction + * @param string $partyId The phone number of the payee + * @param float $amount Amount to transfer + * @param string $currency Currency of the transfer (e.g., EUR, USD) + * @param string $payerMessage Message from the payer + * @param string $payeeNote Note to the payee + * + * @return array Response from the API + */ public function transfer($externalId, $partyId, $amount, $currency, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/transfer'; @@ -34,36 +63,82 @@ public function transfer($externalId, $partyId, $amount, $currency, $payerMessag return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a specific remittance transaction. + * + * @param string $referenceId The reference ID of the transaction + * + * @return array Transaction status details + */ public function getTransactionStatus($referenceId) { $endpoint = $this->baseUrl . '/transfer/' . $referenceId; return $this->makeRequest('GET', $endpoint); } + /** + * Get the current balance of the remittance account. + * + * @return array Account balance information + */ public function getAccountBalance() { $endpoint = $this->baseUrl . '/account/balance'; return $this->makeRequest('GET', $endpoint); } + /** + * Get information about a specific account holder. + * + * @param string $accountHolderId ID of the account holder + * @param string $accountHolderIdType Type of the ID (e.g., MSISDN) + * + * @return array Account holder information + */ public function getAccountHolder($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Validate the status of an account holder. + * + * @param string $accountHolderId ID of the account holder + * @param string $accountHolderIdType Type of the ID (e.g., MSISDN) + * + * @return array Account holder status information + */ public function validateAccountHolderStatus($accountHolderId, $accountHolderIdType) { $endpoint = $this->baseUrl . '/accountholder/' . $accountHolderIdType . '/' . $accountHolderId . '/active'; return $this->makeRequest('GET', $endpoint); } + /** + * Get basic information about a user using their MSISDN. + * + * @param string $msisdn Mobile number of the user + * + * @return array Basic user information + */ public function getBasicUserinfo($msisdn) { $endpoint = $this->baseUrl . '/accountholder/msisdn/' . $msisdn . '/basicuserinfo'; return $this->makeRequest('GET', $endpoint); } + /** + * Initiate a cash transfer transaction. + * + * @param string $externalId Unique identifier for the transaction + * @param float $amount Amount to transfer + * @param string $currency Currency of the transfer + * @param string $payerMessage Message from the payer + * @param string $payeeNote Note to the payee + * + * @return array Response from the API + */ public function cashTransfer($externalId, $amount, $currency, $payerMessage, $payeeNote) { $endpoint = $this->baseUrl . '/cashtransfer'; @@ -77,9 +152,16 @@ public function cashTransfer($externalId, $amount, $currency, $payerMessage, $pa return $this->makeRequest('POST', $endpoint, $body); } + /** + * Get the status of a specific cash transfer transaction. + * + * @param string $referenceId The reference ID of the cash transfer + * + * @return array Cash transfer status details + */ public function getCashTransferStatus($referenceId) { $endpoint = $this->baseUrl . '/cashtransfer/' . $referenceId; return $this->makeRequest('GET', $endpoint); } -} +} \ No newline at end of file diff --git a/src/Exceptions/MtnMomoApiException.php b/src/Exceptions/MtnMomoApiException.php index b1a5be8..77f08e0 100644 --- a/src/Exceptions/MtnMomoApiException.php +++ b/src/Exceptions/MtnMomoApiException.php @@ -4,16 +4,51 @@ use Exception; +/** + * MTN MOMO API Exception Handler + * + * This exception class handles specific errors that occur during + * interactions with the MTN Mobile Money API. It extends the base + * PHP Exception class and adds functionality to store and retrieve + * the API response body. + * + * @package AlvinCoded\MtnMomoAi\Exceptions + * @author Alvin Panford + * @since 1.0.0 + */ class MtnMomoApiException extends Exception { + /** + * The raw response body from the API request + * + * @var mixed|null + */ protected $responseBody; + /** + * Create a new MTN MOMO API Exception instance + * + * @param string $message The exception message + * @param int $code The exception code (defaults to 0) + * @param mixed|null $responseBody The raw API response body + * + * @return void + */ public function __construct($message, $code = 0, $responseBody = null) { parent::__construct($message, $code); $this->responseBody = $responseBody; } + /** + * Get the raw response body from the API request + * + * This method returns the complete response body received from + * the MTN MOMO API during the failed request. This can be useful + * for debugging purposes or for logging detailed error information. + * + * @return mixed|null The response body or null if not available + */ public function getResponseBody() { return $this->responseBody; diff --git a/src/Facades/MtnMomoAi.php b/src/Facades/MtnMomoAi.php index b105e97..b31ea54 100644 --- a/src/Facades/MtnMomoAi.php +++ b/src/Facades/MtnMomoAi.php @@ -4,8 +4,46 @@ use Illuminate\Support\Facades\Facade; +/** + * MTN MOMO AI Facade + * + * @method static array analyzeTransaction(string $transactionId, string|null $model = null) Analyze a transaction using AI + * @method static array detectFraud(array $transactionData, string|null $model = null) Detect potential fraud in a transaction + * @method static array smartRetry(array $failedTransaction, string|null $model = null) Retry a failed transaction with AI-optimized strategy + * @method static array forecastCashFlow(string $timeframe, string|null $model = null) Forecast cash flow based on historical data + * @method static array parseNaturalLanguageCommand(string $command, string|null $model = null) Parse natural language commands into API calls + * @method static array generateReport(string $startDate, string $endDate) Generate AI-enhanced transaction reports + * @method static array scheduleDisbursement(float $amount, string $recipient, string|null $currency = null) Schedule an AI-optimized disbursement + * @method static array monitorTransactions() Monitor transactions for anomalies + * @method static array optimizeApiCalls(string $endpoint) Optimize API call patterns + * @method static array handleError(string $errorCode, array $context) Handle and explain API errors + * + * @method static array requestToPay(float $amount, string $currency, string $externalId, string $partyId, string $payerMessage, string $payeeNote) Request a payment + * @method static array getCollectionTransactionStatus(string $referenceId) Get collection transaction status + * @method static array getAccountBalance() Get account balance + * @method static array getAccountHolder(string $accountHolderId, string $accountHolderIdType) Get account holder information + * + * @method static array transfer(float $amount, string $currency, string $externalId, string $payee, string $payerMessage, string $payeeNote) Transfer funds + * @method static array getDisbursementTransactionStatus(string $referenceId) Get disbursement transaction status + * @method static array getDisbursementAccountBalance() Get disbursement account balance + * + * @method static array remit(float $amount, string $currency, string $externalId, string $payee, string $payerMessage, string $payeeNote) Perform remittance + * @method static array getRemittanceTransactionStatus(string $referenceId) Get remittance transaction status + * @method static array getRemittanceAccountBalance() Get remittance account balance + * + * @see \AlvinCoded\MtnMomoAi\MtnMomoAi + * @package AlvinCoded\MtnMomoAi\Facades + */ class MtnMomoAi extends Facade { + /** + * Get the registered name of the component. + * + * This function registers the facade accessor for the MTN MOMO AI package. + * The accessor is used to resolve the underlying instance behind the facade. + * + * @return string + */ protected static function getFacadeAccessor() { return 'mtn-momo-ai'; diff --git a/src/MtnMomoAi.php b/src/MtnMomoAi.php index fbd5b3d..65ff5e4 100644 --- a/src/MtnMomoAi.php +++ b/src/MtnMomoAi.php @@ -10,27 +10,65 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; +/** + * MTN MOMO AI Integration Package + * + * This class provides a comprehensive integration between MTN Mobile Money API + * and various AI models for enhanced transaction processing and analysis. + * + * @package AlvinCoded\MtnMomoAi + * @author Alvin Panford + */ class MtnMomoAi { + /** + * Trait for making HTTP requests to MTN MOMO API + */ use MakesHttpRequests; + /** + * @var Collections + */ protected $collections; + + /** + * @var Disbursements + */ protected $disbursements; + + /** + * @var Remittances + */ protected $remittances; + + /** + * @var LLMFactory + */ protected $llmFactory; - public function __construct( - Collections $collections, - Disbursements $disbursements, - Remittances $remittances, - LLMFactory $llmFactory - ) { + /** + * Constructor for MtnMomoAi + * + * @param Collections $collections The Collections API endpoint handler + * @param Disbursements $disbursements The Disbursements API endpoint handler + * @param Remittances $remittances The Remittances API endpoint handler + * @param LLMFactory $llmFactory Factory for creating AI model instances + */ + public function __construct(Collections $collections, Disbursements $disbursements, Remittances $remittances, LLMFactory $llmFactory) + { $this->collections = $collections; $this->disbursements = $disbursements; $this->remittances = $remittances; $this->llmFactory = $llmFactory; } + /** + * Analyze a transaction using AI + * + * @param string $transactionId The transaction ID to analyze + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return string Analysis results from the AI model + */ public function analyzeTransaction($transactionId, $model = null) { $transaction = $this->getTransactionDetails($transactionId); @@ -38,12 +76,26 @@ public function analyzeTransaction($transactionId, $model = null) return $llm->analyze($transaction); } + /** + * Detect potential fraud in a transaction + * + * @param array $transactionData Transaction data to analyze + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Fraud detection results + */ public function detectFraud($transactionData, $model = null) { $llm = $this->llmFactory->create($model ?? config('mtn-momo-ai.default_llm')); return $llm->detectFraud($transactionData); } + /** + * Implement smart retry strategy for failed transactions + * + * @param array $failedTransaction Failed transaction data + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Retry attempt results + */ public function smartRetry($failedTransaction, $model = null) { $llm = $this->llmFactory->create($model ?? config('mtn-momo-ai.default_llm')); @@ -51,6 +103,13 @@ public function smartRetry($failedTransaction, $model = null) return $this->retryTransaction($failedTransaction, $retryStrategy); } + /** + * Generate cash flow forecast + * + * @param string $timeframe Time period to forecast (e.g., '1month', '1year') + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Forecast data + */ public function forecastCashFlow($timeframe, $model = null) { $historicalData = $this->getHistoricalTransactions($timeframe); @@ -58,6 +117,13 @@ public function forecastCashFlow($timeframe, $model = null) return $llm->forecastCashFlow($historicalData); } + /** + * Parse natural language commands into API calls + * + * @param string $command Natural language command + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Command execution results + */ public function parseNaturalLanguageCommand($command, $model = null) { $llm = $this->llmFactory->create($model ?? config('mtn-momo-ai.default_llm')); @@ -65,7 +131,13 @@ public function parseNaturalLanguageCommand($command, $model = null) return $this->executeCommand($parsedCommand); } - + /** + * Generate transaction report + * + * @param string|\DateTime $startDate Start date for report + * @param string|\DateTime $endDate End date for report + * @return array Generated report data + */ public function generateReport($startDate, $endDate) { $transactionData = $this->getTransactions($startDate, $endDate); @@ -73,26 +145,38 @@ public function generateReport($startDate, $endDate) return $llm->generateReport($transactionData); } + /** + * Schedule a disbursement with AI-optimized timing + * + * @param float $amount Amount to disburse + * @param string $recipient Recipient identifier + * @param string|null $currency Optional currency code + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Disbursement results + */ public function scheduleDisbursement($amount, $recipient, $currency = null, $model = null) { $llm = $this->llmFactory->create($model ?? config('mtn-momo-ai.default_llm')); $optimalTime = $llm->suggestDisbursementTime($amount, $recipient); - // Use provided currency or fall back to default $currency = $currency ?? config('mtn-momo-ai.default_currency'); return $this->disbursements->transfer( - 'ext_'.uniqid(), // externalId - $recipient, // partyId - $amount, // amount - $currency, // currency from config or parameter - 'Scheduled Transfer', // payerMessage - 'Scheduled at '.$optimalTime // payeeNote + 'ext_'.uniqid(), + $recipient, + $amount, + $currency, + 'Scheduled Transfer', + 'Scheduled at '.$optimalTime ); } - - + /** + * Monitor transactions for anomalies + * + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array|void Detected anomalies and monitoring results + */ public function monitorTransactions($model = null) { $recentTransactions = $this->getRecentTransactions(); @@ -101,6 +185,13 @@ public function monitorTransactions($model = null) return $this->alertAnomalies($anomalies); } + /** + * Optimize API call patterns + * + * @param string $endpoint The endpoint to optimize + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Optimization suggestions and timing recommendations + */ public function optimizeApiCalls($endpoint, $model = null) { $usageData = $this->getApiUsageData($endpoint); @@ -108,6 +199,14 @@ public function optimizeApiCalls($endpoint, $model = null) return $llm->suggestOptimalCallTimes($usageData); } + /** + * Handle and explain API errors + * + * @param string $errorCode The error code received + * @param array $context Additional context about the error + * @param string|null $model Optional AI model to use (ChatGPT, Claude, or Gemini) + * @return array Formatted error response with AI-generated explanation + */ public function handleError($errorCode, $context, $model = null) { $llm = $this->llmFactory->create($model ?? config('mtn-momo-ai.default_llm')); @@ -116,54 +215,140 @@ public function handleError($errorCode, $context, $model = null) } // Collection API methods + + /** + * Request to pay via Collections API + * + * @param float $amount Amount to request + * @param string $currency Currency code + * @param string $externalId Your transaction reference + * @param string $partyId Payer's account number + * @param string $payerMessage Message to payer + * @param string $payeeNote Note about payment + * @return array Payment request result + */ public function requestToPay($amount, $currency, $externalId, $partyId, $payerMessage, $payeeNote) { return $this->collections->requestToPay($amount, $currency, $externalId, $partyId, $payerMessage, $payeeNote); } + + /** + * Get Collection transaction status + * + * @param string $referenceId Transaction reference ID + * @return array Transaction status details + */ public function getCollectionTransactionStatus($referenceId) { return $this->collections->getTransactionStatus($referenceId); } + + /** + * Get account balance + * + * @return array Account balance information + */ public function getAccountBalance() { return $this->collections->getAccountBalance(); } + + /** + * Get account holder information + * + * @param string $accountHolderId Account holder's identifier + * @param string $accountHolderIdType Type of identifier (e.g., 'MSISDN') + * @return array Account holder details + */ public function getAccountHolder($accountHolderId, $accountHolderIdType) { return $this->collections->getAccountHolder($accountHolderId, $accountHolderIdType); } // Disbursement API methods + + /** + * Transfer funds via Disbursements API + * + * @param float $amount Amount to transfer + * @param string $currency Currency code + * @param string $externalId Your transaction reference + * @param string $payee Recipient's account number + * @param string $payerMessage Message to payer + * @param string $payeeNote Note about transfer + * @return array Transfer result + */ public function transfer($amount, $currency, $externalId, $payee, $payerMessage, $payeeNote) { return $this->disbursements->transfer($amount, $currency, $externalId, $payee, $payerMessage, $payeeNote); } + + /** + * Get Disbursement transaction status + * + * @param string $referenceId Transaction reference ID + * @return array Transaction status details + */ public function getDisbursementTransactionStatus($referenceId) { return $this->disbursements->getTransactionStatus($referenceId); } + + /** + * Get Disbursement account balance + * + * @return array Disbursement account balance information + */ public function getDisbursementAccountBalance() { return $this->disbursements->getAccountBalance(); } // Remittance API methods + + /** + * Send remittance via Remittance API + * + * @param float $amount Amount to remit + * @param string $currency Currency code + * @param string $externalId Your transaction reference + * @param string $payee Recipient's account number + * @param string $payerMessage Message to payer + * @param string $payeeNote Note about remittance + * @return array Remittance result + */ public function remit($amount, $currency, $externalId, $payee, $payerMessage, $payeeNote) { return $this->remittances->transfer($amount, $currency, $externalId, $payee, $payerMessage, $payeeNote); } + + /** + * Get Remittance transaction status + * + * @param string $referenceId Transaction reference ID + * @return array Transaction status details + */ public function getRemittanceTransactionStatus($referenceId) { return $this->remittances->getTransactionStatus($referenceId); } + + /** + * Get Remittance account balance + * + * @return array Remittance account balance information + */ public function getRemittanceAccountBalance() { return $this->remittances->getAccountBalance(); } - // Helper methods - - // Fetch transaction details + /** + * Get transaction details across all products + * + * @param string $transactionId Transaction ID to look up + * @return array Combined transaction details + */ protected function getTransactionDetails($transactionId) { $collectionStatus = $this->collections->getTransactionStatus($transactionId); @@ -177,7 +362,13 @@ protected function getTransactionDetails($transactionId) ]); } - // Retry a failed transaction + /** + * Retry a failed transaction with specified strategy + * + * @param array $failedTransaction Original failed transaction data + * @param array $retryStrategy AI-generated retry strategy + * @return array|null Retry attempt results + */ protected function retryTransaction($failedTransaction, $retryStrategy) { $product = $failedTransaction['product']; @@ -198,7 +389,12 @@ protected function retryTransaction($failedTransaction, $retryStrategy) } } - // Fetch historical transactions + /** + * Get historical transaction data + * + * @param string $timeframe Time period to fetch (e.g., '1month', '1year') + * @return array Historical transaction data + */ protected function getHistoricalTransactions($timeframe) { $endDate = now(); @@ -211,6 +407,12 @@ protected function getHistoricalTransactions($timeframe) return array_merge($collections, $disbursements, $remittances); } + /** + * Execute parsed natural language command + * + * @param array $parsedCommand Structured command data from AI parsing + * @return array|null Command execution results + */ protected function executeCommand($parsedCommand) { switch ($parsedCommand['action']) { @@ -244,7 +446,13 @@ protected function executeCommand($parsedCommand) } } - // Fetch transactions within a date range + /** + * Get transactions within a date range + * + * @param \DateTime|string $startDate Start date for transaction fetch + * @param \DateTime|string $endDate End date for transaction fetch + * @return array Filtered transactions across all products + */ protected function getTransactions($startDate, $endDate) { $collections = $this->collections->getTransactionStatus($startDate); @@ -258,8 +466,11 @@ protected function getTransactions($startDate, $endDate) ]); } - - // Fetch recent transactions + /** + * Get recent transactions from the last 7 days + * + * @return array Recent transactions across all products + */ protected function getRecentTransactions() { $endDate = now(); @@ -268,18 +479,27 @@ protected function getRecentTransactions() return $this->getTransactions($startDate, $endDate); } - // Alert about detected anomalies + /** + * Process and alert about detected anomalies + * + * @param array $anomalies List of detected anomalies + * @return void + * @throws \Exception When notification fails + */ protected function alertAnomalies($anomalies) { foreach ($anomalies as $anomaly) { - // Log anomaly Log::warning('Transaction anomaly detected', $anomaly); - - // Send notification using Laravel's notification system Notification::route('mail', config('mtn-momo-ai.alert_email'))->notify(new \AlvinCoded\MtnMomoAi\Notifications\AnomalyDetectedNotification($anomaly)); } } + /** + * Format error response with consistent structure + * + * @param string $explanation AI-generated error explanation + * @return array Structured error response + */ protected function formatErrorResponse($explanation) { return [ @@ -289,7 +509,12 @@ protected function formatErrorResponse($explanation) ]; } - // Fetch API usage data + /** + * Get API usage statistics for an endpoint + * + * @param string $endpoint API endpoint to analyze + * @return array Usage statistics including calls, response times, and error rates + */ protected function getApiUsageData($endpoint) { $baseUrl = config('mtn-momo-ai.base_url'); @@ -313,6 +538,12 @@ protected function getApiUsageData($endpoint) ]; } + /** + * Calculate average response time for a set of transactions + * + * @param array $transactions Array of transactions to analyze + * @return float|int Average response time in milliseconds + */ private function calculateAverageResponseTime($transactions) { if (empty($transactions)) { diff --git a/src/MtnMomoAiServiceProvider.php b/src/MtnMomoAiServiceProvider.php index 262da75..fa118e8 100644 --- a/src/MtnMomoAiServiceProvider.php +++ b/src/MtnMomoAiServiceProvider.php @@ -10,17 +10,31 @@ use AlvinCoded\MtnMomoAi\AI\LLMFactory; use AlvinCoded\MtnMomoAi\Console\InstallCommand; +/** + * MTN MOMO AI Service Provider + * + * This service provider is responsible for registering and bootstrapping the + * MTN MOMO AI package within a Laravel application. It handles configuration + * merging, service registration, and publishes package assets. + * + * @package AlvinCoded\MtnMomoAi + */ class MtnMomoAiServiceProvider extends ServiceProvider { /** - * Register any application services. + * Register package services and bindings. + * + * This method: + * - Merges the package configuration with the application's config + * - Registers the main MtnMomoAi class as a singleton + * - Sets up facade aliases for easy access + * + * @return void */ public function register() { - // Merge the package configuration $this->mergeConfigFrom(__DIR__ . '/../config/mtn-momo-ai.php', 'mtn-momo-ai'); - // Bind the main MtnMomoAi class as a singleton $this->app->singleton('mtn-momo-ai', function ($app) { return new MtnMomoAi( new Collections($app['config']['mtn-momo-ai']), @@ -30,22 +44,28 @@ public function register() ); }); - // Alias for easy facade access $this->app->alias('mtn-momo-ai', MtnMomoAi::class); } /** - * Bootstrap any application services. + * Bootstrap the package services. + * + * This method is called after all services are registered. + * It handles: + * - Registration of console commands + * - Publishing of configuration files + * - Any other bootstrapping requirements + * + * @return void */ public function boot() { if ($this->app->runningInConsole()) { - // Register your install command (optional/custom) + $this->commands([ - InstallCommand::class, + InstallCommand::class ]); - // Publish the config file $this->publishes([ __DIR__ . '/../config/mtn-momo-ai.php' => config_path('mtn-momo-ai.php'), ], 'config'); @@ -55,7 +75,11 @@ public function boot() /** * Get the services provided by the provider. * - * @return array + * Returns an array of service identifiers that this provider makes available + * to the application. These identifiers can be used for deferred loading + * of service providers. + * + * @return array */ public function provides() { diff --git a/src/Notifications/AnomalyDetectedNotification.php b/src/Notifications/AnomalyDetectedNotification.php index 79efa16..fa3ac73 100644 --- a/src/Notifications/AnomalyDetectedNotification.php +++ b/src/Notifications/AnomalyDetectedNotification.php @@ -6,22 +6,67 @@ use Illuminate\Notifications\Notification; use Illuminate\Notifications\Messages\MailMessage; +/** + * Class AnomalyDetectedNotification + * + * Handles notifications for detected anomalies in MTN MOMO transactions. + * This notification is triggered when the AI system detects unusual patterns + * or potential security concerns in transaction data. + * + * @package AlvinCoded\MtnMomoAi\Notifications + * @author Alvin Panford + * @since 1.0.0 + */ class AnomalyDetectedNotification extends Notification { use Queueable; + /** + * The anomaly data containing transaction details and detection information. + * + * @var array + */ protected $anomaly; + /** + * Create a new notification instance. + * + * @param array $anomaly An array containing anomaly details with the following structure: + * [ + * 'type' => string, // Type of anomaly detected + * 'transaction_id' => string, // ID of the suspicious transaction + * 'amount' => float|string, // Transaction amount + * 'severity' => string, // Severity level of the anomaly + * 'details' => array, // Additional detection details + * 'timestamp' => string // When the anomaly was detected + * ] + * @return void + */ public function __construct($anomaly) { $this->anomaly = $anomaly; } + /** + * Get the notification delivery channels. + * + * @param mixed $notifiable The entity receiving the notification + * @return array Returns an array of channels through which the notification should be delivered + */ public function via($notifiable) { return ['mail']; } + /** + * Get the mail representation of the notification. + * + * Builds an email message containing detailed information about the detected anomaly, + * including transaction details and recommended actions. + * + * @param mixed $notifiable The entity receiving the notification + * @return \Illuminate\Notifications\Messages\MailMessage + */ public function toMail($notifiable) { return (new MailMessage) @@ -38,6 +83,15 @@ public function toMail($notifiable) ->line('Please review this transaction immediately for potential security concerns.'); } + /** + * Get the array representation of the notification. + * + * Provides a serializable representation of the anomaly notification + * for storage or transmission through other channels. + * + * @param mixed $notifiable The entity receiving the notification + * @return array Returns an array containing the complete anomaly data + */ public function toArray($notifiable) { return [ diff --git a/src/Traits/MakesHttpRequests.php b/src/Traits/MakesHttpRequests.php index 7a8d7e7..4dee0c5 100644 --- a/src/Traits/MakesHttpRequests.php +++ b/src/Traits/MakesHttpRequests.php @@ -7,10 +7,24 @@ use AlvinCoded\MtnMomoAi\Exceptions\MtnMomoApiException; use Illuminate\Support\Facades\Cache; +/** + * Trait MakesHttpRequests + * + * Handles HTTP communication with the MTN MOMO API, including authentication, + * token management, and request handling. + * + * @package AlvinCoded\MtnMomoAi\Traits + */ trait MakesHttpRequests { + /** @var Client */ protected $httpClient; + /** + * Get or create a configured HTTP client instance. + * + * @return Client + */ protected function getHttpClient() { if (!$this->httpClient) { @@ -23,11 +37,21 @@ protected function getHttpClient() return $this->httpClient; } + /** + * Make an HTTP request to the MTN MOMO API. + * + * @param string $method HTTP method (GET, POST, etc.) + * @param string $endpoint API endpoint path + * @param array $data Request body data + * @param array $headers Additional headers + * @return array Decoded response + * @throws MtnMomoApiException When the API request fails + */ protected function makeRequest($method, $endpoint, $data = [], $headers = []) { $defaultHeaders = [ 'Authorization' => 'Bearer ' . $this->getAccessToken(), - 'X-Reference-Id' => $this->generateUuid(), + 'X-Reference-Id' => $this->config['api_user'], 'X-Target-Environment' => $this->config['environment'], 'Ocp-Apim-Subscription-Key' => $this->config['subscription_key'], 'Content-Type' => 'application/json', @@ -51,6 +75,15 @@ protected function makeRequest($method, $endpoint, $data = [], $headers = []) } } + /** + * Get a valid access token, either from cache or by requesting a new one. + * + * The MTN MOMO API access tokens are valid for 1 hour. This method implements + * caching to avoid requesting new tokens unnecessarily. + * + * @return string Valid access token + * @throws MtnMomoApiException When token retrieval fails + */ protected function getAccessToken() { $cacheKey = 'mtn_momo_access_token'; @@ -61,31 +94,57 @@ protected function getAccessToken() $token = $this->requestNewAccessToken(); - // Cache the token for slightly less than its expiration time (3600 seconds = 1 hour) + // Cache for 59 minutes (3540 seconds) to ensure token refresh before expiration Cache::put($cacheKey, $token, 3540); return $token; } + /** + * Request a new access token from the MTN MOMO API. + * + * This method handles the OAuth 2.0 client credentials flow to obtain + * a new access token using the API user credentials. + * + * @return string New access token + * @throws MtnMomoApiException When token request fails + */ protected function requestNewAccessToken() { $client = new Client(); - $response = $client->post($this->config['base_url'] . '/collection/token/', [ - 'headers' => [ - 'Authorization' => 'Basic ' . base64_encode($this->config['api_user'] . ':' . $this->config['api_key']), - 'Ocp-Apim-Subscription-Key' => $this->config['subscription_key'], - ], - ]); + try { + $response = $client->post($this->config['base_url'] . '/collection/token/', [ + 'headers' => [ + 'Authorization' => 'Basic ' . base64_encode($this->config['api_user'] . ':' . $this->config['api_key']), + 'Ocp-Apim-Subscription-Key' => $this->config['subscription_key'], + ], + ]); - $body = json_decode($response->getBody(), true); + $body = json_decode($response->getBody(), true); - if (!isset($body['access_token'])) { - throw new MtnMomoApiException('Failed to obtain access token'); - } + if (!isset($body['access_token'])) { + throw new MtnMomoApiException('Failed to obtain access token: Invalid response format'); + } - return $body['access_token']; + return $body['access_token']; + } catch (RequestException $e) { + throw new MtnMomoApiException( + 'Failed to obtain access token: ' . $e->getMessage(), + $e->getCode(), + $e->getResponse() ? json_decode($e->getResponse()->getBody()->getContents(), true) : null + ); + } } + /** + * Generate a UUID v4. + * + * Note: This method is kept for backward compatibility or custom UUID generation needs. + * For API requests, we now use the stored API user UUID instead. + * + * @return string UUID v4 + * @deprecated Use stored API user UUID instead for API requests + */ protected function generateUuid() { return sprintf(