diff --git a/.github/workflows/close-pull-request.yml b/.github/workflows/close-pull-request.yml deleted file mode 100644 index 591822c0f..000000000 --- a/.github/workflows/close-pull-request.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: Close Pull Request - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/hyperf/hyperf repository.

This Pull Request will close automatically.

Thanks! " diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 0f7d23faa..000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,25 +0,0 @@ -on: - push: - # Sequence of patterns matched against refs/tags - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Release - -jobs: - release: - name: Release - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: false diff --git a/.gitignore b/.gitignore index 7e11e886d..8817c90f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/vendor/ -composer.lock +.idea +.vscode *.cache -*.log \ No newline at end of file +*.log +vendor/ diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 000000000..1b4f0b774 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,99 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + '@Symfony' => true, + '@DoctrineAnnotation' => true, + '@PhpCsFixer' => true, + 'header_comment' => [ + 'comment_type' => 'PHPDoc', + 'header' => $header, + 'separate' => 'none', + 'location' => 'after_declare_strict', + ], + 'array_syntax' => [ + 'syntax' => 'short' + ], + 'list_syntax' => [ + 'syntax' => 'short' + ], + 'concat_space' => [ + 'spacing' => 'one' + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'declare', + ], + ], + 'general_phpdoc_annotation_remove' => [ + 'annotations' => [ + 'author' + ], + ], + 'ordered_imports' => [ + 'imports_order' => [ + 'class', 'function', 'const', + ], + 'sort_algorithm' => 'alpha', + ], + 'single_line_comment_style' => [ + 'comment_types' => [ + ], + ], + 'yoda_style' => [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'constant_case' => [ + 'case' => 'lower', + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ], + 'class_attributes_separation' => true, + 'combine_consecutive_unsets' => true, + 'declare_strict_types' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_static_reference' => true, + 'no_useless_else' => true, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'not_operator_with_space' => false, + 'ordered_class_elements' => true, + 'php_unit_strict' => false, + 'phpdoc_separation' => false, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'multiline_comment_opening_closing' => true, + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ], + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in(__DIR__) + ) + ->setUsingCache(true); diff --git a/LICENSE b/LICENSE index c35d3f5a8..36eac0473 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) Hyperf +Copyright (c) Hyperf & OpenCodeCo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 000000000..aaa3423d1 --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Hyperf Metric + +🔭 Drop-in replacement for the `hyperf/metric` component. + +Suited for special needs, especially for OpenTelemetry, New Relic and Dynatrace platforms. + +## Getting started + +### Install + +#### Add OpenCodeCo's Composer repository: +```shell +composer config repositories.opencodeco composer https://composer.opencodeco.dev +``` + +#### Update your `hyperf/metric`: +```shell +composer update hyperf/metric +``` diff --git a/composer.json b/composer.json index 3d6170a44..0b8a57c03 100644 --- a/composer.json +++ b/composer.json @@ -9,29 +9,51 @@ "metrics", "influxdb" ], - "description": "hyperf metric component", + "description": "Drop-in replacement for the Hyperf Metric component.", "require": { - "php": ">=8.0", - "hyperf/codec": "~3.0.0", - "hyperf/contract": "~3.0.0", - "hyperf/engine": "^1.5|^2.3", - "hyperf/guzzle": "~3.0.0", - "hyperf/support": "~3.0.0", - "hyperf/utils": "~3.0.0", - "promphp/prometheus_client_php": "2.2.*", - "psr/container": "^1.0|^2.0", + "php": ">=8.1", + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/engine": "^2.3", + "hyperf/guzzle": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0", - "psr/http-message": "^1.0|^2.0" + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.21", + "hyperf/async-queue": "^3.0", + "hyperf/config": "^3.0", + "hyperf/db-connection": "^3.0", + "hyperf/di": "^3.0", + "hyperf/event": "^3.0", + "hyperf/framework": "^3.0", + "hyperf/process": "^3.0", + "hyperf/redis": "^3.0", + "hyperf/testing": "^3.0", + "influxdb/influxdb-php": "^1.15", + "mockery/mockery": "^1.6", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-mockery": "^1.1", + "rector/rector": "^0.17.5", + "slickdeals/statsd": "^3.1", + "swoole/ide-helper": "^5.0" }, "suggest": { - "slickdeals/statsd": "Required to use StatdD driver.", - "influxdb/influxdb-php": "Required to use InfluxDB driver.", "hyperf/di": "Required to use annotations.", "hyperf/event": "Required to use listeners for default metrics.", + "hyperf/http-server": "Required to capture routes in middleware.", "hyperf/process": "Required to use standalone process, or you have to roll your own", "hyperf/retry": "Required to use back-off retry implementation.", - "hyperf/http-server": "Required to capture routes in middleware." + "influxdb/influxdb-php": "Required to use InfluxDB driver.", + "promphp/prometheus_client_php": "Required to use Prometheus driver.(2.2.*)", + "slickdeals/statsd": "Required to use StatdD driver." }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "psr-4": { "Hyperf\\Metric\\": "src/" @@ -42,15 +64,24 @@ "HyperfTest\\Metric\\": "tests/" } }, - "minimum-stability": "dev", - "prefer-stable": true, + "scripts": { + "test": "co-phpunit", + "test:filter": "co-phpunit --prepend test/bootstrap.php -c phpunit.xml --colors=always --testdox --filter", + "test-coverage": "co-phpunit --coverage-clover clover.xml", + "cs-fix": "php-cs-fixer fix $1", + "analyse": "phpstan analyse --memory-limit=-1 -l 5 -c phpstan.neon", + "rector": "rector process --clear-cache" + }, "config": { "optimize-autoloader": true, - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "phpstan/extension-installer": true + } }, "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" }, "hyperf": { "config": "Hyperf\\Metric\\ConfigProvider" diff --git a/composer.lock b/composer.lock new file mode 100644 index 000000000..7d95ba90e --- /dev/null +++ b/composer.lock @@ -0,0 +1,8360 @@ +{ + "_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": "60d230790b3107f97e331017e86b7837", + "packages": [ + { + "name": "doctrine/inflector", + "version": "2.0.9", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/2930cd5ef353871c821d5c43ed030d39ac8cfe65", + "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65", + "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.9" + }, + "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-01-15T18:05:13+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "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": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "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.8.1" + }, + "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": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "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.2" + }, + "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": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "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", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "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.6.2" + }, + "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": "2023-12-03T20:05:35+00:00" + }, + { + "name": "hyperf/code-parser", + "version": "v3.1.4", + "source": { + "type": "git", + "url": "https://github.com/hyperf/code-parser.git", + "reference": "e36ac337cf7852aaa817db61ade0941d8826f0d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/code-parser/zipball/e36ac337cf7852aaa817db61ade0941d8826f0d8", + "reference": "e36ac337cf7852aaa817db61ade0941d8826f0d8", + "shasum": "" + }, + "require": { + "hyperf/collection": "~3.1.0", + "hyperf/stringable": "~3.1.0", + "hyperf/support": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "jean85/pretty-package-versions": "Required to use PrettyVersions. (^1.2|^2.0)", + "nikic/php-parser": "Required to use PhpParser. (^4.0)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\CodeParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A code parser component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "code-parser", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-28T08:46:40+00:00" + }, + { + "name": "hyperf/codec", + "version": "v3.1.4", + "source": { + "type": "git", + "url": "https://github.com/hyperf/codec.git", + "reference": "764e81cf3ba358813ea8e058bf2dabd16058cb2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/codec/zipball/764e81cf3ba358813ea8e058bf2dabd16058cb2d", + "reference": "764e81cf3ba358813ea8e058bf2dabd16058cb2d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-xml": "*", + "hyperf/contract": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "ext-igbinary": "Required to use IgbinarySerializerPacker." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Codec\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A codec component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "codec", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-25T06:07:48+00:00" + }, + { + "name": "hyperf/collection", + "version": "v3.1.7", + "source": { + "type": "git", + "url": "https://github.com/hyperf/collection.git", + "reference": "40e25ca34f798e173a1f9a6871d56a6abae43dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/collection/zipball/40e25ca34f798e173a1f9a6871d56a6abae43dbb", + "reference": "40e25ca34f798e173a1f9a6871d56a6abae43dbb", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Collection package which come from illuminate/collections", + "homepage": "https://hyperf.io", + "keywords": [ + "collection", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-26T01:52:03+00:00" + }, + { + "name": "hyperf/conditionable", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/conditionable.git", + "reference": "18da1405ae39a775bd3fae8cec98841eaa22f013" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/conditionable/zipball/18da1405ae39a775bd3fae8cec98841eaa22f013", + "reference": "18da1405ae39a775bd3fae8cec98841eaa22f013", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Conditionable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Macroable package which come from illuminate/conditionable", + "homepage": "https://hyperf.io", + "keywords": [ + "conditionable", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/context", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/context.git", + "reference": "8307d6c924ed67c7abd47874ec14f0e2e3e4b732" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/context/zipball/8307d6c924ed67c7abd47874ec14f0e2e3e4b732", + "reference": "8307d6c924ed67c7abd47874ec14f0e2e3e4b732", + "shasum": "" + }, + "require": { + "hyperf/engine": "^2.0", + "php": ">=8.1" + }, + "suggest": { + "swow/psr7-plus": "Required to use RequestContext and ResponseContext" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Context\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A coroutine/application context library.", + "homepage": "https://hyperf.io", + "keywords": [ + "Context", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/contract", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/contract.git", + "reference": "f5379df6df65363d645506f373888372135ac0c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/contract/zipball/f5379df6df65363d645506f373888372135ac0c6", + "reference": "f5379df6df65363d645506f373888372135ac0c6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Contract\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The contracts of Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-11T03:14:01+00:00" + }, + { + "name": "hyperf/coordinator", + "version": "v3.1.7", + "source": { + "type": "git", + "url": "https://github.com/hyperf/coordinator.git", + "reference": "0b812abc6253dec888f5484e1bbd87d7e206b8c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/coordinator/zipball/0b812abc6253dec888f5484e1bbd87d7e206b8c3", + "reference": "0b812abc6253dec888f5484e1bbd87d7e206b8c3", + "shasum": "" + }, + "require": { + "hyperf/engine": "^2.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Coordinator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Coordinator", + "homepage": "https://hyperf.io", + "keywords": [ + "Coordinator", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-22T07:40:06+00:00" + }, + { + "name": "hyperf/coroutine", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/coroutine.git", + "reference": "cd5bad67724c5c7a7ad749d8e9eb045470488d75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/coroutine/zipball/cd5bad67724c5c7a7ad749d8e9eb045470488d75", + "reference": "cd5bad67724c5c7a7ad749d8e9eb045470488d75", + "shasum": "" + }, + "require": { + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/engine": "^2.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Coroutine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Coroutine", + "homepage": "https://hyperf.io", + "keywords": [ + "coroutine", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-01T06:59:45+00:00" + }, + { + "name": "hyperf/engine", + "version": "v2.10.4", + "source": { + "type": "git", + "url": "https://github.com/hyperf/engine.git", + "reference": "34ba1825f5b596c677d027e60ec4e2b75c65d09e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/engine/zipball/34ba1825f5b596c677d027e60ec4e2b75c65d09e", + "reference": "34ba1825f5b596c677d027e60ec4e2b75c65d09e", + "shasum": "" + }, + "require": { + "hyperf/engine-contract": "~1.9.0", + "php": ">=8.0" + }, + "conflict": { + "ext-swoole": "<5.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "hyperf/guzzle": "^3.0", + "hyperf/http-message": " 3.0.*", + "mockery/mockery": "^1.5", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "dev-master" + }, + "suggest": { + "ext-sockets": "*", + "ext-swoole": ">=5.0", + "hyperf/http-message": "Required to use ResponseEmitter.", + "psr/http-message": "Required to use WebSocket Frame." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + }, + "hyperf": { + "config": "Hyperf\\Engine\\ConfigProvider" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Engine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Coroutine engine provided by swoole.", + "keywords": [ + "engine", + "hyperf", + "php", + "swoole" + ], + "support": { + "issues": "https://github.com/hyperf/engine/issues", + "source": "https://github.com/hyperf/engine/tree/v2.10.4" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-15T07:47:12+00:00" + }, + { + "name": "hyperf/engine-contract", + "version": "v1.9.1", + "source": { + "type": "git", + "url": "https://github.com/hyperf/engine-contract.git", + "reference": "fec2e45f35404b2e5b4c3eaf1b0dce67d60771eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/engine-contract/zipball/fec2e45f35404b2e5b4c3eaf1b0dce67d60771eb", + "reference": "fec2e45f35404b2e5b4c3eaf1b0dce67d60771eb", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": ">=7.0", + "psr/http-message": "^1.0", + "swoole/ide-helper": "^4.5" + }, + "suggest": { + "psr/http-message": "Required to use WebSocket Frame." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Engine\\Contract\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Contract for Coroutine Engine", + "keywords": [ + "contract", + "coroutine", + "engine", + "hyperf", + "php" + ], + "support": { + "issues": "https://github.com/hyperf/engine-contract/issues", + "source": "https://github.com/hyperf/engine-contract/tree/v1.9.1" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-15T07:37:14+00:00" + }, + { + "name": "hyperf/guzzle", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/guzzle.git", + "reference": "df01c9b6ba645347a05113c6bcac2314145e611c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/guzzle/zipball/df01c9b6ba645347a05113c6bcac2314145e611c", + "reference": "df01c9b6ba645347a05113c6bcac2314145e611c", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.3|^7.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0|^2.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "hyperf/pool": "Required to use pool handler." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Guzzle\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Guzzle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Swoole coroutine handler for guzzle", + "keywords": [ + "Guzzle", + "handler", + "php", + "swoole" + ], + "support": { + "issues": "https://github.com/hyperf/guzzle/issues", + "source": "https://github.com/hyperf/guzzle/tree/v3.1.0" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/macroable", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/macroable.git", + "reference": "de5b07be74d666f04ecef4ce5ee6ceb97d846cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/macroable/zipball/de5b07be74d666f04ecef4ce5ee6ceb97d846cfa", + "reference": "de5b07be74d666f04ecef4ce5ee6ceb97d846cfa", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Macroable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Macroable package which come from illuminate/macroable", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "macroable", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/serializer", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/serializer.git", + "reference": "8fae2fa4342cbefead70b54e42e11c228d8be94b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/serializer/zipball/8fae2fa4342cbefead70b54e42e11c228d8be94b", + "reference": "8fae2fa4342cbefead70b54e42e11c228d8be94b", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "hyperf/di": "Required to use ExceptionNormalizer", + "symfony/property-access": "Required to use SymfonyNormalizer (^5.0|^6.0)", + "symfony/serializer": "Required to use SymfonyNormalizer (^5.0|^6.0)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Serializer\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Serializer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A serializer component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole", + "tappable" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/stringable", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/stringable.git", + "reference": "10465337a7bbf528ab28bd84330d795a5b3e06bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/stringable/zipball/10465337a7bbf528ab28bd84330d795a5b3e06bd", + "reference": "10465337a7bbf528ab28bd84330d795a5b3e06bd", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "hyperf/collection": "~3.1.0", + "hyperf/conditionable": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "doctrine/inflector": "Required to use plural and singular methods.(^2.0|^3.0)", + "ramsey/uuid": "Required to use uuid and orderedUuid methods.(^4.7|^5.0)", + "symfony/uid": "Required to use ulid method.(^5.0|^6.0)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Stringable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Stringable package which come from illuminate/support", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "stringable", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/support", + "version": "v3.1.7", + "source": { + "type": "git", + "url": "https://github.com/hyperf/support.git", + "reference": "5f3bb356632089f92feefb7dd7202c22444404e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/support/zipball/5f3bb356632089f92feefb7dd7202c22444404e5", + "reference": "5f3bb356632089f92feefb7dd7202c22444404e5", + "shasum": "" + }, + "require": { + "hyperf/collection": "~3.1.0", + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/stringable": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "nesbot/carbon": "Use Carbon as DateTime object.(^2.0)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Support\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A support component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "support", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-22T08:45:43+00:00" + }, + { + "name": "hyperf/tappable", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/tappable.git", + "reference": "f640e37006dad09ca6f2b9a4cf047907aaebf002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/tappable/zipball/f640e37006dad09ca6f2b9a4cf047907aaebf002", + "reference": "f640e37006dad09ca6f2b9a4cf047907aaebf002", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Tappable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Macroable package which come from illuminate/tappable", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole", + "tappable" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/utils", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/utils.git", + "reference": "10522904195eb5af9090bbd072589fb387c91041" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/utils/zipball/10522904195eb5af9090bbd072589fb387c91041", + "reference": "10522904195eb5af9090bbd072589fb387c91041", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "hyperf/code-parser": "~3.1.0", + "hyperf/codec": "~3.1.0", + "hyperf/collection": "~3.1.0", + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coordinator": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/engine": "^2.0", + "hyperf/macroable": "~3.1.0", + "hyperf/serializer": "~3.1.0", + "hyperf/stringable": "~3.1.0", + "hyperf/support": "~3.1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A tools package that could help developer solved the problem quickly.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "swoole", + "utils" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "promphp/prometheus_client_php", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/PromPHP/prometheus_client_php.git", + "reference": "ad2a85fa52a7b9f6e6d84095cd34d1cb6f0a06bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PromPHP/prometheus_client_php/zipball/ad2a85fa52a7b9f6e6d84095cd34d1cb6f0a06bc", + "reference": "ad2a85fa52a7b9f6e6d84095cd34d1cb6f0a06bc", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "endclothing/prometheus_client_php": "*", + "jimdo/prometheus_client_php": "*", + "lkaemmerling/prometheus_client_php": "*" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.3|^7.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5.4", + "phpstan/phpstan-phpunit": "^1.1.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/polyfill-apcu": "^1.6" + }, + "suggest": { + "ext-apc": "Required if using APCu.", + "ext-redis": "Required if using Redis.", + "promphp/prometheus_push_gateway_php": "An easy client for using Prometheus PushGateway.", + "symfony/polyfill-apcu": "Required if you use APCu on PHP8.0+" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Prometheus\\": "src/Prometheus/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Lukas Kämmerling", + "email": "kontakt@lukas-kaemmerling.de" + } + ], + "description": "Prometheus instrumentation library for PHP applications.", + "support": { + "issues": "https://github.com/PromPHP/prometheus_client_php/issues", + "source": "https://github.com/PromPHP/prometheus_client_php/tree/v2.9.0" + }, + "time": "2023-12-20T06:22:58+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.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "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": "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/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+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": "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": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + } + ], + "packages-dev": [ + { + "name": "carbonphp/carbon-doctrine-types", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/a31d3358a2a5d6ae947df1691d1f321418a5f3d5", + "reference": "a31d3358a2a5d6ae947df1691d1f321418a5f3d5", + "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.1.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": "2023-12-10T15:33:53+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-10-11T07:11:09+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "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.0" + }, + "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": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.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": "2022-02-25T21:32:43+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, + { + "name": "fig/http-message-util", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message-util.git", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message-util/zipball/9d94dc0154230ac39e5bf89398b324a86f63f765", + "reference": "9d94dc0154230ac39e5bf89398b324a86f63f765", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "suggest": { + "psr/http-message": "The package containing the PSR-7 interfaces" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Fig\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Utility classes and constants for use with PSR-7 (psr/http-message)", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-message-util/issues", + "source": "https://github.com/php-fig/http-message-util/tree/1.1.5" + }, + "time": "2020-11-24T22:02:12+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.48.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a92472c6fb66349de25211f31c77eceae3df024e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a92472c6fb66349de25211f31c77eceae3df024e", + "reference": "a92472c6fb66349de25211f31c77eceae3df024e", + "shasum": "" + }, + "require": { + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.48.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-01-19T21:44:39+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "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.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:16:48+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": "hyperf/async-queue", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/hyperf/async-queue.git", + "reference": "349d1f7d3eb317f2d3b8a16399d8b0e7405fdbdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/async-queue/zipball/349d1f7d3eb317f2d3b8a16399d8b0e7405fdbdf", + "reference": "349d1f7d3eb317f2d3b8a16399d8b0e7405fdbdf", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/collection": "~3.1.0", + "hyperf/command": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Required to dispatch a event.", + "hyperf/logger": "Required to use QueueHandleListener.", + "hyperf/process": "Auto register the consumer process for server." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\AsyncQueue\\ConfigProvider" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\AsyncQueue\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A async queue component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "async-queue", + "hyperf", + "php" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-12T01:57:51+00:00" + }, + { + "name": "hyperf/command", + "version": "v3.1.7", + "source": { + "type": "git", + "url": "https://github.com/hyperf/command.git", + "reference": "72631c29841981812a5a245f5fe81c7a8e423b36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/command/zipball/72631c29841981812a5a245f5fe81c7a8e423b36", + "reference": "72631c29841981812a5a245f5fe81c7a8e423b36", + "shasum": "" + }, + "require": { + "hyperf/collection": "~3.1.0", + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/di": "~3.1.0", + "hyperf/stringable": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "php": ">=8.1", + "psr/event-dispatcher": "^1.0", + "symfony/console": "^5.0|^6.0|^7.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Required to use listeners." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Command\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Command\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Command for hyperf", + "keywords": [ + "command", + "php", + "swoole" + ], + "support": { + "issues": "https://github.com/hyperf/command/issues", + "source": "https://github.com/hyperf/command/tree/v3.1.7" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-24T06:16:09+00:00" + }, + { + "name": "hyperf/config", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/config.git", + "reference": "1364385aeb0c64fa018d2655119a5ab176aadebc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/config/zipball/1364385aeb0c64fa018d2655119a5ab176aadebc", + "reference": "1364385aeb0c64fa018d2655119a5ab176aadebc", + "shasum": "" + }, + "require": { + "hyperf/collection": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "symfony/finder": "^5.0|^6.0|^7.0" + }, + "suggest": { + "hyperf/context": "Required to use config()", + "hyperf/di": "Allows using @Value annotation", + "hyperf/event": "Allows using @Value annotation", + "hyperf/framework": "Allows using @Value annotation", + "vlucas/phpdotenv": "Allows using enviroment value to override the config" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Config\\ConfigProvider" + } + }, + "autoload": { + "files": [ + "./src/Functions.php" + ], + "psr-4": { + "Hyperf\\Config\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An independent component that provides configuration container.", + "homepage": "https://hyperf.io", + "keywords": [ + "config", + "configuration", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-08T02:35:39+00:00" + }, + { + "name": "hyperf/database", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/hyperf/database.git", + "reference": "a3ff1e706ba60925700ee854d47d1d9de2a4b705" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/database/zipball/a3ff1e706ba60925700ee854d47d1d9de2a4b705", + "reference": "a3ff1e706ba60925700ee854d47d1d9de2a4b705", + "shasum": "" + }, + "require": { + "hyperf/code-parser": "~3.1.0", + "hyperf/collection": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "hyperf/utils": "~3.1.0", + "nesbot/carbon": "^2.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "doctrine/dbal": "Required to rename columns (^3.0).", + "nikic/php-parser": "Required to use ModelCommand. (^4.0)", + "php-di/phpdoc-reader": "Required to use ModelCommand. (^2.2)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Database\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A flexible database library.", + "homepage": "https://hyperf.io", + "keywords": [ + "database", + "hyperf", + "php" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-04T13:47:09+00:00" + }, + { + "name": "hyperf/db-connection", + "version": "v3.1.7", + "source": { + "type": "git", + "url": "https://github.com/hyperf/db-connection.git", + "reference": "a23ffd3b82d858ff912ec08b0a613eae0c840e4b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/db-connection/zipball/a23ffd3b82d858ff912ec08b0a613eae0c840e4b", + "reference": "a23ffd3b82d858ff912ec08b0a613eae0c840e4b", + "shasum": "" + }, + "require": { + "hyperf/database": "~3.1.0", + "hyperf/di": "~3.1.0", + "hyperf/framework": "~3.1.0", + "hyperf/model-listener": "~3.1.0", + "hyperf/pool": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\DbConnection\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\DbConnection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A hyperf db connection handler for hyperf/database.", + "homepage": "https://hyperf.io", + "keywords": [ + "Connection", + "database", + "hyperf", + "php" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-22T08:45:43+00:00" + }, + { + "name": "hyperf/di", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/hyperf/di.git", + "reference": "e042ac1cef7da80df15ba77a5a9f9abfe70627d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/di/zipball/e042ac1cef7da80df15ba77a5a9f9abfe70627d0", + "reference": "e042ac1cef7da80df15ba77a5a9f9abfe70627d0", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0", + "hyperf/code-parser": "~3.1.0", + "hyperf/pipeline": "~3.1.0", + "hyperf/stdlib": "~3.1.0", + "hyperf/support": "~3.1.0", + "nikic/php-parser": "^4.1", + "php": ">=8.1", + "php-di/phpdoc-reader": "^2.2", + "psr/container": "^1.0|^2.0", + "symfony/finder": "^5.0|^6.0|^7.0", + "vlucas/phpdotenv": "^5.0" + }, + "suggest": { + "ext-pcntl": "Required to scan annotations.", + "hyperf/config": "Require this component for annotation scan progress to retrieve the scan path." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Di\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Di\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A DI for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "annotation", + "di", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-08T13:45:10+00:00" + }, + { + "name": "hyperf/dispatcher", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/dispatcher.git", + "reference": "582dc948da50db771294130bba465d8163f11ab1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/dispatcher/zipball/582dc948da50db771294130bba465d8163f11ab1", + "reference": "582dc948da50db771294130bba465d8163f11ab1", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0|^2.0", + "psr/http-server-middleware": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Dispatcher\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Dispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A HTTP Server for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "dispatcher", + "filter", + "hyperf", + "middleware", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/event", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/event.git", + "reference": "6eada5f74ce80786c567d5aed0361d51175217bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/event/zipball/6eada5f74ce80786c567d5aed0361d51175217bb", + "reference": "6eada5f74ce80786c567d5aed0361d51175217bb", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/stdlib": "~3.1.0", + "php": ">=8.1", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotatioins." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Event\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "an event manager that implements PSR-14.", + "homepage": "https://hyperf.io", + "keywords": [ + "event", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/exception-handler", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/hyperf/exception-handler.git", + "reference": "8987b0764c6ade4e31b9753152e80dbac9a4a785" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/exception-handler/zipball/8987b0764c6ade4e31b9753152e80dbac9a4a785", + "reference": "8987b0764c6ade4e31b9753152e80dbac9a4a785", + "shasum": "" + }, + "require": { + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/dispatcher": "~3.1.0", + "hyperf/http-message": "~3.1.0", + "hyperf/stdlib": "~3.1.0", + "hyperf/support": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/http-message": "^1.0|^2.0", + "swow/psr7-plus": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use #[ExceptionHandler]", + "hyperf/event": "Required to use listeners", + "hyperf/framework": "Required to use listeners", + "hyperf/stringable": "Required to use WhoopsExceptionHandler" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\ExceptionHandler\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ExceptionHandler\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Exception handler for hyperf", + "homepage": "https://hyperf.io", + "keywords": [ + "exception-handler", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-04T02:06:27+00:00" + }, + { + "name": "hyperf/framework", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/framework.git", + "reference": "3b24833c8341a8f71cbf957653c10dee033604c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/framework/zipball/3b24833c8341a8f71cbf957653c10dee033604c5", + "reference": "3b24833c8341a8f71cbf957653c10dee033604c5", + "shasum": "" + }, + "require": { + "fig/http-message-util": "^1.1.2", + "hyperf/contract": "~3.1.0", + "hyperf/coordinator": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0" + }, + "suggest": { + "ext-swoole": "Required to use swoole engine.", + "hyperf/command": "Required to use Command annotation.", + "hyperf/di": "Required to use Command annotation.", + "hyperf/dispatcher": "Required to use BootApplication event.", + "symfony/event-dispatcher": "Required to use symfony event dispatcher (^5.0|^6.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Framework\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Framework\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", + "homepage": "https://hyperf.io", + "keywords": [ + "Microservice", + "framework", + "hyperf", + "middleware", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/http-message", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-message.git", + "reference": "1aa6b862003262d1186f5978f251970f687c16d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/http-message/zipball/1aa6b862003262d1186f5978f251970f687c16d5", + "reference": "1aa6b862003262d1186f5978f251970f687c16d5", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/engine": "^2.7", + "hyperf/support": "~3.1.0", + "laminas/laminas-mime": "^2.7", + "php": ">=8.1", + "psr/http-message": "^1.0|^2.0", + "swow/psr7-plus": "^1.0" + }, + "suggest": { + "psr/container": "Required to replace RequestParserInterface." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\HttpMessage\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\HttpMessage\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "microservice framework base on swoole", + "keywords": [ + "http-message", + "hyperf", + "php", + "swoole" + ], + "support": { + "issues": "https://github.com/hyperf/http-message/issues", + "source": "https://github.com/hyperf/http-message/tree/v3.1.0" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/http-server", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-server.git", + "reference": "c61c4cead88bbe14152e699760bc779a9a21dd05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/http-server/zipball/c61c4cead88bbe14152e699760bc779a9a21dd05", + "reference": "c61c4cead88bbe14152e699760bc779a9a21dd05", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/collection": "~3.1.0", + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/dispatcher": "~3.1.0", + "hyperf/event": "~3.1.0", + "hyperf/exception-handler": "~3.1.0", + "hyperf/http-message": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/serializer": "~3.1.0", + "hyperf/server": "~3.1.0", + "hyperf/stdlib": "~3.1.0", + "hyperf/support": "~3.1.0", + "nikic/fast-route": "^1.3", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "swow/psr7-plus": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\HttpServer\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\HttpServer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A HTTP Server for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "http", + "http-server", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-01-18T04:33:08+00:00" + }, + { + "name": "hyperf/model-listener", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/model-listener.git", + "reference": "03ff9d027871fed6f1be784a7835f5e107c7de5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/model-listener/zipball/03ff9d027871fed6f1be784a7835f5e107c7de5f", + "reference": "03ff9d027871fed6f1be784a7835f5e107c7de5f", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/database": "~3.1.0", + "hyperf/di": "~3.1.0", + "hyperf/event": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\ModelListener\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ModelListener\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A model listener for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "model-listener", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/pipeline", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/pipeline.git", + "reference": "44352f9b20c61c372dae655894f7a8f2bb86d0de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/pipeline/zipball/44352f9b20c61c372dae655894f7a8f2bb86d0de", + "reference": "44352f9b20c61c372dae655894f7a8f2bb86d0de", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Pipeline\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Hyperf Macroable package which come from illuminate/pipeline", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "pipeline", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/pool", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/pool.git", + "reference": "75b0d64bf44a77b95a657e6c0a0a2a53aeafe577" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/pool/zipball/75b0d64bf44a77b95a657e6c0a0a2a53aeafe577", + "reference": "75b0d64bf44a77b95a657e6c0a0a2a53aeafe577", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Pool\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Pool\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An independent universal connection pool component.", + "homepage": "https://hyperf.io", + "keywords": [ + "connection-pool", + "hyperf", + "php", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/process", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/process.git", + "reference": "962149325efc5f762e85286f2cb1cc5511d8a21a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/process/zipball/962149325efc5f762e85286f2cb1cc5511d8a21a", + "reference": "962149325efc5f762e85286f2cb1cc5511d8a21a", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Required to dump the message before and after process.", + "hyperf/framework": "Required to use BootProcessListener." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Process\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Process\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A process component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "process" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/redis", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/redis.git", + "reference": "4cbb9579e5295f0cc12bedbc81962eca24f10ff1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/redis/zipball/4cbb9579e5295f0cc12bedbc81962eca24f10ff1", + "reference": "4cbb9579e5295f0cc12bedbc81962eca24f10ff1", + "shasum": "" + }, + "require": { + "ext-redis": "^5.0|^6.0", + "hyperf/contract": "~3.1.0", + "hyperf/pool": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0" + }, + "suggest": { + "ext-redis": "Required to use sentinel mode (>=5.2).", + "hyperf/di": "Create the RedisPool via dependency injection." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Redis\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Redis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A redis component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "pool", + "redis" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/server", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/hyperf/server.git", + "reference": "d92c3756ccadd02349fd417eef382d8d55c970bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/server/zipball/d92c3756ccadd02349fd417eef382d8d55c970bf", + "reference": "d92c3756ccadd02349fd417eef382d8d55c970bf", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/coordinator": "~3.1.0", + "hyperf/engine": "^2.8", + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0|^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0", + "symfony/console": "^5.0|^6.0|^7.0" + }, + "suggest": { + "hyperf/event": "Dump the info after server start.", + "hyperf/framework": "Dump the info after server start." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + }, + "hyperf": { + "config": "Hyperf\\Server\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A base server library for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "server", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-12T08:06:45+00:00" + }, + { + "name": "hyperf/stdlib", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/stdlib.git", + "reference": "25b73da235551d0d71d9157324709abaea36c455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/stdlib/zipball/25b73da235551d0d71d9157324709abaea36c455", + "reference": "25b73da235551d0d71d9157324709abaea36c455", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A stdlib component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "stdlib", + "swoole" + ], + "support": { + "docs": "https://hyperf.wiki", + "issues": "https://github.com/hyperf/hyperf/issues", + "pull-request": "https://github.com/hyperf/hyperf/pulls", + "source": "https://github.com/hyperf/hyperf" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-11-24T03:10:53+00:00" + }, + { + "name": "hyperf/testing", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/hyperf/testing.git", + "reference": "00be4729882b0fcc9f5307b08db635f6ad3b56cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/testing/zipball/00be4729882b0fcc9f5307b08db635f6ad3b56cc", + "reference": "00be4729882b0fcc9f5307b08db635f6ad3b56cc", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/collection": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/http-message": "~3.1.0", + "hyperf/http-server": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "phpunit/phpunit": "^10.0", + "psr/container": "^1.0|^2.0", + "symfony/http-foundation": "^5.4|^6.0" + }, + "suggest": { + "fakerphp/faker": "Required to use Faker feature.(^1.23)" + }, + "bin": [ + "co-phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Testing\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Testing for hyperf", + "keywords": [ + "dev", + "php", + "swoole", + "testing" + ], + "support": { + "source": "https://github.com/hyperf/testing/tree/v3.1.3" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2023-12-17T08:53:12+00:00" + }, + { + "name": "influxdb/influxdb-php", + "version": "1.15.2", + "source": { + "type": "git", + "url": "https://github.com/influxdata/influxdb-php.git", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "Curl extension, needed for Curl driver", + "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." + }, + "type": "library", + "autoload": { + "psr-4": { + "InfluxDB\\": "src/InfluxDB" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Hoogendijk", + "email": "stephen@tca0.nl" + }, + { + "name": "Daniel Martinez", + "email": "danimartcas@hotmail.com" + }, + { + "name": "Gianluca Arbezzano", + "email": "gianarb92@gmail.com" + } + ], + "description": "InfluxDB client library for PHP", + "keywords": [ + "client", + "influxdata", + "influxdb", + "influxdb class", + "influxdb client", + "influxdb library", + "time series" + ], + "support": { + "issues": "https://github.com/influxdata/influxdb-php/issues", + "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" + }, + "abandoned": true, + "time": "2020-12-26T17:45:17+00:00" + }, + { + "name": "laminas/laminas-mime", + "version": "2.12.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-mime.git", + "reference": "08cc544778829b7d68d27a097885bd6e7130135e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-mime/zipball/08cc544778829b7d68d27a097885bd6e7130135e", + "reference": "08cc544778829b7d68d27a097885bd6e7130135e", + "shasum": "" + }, + "require": { + "laminas/laminas-stdlib": "^2.7 || ^3.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "conflict": { + "zendframework/zend-mime": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~2.4.0", + "laminas/laminas-mail": "^2.19.0", + "phpunit/phpunit": "~9.5.25" + }, + "suggest": { + "laminas/laminas-mail": "Laminas\\Mail component" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Mime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Create and parse MIME messages and parts", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "mime" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-mime/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-mime/issues", + "rss": "https://github.com/laminas/laminas-mime/releases.atom", + "source": "https://github.com/laminas/laminas-mime" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2023-11-02T16:47:19+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.19.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "6a192dd0882b514e45506f533b833b623b78fff3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/6a192dd0882b514e45506f533b833b623b78fff3", + "reference": "6a192dd0882b514e45506f533b833b623b78fff3", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "conflict": { + "zendframework/zend-stdlib": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^2.5", + "phpbench/phpbench": "^1.2.15", + "phpunit/phpunit": "^10.5.8", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.20.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Laminas\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "SPL extensions, array utilities, error handlers, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "stdlib" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-stdlib/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-stdlib/issues", + "rss": "https://github.com/laminas/laminas-stdlib/releases.atom", + "source": "https://github.com/laminas/laminas-stdlib" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2024-01-19T12:39:49+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.7", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", + "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", + "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.10", + "symplify/easy-coding-standard": "^12.0.8" + }, + "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": "2023-12-10T02:24:34+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "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", + "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.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.72.2", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/3e7edc41b58d65509baeb0d4a14c8fa41d627130", + "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "*", + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "psr/clock": "^1.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0", + "doctrine/orm": "^2.7 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "ondrejmirtes/better-reflection": "*", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "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-01-19T00:21:53+00:00" + }, + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "FastRoute\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "support": { + "issues": "https://github.com/nikic/FastRoute/issues", + "source": "https://github.com/nikic/FastRoute/tree/master" + }, + "time": "2018-02-13T20:26:39+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-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/v4.18.0" + }, + "time": "2023-12-10T21:03:43+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "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.3" + }, + "time": "2021-07-20T11:28:43+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": "php-di/phpdoc-reader", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PhpDocReader.git", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/66daff34cbd2627740ffec9469ffbac9f8c8185c", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpDocReader\\": "src/PhpDocReader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", + "keywords": [ + "phpdoc", + "reflection" + ], + "support": { + "issues": "https://github.com/PHP-DI/PhpDocReader/issues", + "source": "https://github.com/PHP-DI/PhpDocReader/tree/2.2.1" + }, + "time": "2020-10-12T12:39:22+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "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.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-11-12T21:59:55+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", + "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" + }, + "time": "2023-05-24T08:59:17+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.57", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1627b1d03446904aaa77593f370c5201d2ecc34e", + "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2024-01-24T11:51:34+00:00" + }, + { + "name": "phpstan/phpstan-mockery", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-mockery.git", + "reference": "88ae85931768efd3aaf3cce4cb9cb54c4d157d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-mockery/zipball/88ae85931768efd3aaf3cce4cb9cb54c4d157d03", + "reference": "88ae85931768efd3aaf3cce4cb9cb54c4d157d03", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10" + }, + "require-dev": { + "mockery/mockery": "^1.2.4", + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan Mockery extension", + "support": { + "issues": "https://github.com/phpstan/phpstan-mockery/issues", + "source": "https://github.com/phpstan/phpstan-mockery/tree/1.1.2" + }, + "time": "2024-01-10T13:50:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.11", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "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-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.11" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T15:38:30+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.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe", + "reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "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.9" + }, + "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-01-22T14:35:40+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/http-server-handler", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" + }, + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" + }, + "time": "2023-04-11T06:14:47+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "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.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "rector/rector", + "version": "0.17.13", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "e2003ba7c5bda06d7bb419cf4be8dae5f8672132" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/e2003ba7c5bda06d7bb419cf4be8dae5f8672132", + "reference": "e2003ba7c5bda06d7bb419cf4be8dae5f8672132", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.26" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.17.13" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-08-14T16:33:29+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "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", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+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.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+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.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "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.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T10:55:06+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/43c751b41d74f96cbbd4e07b7aec9675651e2951", + "reference": "43c751b41d74f96cbbd4e07b7aec9675651e2951", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "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": "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.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-04-11T05:39:26+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-24T13:22:09+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "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": "http://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.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+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": "slickdeals/statsd", + "version": "3.2.0", + "source": { + "type": "git", + "url": "git@github.com:Slickdeals/statsd-php.git", + "reference": "96b8a5e0370e09914adc87513f5c49e1a9289b5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/96b8a5e0370e09914adc87513f5c49e1a9289b5a", + "reference": "96b8a5e0370e09914adc87513f5c49e1a9289b5a", + "shasum": "" + }, + "require": { + "php": ">= 7.3 || ^8" + }, + "replace": { + "domnikl/statsd": "<=3.0.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Domnikl\\Statsd\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dominik Liebler", + "email": "liebler.dominik@gmail.com" + } + ], + "description": "a PHP client for statsd", + "homepage": "https://github.com/Slickdeals/statsd-php", + "keywords": [ + "Metrics", + "monitoring", + "statistics", + "statsd", + "udp" + ], + "time": "2023-11-24T08:03:36+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "69b374d982e7139fc904cc61757e7fede1d9c3d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/69b374d982e7139fc904cc61757e7fede1d9c3d8", + "reference": "69b374d982e7139fc904cc61757e7fede1d9c3d8", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Team Swoole", + "email": "team@swoole.com" + } + ], + "description": "IDE help files for Swoole.", + "support": { + "issues": "https://github.com/swoole/ide-helper/issues", + "source": "https://github.com/swoole/ide-helper/tree/5.1.1" + }, + "time": "2023-12-08T17:56:23+00:00" + }, + { + "name": "swow/psr7-plus", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/swow/psr7-plus.git", + "reference": "7acc4924be907d2ff64edee5a2bd116620e56364" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swow/psr7-plus/zipball/7acc4924be907d2ff64edee5a2bd116620e56364", + "reference": "7acc4924be907d2ff64edee5a2bd116620e56364", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Swow\\Psr7\\Message\\": "src/Message/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "twose", + "email": "twosee@php.net" + } + ], + "description": "Modern strong-typed interfaces for Psr7, not only HTTP but also WebSocket", + "keywords": [ + "http", + "psr17", + "psr7", + "swow", + "websocket" + ], + "support": { + "issues": "https://github.com/swow/swow", + "source": "https://github.com/swow/psr7-plus/tree/v1.1.2" + }, + "time": "2023-06-15T09:18:11+00:00" + }, + { + "name": "symfony/console", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/f8587c4cdc5acad67af71c37db34ef03af91e59c", + "reference": "f8587c4cdc5acad67af71c37db34ef03af91e59c", + "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.0.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": "2023-12-10T16:54:46+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/098b62ae81fdd6cbf941f355059f617db28f4f9a", + "reference": "098b62ae81fdd6cbf941f355059f617db28f4f9a", + "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.0.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": "2023-12-27T22:24:19+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7da8ea2362a283771478c5f7729cfcb43a76b8b7", + "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-27T06:33:22+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "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.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-10-31T17:59:56+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/172d807f9ef3fc3fbed8377cc57c20d389269271", + "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "symfony/cache": "<6.3" + }, + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" + }, + "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/v6.4.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": "2023-12-27T22:16:42+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "700ff4096e346f54cb628ea650767c8130f1001f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", + "reference": "700ff4096e346f54cb628ea650767c8130f1001f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-08T10:20:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-28T09:04:16+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/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.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-16T06:22:46+00:00" + }, + { + "name": "symfony/process", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", + "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", + "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.0.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": "2023-12-24T09:15:37+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.4.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": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-05T13:06:06+00:00" + }, + { + "name": "symfony/string", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/cc78f14f91f5e53b42044d0620961c48028ff9f5", + "reference": "cc78f14f91f5e53b42044d0620961c48028ff9f5", + "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/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.0.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": "2023-12-10T16:54:46+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", + "reference": "a2ab2ec1a462e53016de8e8d5e8912bfd62ea681", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^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/v6.4.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": "2023-12-18T09:25:29+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "06450585bf65e978026bda220cdebca3f867fde7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", + "reference": "06450585bf65e978026bda220cdebca3f867fde7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "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.4.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": "2023-12-26T14:02:43+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "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.2" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2023-11-20T00:12:19+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "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": true + }, + "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.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+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/grafana.json b/grafana.json index 64eb41a48..5103b0150 100644 --- a/grafana.json +++ b/grafana.json @@ -397,7 +397,7 @@ { "expr": "sum([[app_name]]_event_num{instance=~'$instance'})", "format": "time_series", - "instant": true, + "instant": false, "intervalFactor": 1, "refId": "A" } @@ -484,7 +484,7 @@ { "expr": "sum([[app_name]]_coroutine_num{instance=~'$instance'})", "format": "time_series", - "instant": true, + "instant": false, "intervalFactor": 1, "refId": "A" } @@ -567,7 +567,7 @@ { "expr": "sum([[app_name]]_connection_num{instance=~'$instance'})", "format": "time_series", - "instant": true, + "instant": false, "intervalFactor": 1, "refId": "A" } @@ -729,7 +729,7 @@ { "expr": "sum([[app_name]]_tasking_num{instance=~'$instance'})", "format": "time_series", - "instant": true, + "instant": false, "intervalFactor": 1, "refId": "A" } @@ -895,7 +895,7 @@ { "expr": "sum([[app_name]]_timer_num{instance=~'$instance'})", "format": "time_series", - "instant": true, + "instant": false, "intervalFactor": 1, "refId": "A" } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 000000000..f25d7d97c --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,11 @@ +parameters: + bootstrapFiles: + - tests/bootstrap.php + paths: + - src + - tests + inferPrivatePropertyTypeFromConstructor: true + treatPhpDocTypesAsCertain: true + reportUnmatchedIgnoredErrors: false + ignoreErrors: + - '#Variable .* in PHPDoc tag @var does not exist#' diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 000000000..bb72997b5 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + + src + + + + + tests + + + diff --git a/publish/metric.php b/publish/metric.php index 34d293f83..ef3d0447f 100644 --- a/publish/metric.php +++ b/publish/metric.php @@ -2,26 +2,31 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ use Hyperf\Metric\Adapter\Prometheus\Constants; +use Hyperf\Metric\Adapter\Prometheus\MetricFactory; use function Hyperf\Support\env; return [ // To disable hyperf/metric temporarily, set default driver to noop. 'default' => env('METRIC_DRIVER', 'prometheus'), - 'use_standalone_process' => env('METRIC_USE_STANDALONE_PROCESS', true), + 'use_standalone_process' => env('METRIC_USE_STANDALONE_PROCESS', false), 'enable_default_metric' => env('METRIC_ENABLE_DEFAULT_METRIC', true), + 'enable_command_metric' => env('METRIC_ENABLE_COMMAND_METRIC', true), 'default_metric_interval' => env('DEFAULT_METRIC_INTERVAL', 5), + // only available when use_standalone_process is true + 'buffer_interval' => env('METRIC_BUFFER_INTERVAL', 5), + 'buffer_size' => env('METRIC_BUFFER_SIZE', 200), 'metric' => [ 'prometheus' => [ - 'driver' => Hyperf\Metric\Adapter\Prometheus\MetricFactory::class, + 'driver' => MetricFactory::class, 'mode' => Constants::SCRAPE_MODE, 'namespace' => env('APP_NAME', 'skeleton'), 'redis_config' => env('PROMETHEUS_REDIS_CONFIG', 'default'), @@ -40,7 +45,7 @@ 'udp_host' => env('STATSD_UDP_HOST', '127.0.0.1'), 'udp_port' => env('STATSD_UDP_PORT', '8125'), 'timeout' => env('STATSD_CONNECTION_TIMEOUT', null), - 'persistent' => env('STATSD_CONNECTION_PERSISTENT', true), + 'persistent' => env('STATSD_CONNECTION_PERSISTENT', false), 'enable_batch' => env('STATSD_ENABLE_BATCH', true), 'push_interval' => env('STATSD_PUSH_INTERVAL', 5), 'sample_rate' => env('STATSD_SAMPLE_RATE', 1.0), diff --git a/src/Adapter/InfluxDB/MetricFactory.php b/src/Adapter/InfluxDB/MetricFactory.php index 3d87049e5..6ee38b3f5 100644 --- a/src/Adapter/InfluxDB/MetricFactory.php +++ b/src/Adapter/InfluxDB/MetricFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\InfluxDB; use Hyperf\Contract\ConfigInterface; @@ -22,7 +23,7 @@ use Hyperf\Metric\Contract\GaugeInterface; use Hyperf\Metric\Contract\HistogramInterface; use Hyperf\Metric\Contract\MetricFactoryInterface; -use Hyperf\Stringable\Str; +use Hyperf\Stringable\StrCache; use InfluxDB\Client; use InfluxDB\Database; use InfluxDB\Database\RetentionPolicy; @@ -119,7 +120,7 @@ protected function createPoint(Sample $sample): Point { return new Point( $sample->getName(), - $sample->getValue(), + (float) $sample->getValue(), $labels = array_combine($sample->getLabelNames(), $sample->getLabelValues()), [], time() @@ -129,6 +130,6 @@ protected function createPoint(Sample $sample): Point private function getNamespace(): string { $name = $this->config->get("metric.metric.{$this->name}.namespace"); - return preg_replace('#[^a-zA-Z0-9:_]#', '_', Str::snake($name)); + return preg_replace('#[^a-zA-Z0-9:_]#', '_', StrCache::snake($name)); } } diff --git a/src/Adapter/NoOp/Counter.php b/src/Adapter/NoOp/Counter.php index 1d4b718b0..768192baf 100644 --- a/src/Adapter/NoOp/Counter.php +++ b/src/Adapter/NoOp/Counter.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\NoOp; use Hyperf\Metric\Contract\CounterInterface; diff --git a/src/Adapter/NoOp/Gauge.php b/src/Adapter/NoOp/Gauge.php index 2eae0be00..23d4ca3ae 100644 --- a/src/Adapter/NoOp/Gauge.php +++ b/src/Adapter/NoOp/Gauge.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\NoOp; use Hyperf\Metric\Contract\GaugeInterface; diff --git a/src/Adapter/NoOp/Histogram.php b/src/Adapter/NoOp/Histogram.php index ac0c3cb6b..93e843895 100644 --- a/src/Adapter/NoOp/Histogram.php +++ b/src/Adapter/NoOp/Histogram.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\NoOp; use Hyperf\Metric\Contract\HistogramInterface; diff --git a/src/Adapter/NoOp/MetricFactory.php b/src/Adapter/NoOp/MetricFactory.php index eec76fe10..f39ee8c97 100644 --- a/src/Adapter/NoOp/MetricFactory.php +++ b/src/Adapter/NoOp/MetricFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\NoOp; use Hyperf\Coordinator\Constants; diff --git a/src/Adapter/Prometheus/Constants.php b/src/Adapter/Prometheus/Constants.php index 72eb4c464..4f6462a97 100644 --- a/src/Adapter/Prometheus/Constants.php +++ b/src/Adapter/Prometheus/Constants.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; class Constants diff --git a/src/Adapter/Prometheus/Counter.php b/src/Adapter/Prometheus/Counter.php index ebe539d41..cfb58b855 100644 --- a/src/Adapter/Prometheus/Counter.php +++ b/src/Adapter/Prometheus/Counter.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use Hyperf\Metric\Contract\CounterInterface; diff --git a/src/Adapter/Prometheus/Gauge.php b/src/Adapter/Prometheus/Gauge.php index 60846aeaf..32ab20287 100644 --- a/src/Adapter/Prometheus/Gauge.php +++ b/src/Adapter/Prometheus/Gauge.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use Hyperf\Metric\Contract\GaugeInterface; diff --git a/src/Adapter/Prometheus/Histogram.php b/src/Adapter/Prometheus/Histogram.php index e38d1e124..cd30fe3b4 100644 --- a/src/Adapter/Prometheus/Histogram.php +++ b/src/Adapter/Prometheus/Histogram.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use Hyperf\Metric\Contract\HistogramInterface; diff --git a/src/Adapter/Prometheus/MetricFactory.php b/src/Adapter/Prometheus/MetricFactory.php index 188c27cc7..4e28f2cc6 100644 --- a/src/Adapter/Prometheus/MetricFactory.php +++ b/src/Adapter/Prometheus/MetricFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use GuzzleHttp\Exception\GuzzleException; @@ -30,6 +31,7 @@ use Hyperf\Metric\Exception\RuntimeException; use Hyperf\Metric\MetricFactoryPicker; use Hyperf\Stringable\Str; +use Hyperf\Stringable\StrCache; use Hyperf\Support\Network; use Prometheus\CollectorRegistry; use Prometheus\Exception\MetricsRegistrationException; @@ -126,6 +128,10 @@ protected function scrapeHandle(): void } } + if (CoordinatorManager::until(Coord::WORKER_EXIT)->isClosing()) { + return; + } + $server = $this->factory->make($host, (int) $port); Coroutine::create(static function () use ($server) { @@ -171,7 +177,7 @@ protected function customHandle(): void private function getNamespace(): string { $name = $this->config->get("metric.metric.{$this->name}.namespace"); - return preg_replace('#[^a-zA-Z0-9:_]#', '_', Str::snake($name)); + return preg_replace('#[^a-zA-Z0-9:_]#', '_', StrCache::snake($name)); } private function getUri(string $address, string $job): string diff --git a/src/Adapter/Prometheus/Redis.php b/src/Adapter/Prometheus/Redis.php index 8d19ddba2..5bdf439f1 100644 --- a/src/Adapter/Prometheus/Redis.php +++ b/src/Adapter/Prometheus/Redis.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use Hyperf\Codec\Json; @@ -22,20 +23,9 @@ class Redis implements Adapter { - /** - * @deprecated since 3.1, use `$metricGatherKeySuffix` instead - */ - public const PROMETHEUS_METRIC_KEYS_SUFFIX = '_METRIC_KEYS'; + private static string $metricGatherKeySuffix = ':metric_keys'; - /** - * @notice TODO: since 3.1, default value will be changed to ':metric_keys' - */ - private static string $metricGatherKeySuffix = '_METRIC_KEYS'; - - /** - * @notice TODO: since 3.1, default value will be changed to 'prometheus:' and should be non static - */ - private static string $prefix = 'PROMETHEUS_'; + private static string $prefix = 'prometheus:'; /** * @param \Redis $redis @@ -63,6 +53,10 @@ public function collect(): array ); } + public function updateSummary(array $data): void + { + } + /** * @throws RedisException */ @@ -350,12 +344,7 @@ protected function collectSamples(string $metricType): array protected function toMetricKey(array $data): string { - // TODO: This is a hack, we should remove it since v3.1. - if (! str_ends_with(self::$prefix, ':')) { - $prefix = self::$prefix . ':'; - } - - return ($prefix ?? self::$prefix) . implode(':', [$data['type'] ?? '', $data['name'] ?? '']) . $this->getRedisTag($data['type'] ?? ''); + return self::$prefix . implode(':', [$data['type'] ?? '', $data['name'] ?? '']) . $this->getRedisTag($data['type'] ?? ''); } protected function getMetricGatherKey(string $metricType): string diff --git a/src/Adapter/Prometheus/RedisStorageFactory.php b/src/Adapter/Prometheus/RedisStorageFactory.php index ddc1188a6..e76024c55 100644 --- a/src/Adapter/Prometheus/RedisStorageFactory.php +++ b/src/Adapter/Prometheus/RedisStorageFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\Prometheus; use Hyperf\Contract\ConfigInterface; @@ -29,8 +30,7 @@ public function __invoke(ContainerInterface $container): Redis $redisFactory = $container->get(RedisFactory::class); Redis::setPrefix($config->get('metric.metric.prometheus.redis_prefix', $config->get('app_name', 'skeleton'))); - // TODO: since 3.1, default value will be changed to ':metric_keys' - Redis::setMetricGatherKeySuffix($config->get('metric.metric.prometheus.redis_gather_key_suffix', '_METRIC_KEYS')); + Redis::setMetricGatherKeySuffix($config->get('metric.metric.prometheus.redis_gather_key_suffix', ':metric_keys')); return new Redis($redisFactory->get($config->get('metric.metric.prometheus.redis_config', 'default'))); } diff --git a/src/Adapter/RemoteProxy/Counter.php b/src/Adapter/RemoteProxy/Counter.php index fad0450d8..eec60140c 100644 --- a/src/Adapter/RemoteProxy/Counter.php +++ b/src/Adapter/RemoteProxy/Counter.php @@ -2,22 +2,22 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\RemoteProxy; +use Hyperf\Context\ApplicationContext; use Hyperf\Metric\Contract\CounterInterface; -use Hyperf\Process\ProcessCollector; +use Hyperf\Metric\Contract\MetricCollectorInterface; class Counter implements CounterInterface { - protected const TARGET_PROCESS_NAME = 'metric'; - /** * @var string[] */ @@ -38,7 +38,9 @@ public function with(string ...$labelValues): static public function add(int $delta): void { $this->delta = $delta; - $process = ProcessCollector::get(static::TARGET_PROCESS_NAME)[0]; - $process->write(serialize($this)); + + ApplicationContext::getContainer() + ->get(MetricCollectorInterface::class) + ->add($this); } } diff --git a/src/Adapter/RemoteProxy/Gauge.php b/src/Adapter/RemoteProxy/Gauge.php index f0501ff6a..f3538db18 100644 --- a/src/Adapter/RemoteProxy/Gauge.php +++ b/src/Adapter/RemoteProxy/Gauge.php @@ -2,22 +2,22 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\RemoteProxy; +use Hyperf\Context\ApplicationContext; use Hyperf\Metric\Contract\GaugeInterface; -use Hyperf\Process\ProcessCollector; +use Hyperf\Metric\Contract\MetricCollectorInterface; class Gauge implements GaugeInterface { - protected const TARGET_PROCESS_NAME = 'metric'; - /** * @var string[] */ @@ -41,15 +41,19 @@ public function set(float $value): void { $this->value = $value; $this->delta = null; - $process = ProcessCollector::get(static::TARGET_PROCESS_NAME)[0]; - $process->write(serialize($this)); + + ApplicationContext::getContainer() + ->get(MetricCollectorInterface::class) + ->add($this); } public function add(float $delta): void { $this->delta = $delta; $this->value = null; - $process = ProcessCollector::get(static::TARGET_PROCESS_NAME)[0]; - $process->write(serialize($this)); + + ApplicationContext::getContainer() + ->get(MetricCollectorInterface::class) + ->add($this); } } diff --git a/src/Adapter/RemoteProxy/Histogram.php b/src/Adapter/RemoteProxy/Histogram.php index 119b9397b..6f6704751 100644 --- a/src/Adapter/RemoteProxy/Histogram.php +++ b/src/Adapter/RemoteProxy/Histogram.php @@ -2,22 +2,22 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\RemoteProxy; +use Hyperf\Context\ApplicationContext; use Hyperf\Metric\Contract\HistogramInterface; -use Hyperf\Process\ProcessCollector; +use Hyperf\Metric\Contract\MetricCollectorInterface; class Histogram implements HistogramInterface { - protected const TARGET_PROCESS_NAME = 'metric'; - /** * @var string[] */ @@ -38,7 +38,9 @@ public function with(string ...$labelValues): static public function put(float $sample): void { $this->sample = $sample; - $process = ProcessCollector::get(static::TARGET_PROCESS_NAME)[0]; - $process->write(serialize($this)); + + ApplicationContext::getContainer() + ->get(MetricCollectorInterface::class) + ->add($this); } } diff --git a/src/Adapter/RemoteProxy/MetricCollector.php b/src/Adapter/RemoteProxy/MetricCollector.php new file mode 100644 index 000000000..64a383455 --- /dev/null +++ b/src/Adapter/RemoteProxy/MetricCollector.php @@ -0,0 +1,50 @@ +buffer[] = $data; + + if (count($this->buffer) >= $this->bufferSize) { + $this->flush(); + } + } + + public function flush(): void + { + $process = ProcessCollector::get(static::TARGET_PROCESS_NAME)[0]; + $buffer = $this->buffer; + $this->buffer = []; + $process->write(serialize($buffer)); + } + + public function getBuffer(): array + { + return $this->buffer; + } +} diff --git a/src/Adapter/RemoteProxy/MetricCollectorFactory.php b/src/Adapter/RemoteProxy/MetricCollectorFactory.php new file mode 100644 index 000000000..387004632 --- /dev/null +++ b/src/Adapter/RemoteProxy/MetricCollectorFactory.php @@ -0,0 +1,35 @@ +get(ConfigInterface::class); + + return new MetricCollector( + (int) $config->get('metric.buffer_size', 200) + ); + } +} diff --git a/src/Adapter/RemoteProxy/MetricFactory.php b/src/Adapter/RemoteProxy/MetricFactory.php index 7a7e59445..3304c5c44 100644 --- a/src/Adapter/RemoteProxy/MetricFactory.php +++ b/src/Adapter/RemoteProxy/MetricFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\RemoteProxy; use Hyperf\Metric\Contract\CounterInterface; diff --git a/src/Adapter/StatsD/Connection.php b/src/Adapter/StatsD/Connection.php new file mode 100644 index 000000000..63ab19d26 --- /dev/null +++ b/src/Adapter/StatsD/Connection.php @@ -0,0 +1,33 @@ +host; + $socket = fsockopen($url, $this->port, $errorNumber, $errorMessage); + fwrite($socket, $message); + fclose($socket); + $socket = null; + } +} diff --git a/src/Adapter/StatsD/Counter.php b/src/Adapter/StatsD/Counter.php index e92de713e..34558fed2 100644 --- a/src/Adapter/StatsD/Counter.php +++ b/src/Adapter/StatsD/Counter.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\StatsD; use Domnikl\Statsd\Client; @@ -34,7 +35,7 @@ public function __construct( public function with(string ...$labelValues): static { - $this->labelValues = $labelValues; + $this->labelValues = array_merge($this->labelValues, $labelValues); return $this; } diff --git a/src/Adapter/StatsD/Gauge.php b/src/Adapter/StatsD/Gauge.php index f277661c1..ab8d4ba17 100644 --- a/src/Adapter/StatsD/Gauge.php +++ b/src/Adapter/StatsD/Gauge.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\StatsD; use Domnikl\Statsd\Client; @@ -34,7 +35,7 @@ public function __construct( public function with(string ...$labelValues): static { - $this->labelValues = $labelValues; + $this->labelValues = array_merge($this->labelValues, $labelValues); return $this; } diff --git a/src/Adapter/StatsD/Histogram.php b/src/Adapter/StatsD/Histogram.php index 8c2884f34..43e4d22a8 100644 --- a/src/Adapter/StatsD/Histogram.php +++ b/src/Adapter/StatsD/Histogram.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\StatsD; use Domnikl\Statsd\Client; @@ -34,7 +35,7 @@ public function __construct( public function with(string ...$labelValues): static { - $this->labelValues = $labelValues; + $this->labelValues = array_merge($this->labelValues, $labelValues); return $this; } diff --git a/src/Adapter/StatsD/MetricFactory.php b/src/Adapter/StatsD/MetricFactory.php index c6bd19a1d..97b578801 100644 --- a/src/Adapter/StatsD/MetricFactory.php +++ b/src/Adapter/StatsD/MetricFactory.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Adapter\StatsD; use Domnikl\Statsd\Client; @@ -21,6 +22,7 @@ use Hyperf\Metric\Contract\HistogramInterface; use Hyperf\Metric\Contract\MetricFactoryInterface; +use function Hyperf\Support\env; use function Hyperf\Support\make; class MetricFactory implements MetricFactoryInterface @@ -38,32 +40,32 @@ public function __construct(private ConfigInterface $config) public function makeCounter(string $name, ?array $labelNames = []): CounterInterface { - return new Counter( + return (new Counter( $this->client, $name, $this->getSampleRate(), - $labelNames - ); + array_merge(['service.name', 'host.name'], $labelNames), + ))->with($this->getNamespace(), $this->getHostname()); } public function makeGauge(string $name, ?array $labelNames = []): GaugeInterface { - return new Gauge( + return (new Gauge( $this->client, $name, $this->getSampleRate(), - $labelNames - ); + array_merge(['service.name', 'host.name'], $labelNames), + ))->with($this->getNamespace(), $this->getHostname()); } public function makeHistogram(string $name, ?array $labelNames = []): HistogramInterface { - return new Histogram( + return (new Histogram( $this->client, $name, $this->getSampleRate(), - $labelNames - ); + array_merge(['service.name', 'host.name'], $labelNames), + ))->with($this->getNamespace(), $this->getHostname()); } public function handle(): void @@ -92,7 +94,7 @@ protected function getConnection(): Connection $host = $this->config->get("metric.metric.{$name}.udp_host"); $port = $this->config->get("metric.metric.{$name}.udp_port"); $timeout = $this->config->get("metric.metric.{$name}.timeout"); - $persistent = $this->config->get("metric.metric.{$name}.persistent", true); + $persistent = $this->config->get("metric.metric.{$name}.persistent", false); return make(Connection::class, [ 'host' => $host, 'port' => (int) $port, @@ -112,4 +114,9 @@ protected function getSampleRate(): float $name = $this->config->get('metric.default'); return $this->config->get("metric.metric.{$name}.sample_rate", 1.0); } + + protected function getHostname(): string + { + return $this->config->get('hostname', env('HOSTNAME', env('APP_NAME'))); + } } diff --git a/src/Annotation/Counter.php b/src/Annotation/Counter.php index 4ef0d8f9c..cbe322074 100644 --- a/src/Annotation/Counter.php +++ b/src/Annotation/Counter.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Annotation; use Attribute; diff --git a/src/Annotation/Histogram.php b/src/Annotation/Histogram.php index e88ed9241..014b816b1 100644 --- a/src/Annotation/Histogram.php +++ b/src/Annotation/Histogram.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Annotation; use Attribute; diff --git a/src/Aspect/CounterAnnotationAspect.php b/src/Aspect/CounterAnnotationAspect.php index 1f12f3bb4..79ea6a25a 100644 --- a/src/Aspect/CounterAnnotationAspect.php +++ b/src/Aspect/CounterAnnotationAspect.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Aspect; use Hyperf\Di\Aop\AbstractAspect; diff --git a/src/Aspect/HistogramAnnotationAspect.php b/src/Aspect/HistogramAnnotationAspect.php index 9f41ba5fc..a8c971778 100644 --- a/src/Aspect/HistogramAnnotationAspect.php +++ b/src/Aspect/HistogramAnnotationAspect.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Aspect; use Hyperf\Di\Aop\AbstractAspect; diff --git a/src/Aspect/HttpClientMetricAspect.php b/src/Aspect/HttpClientMetricAspect.php new file mode 100644 index 000000000..3995b8f76 --- /dev/null +++ b/src/Aspect/HttpClientMetricAspect.php @@ -0,0 +1,112 @@ +arguments['keys']['options']; + + if (isset($options['no_aspect']) && $options['no_aspect'] === true) { + return $proceedingJoinPoint->process(); + } + + /** @var Client $instance */ + /** @var Uri $base_uri */ + $instance = $proceedingJoinPoint->getInstance(); + $base_uri = $instance->getConfig('base_uri'); + + $arguments = $proceedingJoinPoint->arguments; + $method = strtoupper($arguments['keys']['method'] ?? ''); + $uri = $arguments['keys']['uri'] ?? ''; + $host = $base_uri === null ? (parse_url($uri, PHP_URL_HOST) ?? '') : $base_uri->getHost(); + $uriMask = $this->getUriMask($instance); + $uri = $this->shouldIgnoreUri($instance) + ? '' + : SupportUri::sanitize(parse_url($uri, PHP_URL_PATH) ?? '/', $uriMask); + $labels = [ + 'uri' => $uri, + 'host' => $host, + 'method' => $method, + 'http_status_code' => '200', + 'message' => 'success', + ]; + + $timer = new Timer('http_client_requests', $labels); + + /** @var PromiseInterface $result */ + $result = $proceedingJoinPoint->process(); + + $result->then( + $this->onFullFilled($timer, $labels), + $this->onRejected($timer, $labels) + ); + + return $result; + } + + private function onFullFilled(Timer $timer, array $labels): callable + { + return function (ResponseInterface $response) use ($timer, $labels) { + $labels['http_status_code'] = (string) $response->getStatusCode(); + $timer->end($labels); + }; + } + + private function onRejected(Timer $timer, array $labels): callable + { + return function (TransferException $exception) use ($timer, $labels) { + $labels['http_status_code'] = ''; + $labels['message'] = 'connect_error'; + + if ($exception instanceof RequestException) { + $labels['http_status_code'] = (string) $exception->getResponse()->getStatusCode(); + $labels['message'] = 'request_error'; + } + + $timer->end($labels); + + return Create::rejectionFor($exception); + }; + } + + private function shouldIgnoreUri(Client $instance): bool + { + return $instance->getConfig('ignore_uri') === true; + } + + public function getUriMask(Client $instance): array + { + $uriMask = $instance->getConfig('uri_mask'); + + if (is_array($uriMask) === false) { + return []; + } + + return $uriMask; + } +} diff --git a/src/Aspect/MongoCollectionMetricAspect.php b/src/Aspect/MongoCollectionMetricAspect.php new file mode 100644 index 000000000..5aec21939 --- /dev/null +++ b/src/Aspect/MongoCollectionMetricAspect.php @@ -0,0 +1,60 @@ +methodName, $this->ignoredMethods)) { + return $proceedingJoinPoint->process(); + } + + $collectionName = $this->getCollectionName($proceedingJoinPoint); + $method = $proceedingJoinPoint->methodName; + + $timer = new Timer('database_queries', [ + 'system' => 'mongodb', + 'operation' => sprintf('MongoDB %s %s', $collectionName, $method), + ]); + + $result = $proceedingJoinPoint->process(); + $timer->end(); + + return $result; + } + + private function getCollectionName(ProceedingJoinPoint $proceedingJoinPoint): string + { + $collection = $proceedingJoinPoint->getInstance(); + + $property = new ReflectionProperty('Hyperf\GoTask\MongoClient\Collection', 'collection'); + $property->setAccessible(true); + + return $property->getValue($collection); + } +} diff --git a/src/Aspect/RedisMetricAspect.php b/src/Aspect/RedisMetricAspect.php new file mode 100644 index 000000000..fb5b20975 --- /dev/null +++ b/src/Aspect/RedisMetricAspect.php @@ -0,0 +1,37 @@ +arguments['keys']; + + $timer = new Timer('database_queries', [ + 'system' => 'redis', + 'operation' => sprintf('Redis %s', $arguments['name']), + ]); + + $result = $proceedingJoinPoint->process(); + $timer->end(); + + return $result; + } +} diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 27ef03f74..76ddfc666 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -2,26 +2,37 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric; use Domnikl\Statsd\Connection; -use Domnikl\Statsd\Connection\UdpSocket; +use Hyperf\Metric\Adapter\StatsD\Connection as StatsDConnection; use Hyperf\Metric\Aspect\CounterAnnotationAspect; use Hyperf\Metric\Aspect\HistogramAnnotationAspect; +use Hyperf\Metric\Aspect\HttpClientMetricAspect; +use Hyperf\Metric\Aspect\MongoCollectionMetricAspect; +use Hyperf\Metric\Aspect\RedisMetricAspect; use Hyperf\Metric\Contract\MetricFactoryInterface; +use Hyperf\Metric\Contract\SqlSanitizerInterface; +use Hyperf\Metric\Listener\DbQueryExecutedMetricListener; +use Hyperf\Metric\Adapter\RemoteProxy\MetricCollectorFactory; +use Hyperf\Metric\Contract\MetricCollectorInterface; +use Hyperf\Metric\Listener\MetricBufferWatcher; use Hyperf\Metric\Listener\OnBeforeHandle; use Hyperf\Metric\Listener\OnCoroutineServerStart; use Hyperf\Metric\Listener\OnMetricFactoryReady; use Hyperf\Metric\Listener\OnPipeMessage; use Hyperf\Metric\Listener\OnWorkerStart; +use Hyperf\Metric\Middleware\MetricMiddleware; use Hyperf\Metric\Process\MetricProcess; +use Hyperf\Metric\Support\SqlSanitizer; use InfluxDB\Driver\DriverInterface; use InfluxDB\Driver\Guzzle; use Prometheus\Storage\Adapter; @@ -35,12 +46,17 @@ public function __invoke(): array 'dependencies' => [ MetricFactoryInterface::class => MetricFactoryPicker::class, Adapter::class => InMemory::class, - Connection::class => UdpSocket::class, + Connection::class => StatsDConnection::class, DriverInterface::class => Guzzle::class, + SqlSanitizerInterface::class => SqlSanitizer::class, + MetricCollectorInterface::class => MetricCollectorFactory::class, ], 'aspects' => [ CounterAnnotationAspect::class, HistogramAnnotationAspect::class, + HttpClientMetricAspect::class, + MongoCollectionMetricAspect::class, + RedisMetricAspect::class, ], 'publish' => [ [ @@ -51,11 +67,16 @@ public function __invoke(): array ], ], 'listeners' => [ + DbQueryExecutedMetricListener::class, OnPipeMessage::class, OnMetricFactoryReady::class, OnBeforeHandle::class, OnWorkerStart::class, OnCoroutineServerStart::class, + MetricBufferWatcher::class, + ], + 'middlewares' => [ + MetricMiddleware::class, ], 'processes' => [ MetricProcess::class, diff --git a/src/Contract/CounterInterface.php b/src/Contract/CounterInterface.php index a625b70dc..13e999213 100644 --- a/src/Contract/CounterInterface.php +++ b/src/Contract/CounterInterface.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Contract; /** diff --git a/src/Contract/GaugeInterface.php b/src/Contract/GaugeInterface.php index 204c121b6..4f80d0883 100644 --- a/src/Contract/GaugeInterface.php +++ b/src/Contract/GaugeInterface.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Contract; /** diff --git a/src/Contract/HistogramInterface.php b/src/Contract/HistogramInterface.php index 1f8bd5d58..068eb6776 100644 --- a/src/Contract/HistogramInterface.php +++ b/src/Contract/HistogramInterface.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Contract; /** diff --git a/src/Contract/MetricCollectorInterface.php b/src/Contract/MetricCollectorInterface.php new file mode 100644 index 000000000..20b992cab --- /dev/null +++ b/src/Contract/MetricCollectorInterface.php @@ -0,0 +1,20 @@ +container->get(ConfigInterface::class); diff --git a/src/Listener/DbQueryExecutedMetricListener.php b/src/Listener/DbQueryExecutedMetricListener.php new file mode 100644 index 000000000..b25368790 --- /dev/null +++ b/src/Listener/DbQueryExecutedMetricListener.php @@ -0,0 +1,49 @@ + 'mysql', + 'operation' => $this->sqlSanitizer->sanitize($event->sql), + ]; + + $histogram = make(MetricFactoryInterface::class) + ->makeHistogram('database_queries', array_keys($labels)) + ->with(...array_values($labels)); + + $histogram->put($event->time); + } +} diff --git a/src/Listener/HttpPoolWatcher.php b/src/Listener/HttpPoolWatcher.php new file mode 100644 index 000000000..16a6c4fa2 --- /dev/null +++ b/src/Listener/HttpPoolWatcher.php @@ -0,0 +1,73 @@ +timer = new Timer(); + } + + public function listen(): array + { + return [ + BeforeWorkerStart::class, + MainCoroutineServerStart::class, + ]; + } + + public function process(object $event): void + { + /** @var PoolFactory $factory */ + $factory = $this->container->get(PoolFactory::class); + $worker = (string) ($event->workerId ?? 0); + + $config = $this->container->get(ConfigInterface::class); + + $timer_interval = $config->get('metric.default_metric_interval', 5); + + $this->timer->tick($timer_interval, function () use ($factory, $worker) { + foreach ($factory->getPoolNames() as $name) { + if (strpos($name, self::GUZZLE_PREFIX) !== 0) { + continue; + } + + $pool = $factory->get($name, function () {}); + + $labels = [ + 'worker' => $worker, + 'pool' => implode('.', array_slice(explode('.', (string) $name), 2, -2)), + ]; + + Metric::gauge('http_connections_in_use', (float) $pool->getCurrentConnections(), $labels); + Metric::gauge('http_connections_in_waiting', (float) $pool->getConnectionsInChannel(), $labels); + Metric::gauge('http_max_connections', (float) $pool->getOption()->getMaxConnections(), $labels); + } + }); + } +} diff --git a/src/Listener/MetricBufferWatcher.php b/src/Listener/MetricBufferWatcher.php new file mode 100644 index 000000000..957c7ab50 --- /dev/null +++ b/src/Listener/MetricBufferWatcher.php @@ -0,0 +1,81 @@ +config = $container->get(ConfigInterface::class); + $this->collector = $container->get(MetricCollectorInterface::class); + $this->timer = new Timer(); + } + + /** + * @return string[] returns the events that you want to listen + */ + public function listen(): array + { + return [ + BeforeWorkerStart::class, + ]; + } + + /** + * Handle the Event when the event is triggered, all listeners will + * complete before the event is returned to the EventDispatcher. + */ + public function process(object $event): void + { + if ($event->workerId === null) { + return; + } + + /* + * Only start buffer watcher in standalone process mode + */ + if (! $this->config->get('metric.use_standalone_process', true)) { + return; + } + + $timerInterval = $this->config->get('metric.buffer_interval', 5); + $timerId = $this->timer->tick($timerInterval, function () { + $this->collector->flush(); + }); + // Clean up timer on worker exit; + Coroutine::create(function () use ($timerId) { + CoordinatorManager::until(Constants::WORKER_EXIT)->yield(); + $this->timer->clear($timerId); + }); + } +} diff --git a/src/Listener/OnBeforeHandle.php b/src/Listener/OnBeforeHandle.php index 0fa0c3201..8d7ba5c5f 100644 --- a/src/Listener/OnBeforeHandle.php +++ b/src/Listener/OnBeforeHandle.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Command\Event\AfterExecute; @@ -63,6 +64,10 @@ public function process(object $event): void return; } + if (! $this->config->get('metric.enable_command_metric', true)) { + return; + } + MetricFactoryPicker::$isCommand = true; if ($this->config->get('metric.use_standalone_process', true)) { diff --git a/src/Listener/OnCoroutineServerStart.php b/src/Listener/OnCoroutineServerStart.php index 5294dd15b..65b4f6e02 100644 --- a/src/Listener/OnCoroutineServerStart.php +++ b/src/Listener/OnCoroutineServerStart.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Contract\ConfigInterface; diff --git a/src/Listener/OnMetricFactoryReady.php b/src/Listener/OnMetricFactoryReady.php index ffc81167e..9de0a8c3b 100644 --- a/src/Listener/OnMetricFactoryReady.php +++ b/src/Listener/OnMetricFactoryReady.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Contract\ConfigInterface; diff --git a/src/Listener/OnPipeMessage.php b/src/Listener/OnPipeMessage.php index 933e27608..f0ddaedc6 100644 --- a/src/Listener/OnPipeMessage.php +++ b/src/Listener/OnPipeMessage.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Coroutine\Coroutine; @@ -18,14 +19,19 @@ use Hyperf\Metric\Adapter\RemoteProxy\Histogram; use Hyperf\Metric\Contract\MetricFactoryInterface; use Hyperf\Process\Event\PipeMessage; - -use function Hyperf\Support\make; +use Psr\Container\ContainerInterface; /** * Receives messages in metric process. */ class OnPipeMessage implements ListenerInterface { + protected MetricFactoryInterface $factory; + + public function __construct(protected ContainerInterface $container) + { + } + /** * @return string[] returns the events that you want to listen */ @@ -42,32 +48,41 @@ public function listen(): array */ public function process(object $event): void { - Coroutine::create(function () use ($event) { - if ($event instanceof PipeMessage) { - $factory = make(MetricFactoryInterface::class); - $inner = $event->data; - switch (true) { - case $inner instanceof Counter: - $counter = $factory->makeCounter($inner->name, $inner->labelNames); - $counter->with(...$inner->labelValues)->add($inner->delta); - break; - case $inner instanceof Gauge: - $gauge = $factory->makeGauge($inner->name, $inner->labelNames); - if (isset($inner->value)) { - $gauge->with(...$inner->labelValues)->set($inner->value); - } else { - $gauge->with(...$inner->labelValues)->add($inner->delta); - } - break; - case $inner instanceof Histogram: - $histogram = $factory->makeHistogram($inner->name, $inner->labelNames); - $histogram->with(...$inner->labelValues)->put($inner->sample); - break; - default: - // Nothing to do - break; + if (! $event instanceof PipeMessage) { + return; + } + + $this->factory = $this->container->get(MetricFactoryInterface::class); + $inner = ! is_array($event->data) ? [$event->data] : $event->data; + foreach ($inner as $data) { + Coroutine::create(function () use ($data) { + $this->processData($data); + }); + } + } + + protected function processData(object $data): void + { + switch (true) { + case $data instanceof Counter: + $counter = $this->factory->makeCounter($data->name, $data->labelNames); + $counter->with(...$data->labelValues)->add($data->delta); + break; + case $data instanceof Gauge: + $gauge = $this->factory->makeGauge($data->name, $data->labelNames); + if (isset($data->value)) { + $gauge->with(...$data->labelValues)->set($data->value); + } else { + $gauge->with(...$data->labelValues)->add($data->delta); } - } - }); + break; + case $data instanceof Histogram: + $histogram = $this->factory->makeHistogram($data->name, $data->labelNames); + $histogram->with(...$data->labelValues)->put($data->sample); + break; + default: + // Nothing to do + break; + } } } diff --git a/src/Listener/OnWorkerStart.php b/src/Listener/OnWorkerStart.php index 0cdb4dc4d..473c4277d 100644 --- a/src/Listener/OnWorkerStart.php +++ b/src/Listener/OnWorkerStart.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Contract\ConfigInterface; @@ -23,6 +24,7 @@ use Hyperf\Metric\MetricSetter; use Psr\Container\ContainerInterface; use Psr\EventDispatcher\EventDispatcherInterface; +use Swoole\Server; use function gc_status; use function getrusage; @@ -124,7 +126,7 @@ public function process(object $event): void $timerInterval = $this->config->get('metric.default_metric_interval', 5); $timerId = $this->timer->tick($timerInterval, function () use ($metrics) { - $server = $this->container->get(\Swoole\Server::class); + $server = $this->container->get(Server::class); $serverStats = $server->stats(); $this->trySet('gc_', $metrics, gc_status()); $this->trySet('', $metrics, getrusage()); diff --git a/src/Listener/PoolWatcher.php b/src/Listener/PoolWatcher.php index 936cc3aae..0044ee840 100644 --- a/src/Listener/PoolWatcher.php +++ b/src/Listener/PoolWatcher.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Contract\ConfigInterface; diff --git a/src/Listener/QueueWatcher.php b/src/Listener/QueueWatcher.php index 592d08dc2..9e886a491 100644 --- a/src/Listener/QueueWatcher.php +++ b/src/Listener/QueueWatcher.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\AsyncQueue\Driver\DriverFactory; diff --git a/src/Listener/RedisPoolWatcher.php b/src/Listener/RedisPoolWatcher.php index fc4817f3c..e3f3dd54f 100644 --- a/src/Listener/RedisPoolWatcher.php +++ b/src/Listener/RedisPoolWatcher.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Listener; use Hyperf\Contract\ConfigInterface; @@ -27,9 +28,6 @@ public function getPrefix() return 'redis'; } - /** - * {@inheritdoc} - */ public function process(object $event): void { $config = $this->container->get(ConfigInterface::class); diff --git a/src/Metric.php b/src/Metric.php index e8cb0ac06..8b54a8bcc 100644 --- a/src/Metric.php +++ b/src/Metric.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric; use Hyperf\Metric\Contract\MetricFactoryInterface; @@ -55,6 +56,7 @@ public static function put(string $name, float $sample, ?array $labels = []) public static function time(string $name, callable $func, ?array $args = [], ?array $labels = []) { + // Must be keep the variable $timer alive, otherwise the destructor will be called right now. $timer = new Timer($name, $labels); return $func(...$args); } diff --git a/src/MetricFactoryPicker.php b/src/MetricFactoryPicker.php index ff7fdae4d..da98fd310 100644 --- a/src/MetricFactoryPicker.php +++ b/src/MetricFactoryPicker.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric; use Hyperf\Contract\ConfigInterface; diff --git a/src/MetricSetter.php b/src/MetricSetter.php index f2d6db0d0..b8e79e7e4 100644 --- a/src/MetricSetter.php +++ b/src/MetricSetter.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric; use Hyperf\Coroutine\Coroutine; diff --git a/src/Middleware/MetricMiddleware.php b/src/Middleware/MetricMiddleware.php index 5dc6b3787..aa6461671 100644 --- a/src/Middleware/MetricMiddleware.php +++ b/src/Middleware/MetricMiddleware.php @@ -2,18 +2,21 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Middleware; +use Hyperf\Contract\ConfigInterface; use Hyperf\HttpMessage\Exception\HttpException; use Hyperf\HttpServer\Router\Dispatched; -use Hyperf\Metric\CoroutineServerStats; +use Hyperf\Metric\Metric; +use Hyperf\Metric\Support\Uri; use Hyperf\Metric\Timer; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -23,8 +26,12 @@ class MetricMiddleware implements MiddlewareInterface { - public function __construct(protected CoroutineServerStats $stats) - { + protected array $config; + + public function __construct( + ConfigInterface $config, + ) { + $this->config = $config->get('metric'); } /** @@ -35,44 +42,59 @@ public function __construct(protected CoroutineServerStats $stats) */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { + if (! empty($this->config['ignore_path']) && preg_match($this->config['ignore_path'], $request->getUri()->getPath())) { + return $handler->handle($request); + } + $labels = [ - 'request_status' => '500', // default to 500 in case uncaught exception occur + 'request_status' => '500', 'request_path' => $this->getPath($request), 'request_method' => $request->getMethod(), ]; - $timer = new Timer('http_requests', $labels); - ++$this->stats->accept_count; - ++$this->stats->request_count; - ++$this->stats->connection_num; + $timer = new Timer('http_requests', $labels); try { $response = $handler->handle($request); $labels['request_status'] = (string) $response->getStatusCode(); + $timer->end($labels); + + return $response; + } catch (HttpException $httpException) { + + // HttpExceptions are valid HTTP responses, not internal errors + $labels['request_status'] = (string) $httpException->getStatusCode(); + $timer->end($labels); + + throw $httpException; } catch (Throwable $exception) { - if ($exception instanceof HttpException) { - $labels['request_status'] = (string) $exception->getStatusCode(); - } - throw $exception; - } finally { + $this->countException($request, $exception); $timer->end($labels); - ++$this->stats->close_count; - ++$this->stats->response_count; - --$this->stats->connection_num; - } - return $response; + throw $exception; + } } protected function getPath(ServerRequestInterface $request): string { $dispatched = $request->getAttribute(Dispatched::class); if (! $dispatched) { - return $request->getUri()->getPath(); + return Uri::sanitize($request->getUri()->getPath()); } if (! $dispatched->handler) { return 'not_found'; } return $dispatched->handler->route; } + + protected function countException(ServerRequestInterface $request, Throwable $exception): void + { + $labels = [ + 'request_path' => $this->getPath($request), + 'request_method' => $request->getMethod(), + 'class' => $exception::class, + ]; + + Metric::count('exception_count', 1, $labels); + } } diff --git a/src/Process/MetricProcess.php b/src/Process/MetricProcess.php index 266987e08..d077a67d6 100644 --- a/src/Process/MetricProcess.php +++ b/src/Process/MetricProcess.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric\Process; use Hyperf\Contract\ConfigInterface; diff --git a/src/Support/SqlSanitizer.php b/src/Support/SqlSanitizer.php new file mode 100644 index 000000000..93de00033 --- /dev/null +++ b/src/Support/SqlSanitizer.php @@ -0,0 +1,31 @@ +', + '/', + '/', + '/', + '/', + '/', + '/', + '/', + '/', + '/', + ], + ), + '/' . ltrim($uri, '/'), + ); + } +} diff --git a/src/Timer.php b/src/Timer.php index 4600b4a4d..7667102c1 100644 --- a/src/Timer.php +++ b/src/Timer.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace Hyperf\Metric; use Hyperf\Metric\Contract\MetricFactoryInterface; diff --git a/tests/Adapter/Prometheus/RedisStorageFactoryTest.php b/tests/Adapter/Prometheus/RedisStorageFactoryTest.php index 9da13b90d..1ea8014ea 100644 --- a/tests/Adapter/Prometheus/RedisStorageFactoryTest.php +++ b/tests/Adapter/Prometheus/RedisStorageFactoryTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Adapter\Prometheus; use Hyperf\Config\Config; @@ -18,6 +19,7 @@ use Hyperf\Redis\RedisFactory; use Hyperf\Redis\RedisProxy; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use ReflectionProperty; @@ -26,6 +28,7 @@ * @internal * @coversNothing */ +#[CoversNothing] class RedisStorageFactoryTest extends TestCase { protected string $prePrefix; @@ -37,10 +40,7 @@ protected function setUp(): void parent::setUp(); $prefixProperty = new ReflectionProperty(Redis::class, 'prefix'); - $prefixProperty->setAccessible(true); - $metricGatherKeySuffix = new ReflectionProperty(Redis::class, 'metricGatherKeySuffix'); - $metricGatherKeySuffix->setAccessible(true); $this->prePrefix = $prefixProperty->getDefaultValue(); $this->preMetricGatherKeySuffix = $metricGatherKeySuffix->getDefaultValue(); @@ -69,14 +69,12 @@ public function testEmptyMetricRedisConfig() $redis = $factory($container); $prefixProperty = new ReflectionProperty(Redis::class, 'prefix'); - $prefixProperty->setAccessible(true); $metricGatherKeySuffixProperty = new ReflectionProperty(Redis::class, 'metricGatherKeySuffix'); - $metricGatherKeySuffixProperty->setAccessible(true); self::assertInstanceOf(Redis::class, $redis); self::assertEquals('skeleton', $prefixProperty->getValue($redis)); - self::assertEquals('_METRIC_KEYS', $metricGatherKeySuffixProperty->getValue($redis)); + self::assertEquals(':metric_keys', $metricGatherKeySuffixProperty->getValue($redis)); } public function testNewConfig() @@ -102,13 +100,42 @@ public function testNewConfig() $redis = $factory($container); $prefixProperty = new ReflectionProperty(Redis::class, 'prefix'); - $prefixProperty->setAccessible(true); $metricGatherKeySuffixProperty = new ReflectionProperty(Redis::class, 'metricGatherKeySuffix'); - $metricGatherKeySuffixProperty->setAccessible(true); self::assertInstanceOf(Redis::class, $redis); self::assertEquals('prometheus:', $prefixProperty->getValue($redis)); self::assertEquals(':metric_keys', $metricGatherKeySuffixProperty->getValue($redis)); } + + public function testCustomConfig() + { + $redisFactory = Mockery::mock(RedisFactory::class); + $redisFactory->shouldReceive('get')->with('custom')->andReturn(Mockery::mock(RedisProxy::class)); + + $container = Mockery::mock(ContainerInterface::class); + $container->shouldReceive('get')->with(ConfigInterface::class)->andReturn(new Config([ + 'metric' => [ + 'metric' => [ + 'prometheus' => [ + 'redis_config' => 'custom', + 'redis_prefix' => 'custom:', + 'redis_gather_key_suffix' => ':custom', + ], + ], + ], + ])); + $container->shouldReceive('get')->with(RedisFactory::class)->andReturn($redisFactory); + + $factory = new RedisStorageFactory(); + $redis = $factory($container); + + $prefixProperty = new ReflectionProperty(Redis::class, 'prefix'); + + $metricGatherKeySuffixProperty = new ReflectionProperty(Redis::class, 'metricGatherKeySuffix'); + + self::assertInstanceOf(Redis::class, $redis); + self::assertEquals('custom:', $prefixProperty->getValue($redis)); + self::assertEquals(':custom', $metricGatherKeySuffixProperty->getValue($redis)); + } } diff --git a/tests/Adapter/Prometheus/RedisTest.php b/tests/Adapter/Prometheus/RedisTest.php index 533a68a5c..81d589124 100644 --- a/tests/Adapter/Prometheus/RedisTest.php +++ b/tests/Adapter/Prometheus/RedisTest.php @@ -2,17 +2,19 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Adapter\Prometheus; use Hyperf\Metric\Adapter\Prometheus\Redis; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use Prometheus\Counter; use Prometheus\Histogram; @@ -23,6 +25,7 @@ * @internal * @coversNothing */ +#[CoversNothing] class RedisTest extends TestCase { protected string $prePrefix; @@ -34,10 +37,7 @@ protected function setUp(): void parent::setUp(); $prefixProperty = new ReflectionProperty(Redis::class, 'prefix'); - $prefixProperty->setAccessible(true); - $metricGatherKeySuffix = new ReflectionProperty(Redis::class, 'metricGatherKeySuffix'); - $metricGatherKeySuffix->setAccessible(true); $this->prePrefix = $prefixProperty->getDefaultValue(); $this->preMetricGatherKeySuffix = $metricGatherKeySuffix->getDefaultValue(); @@ -62,22 +62,14 @@ public function testToMetricKey() Redis::setPrefix('prometheus:'); $method = new ReflectionMethod(Redis::class, 'toMetricKey'); - $method->setAccessible(true); self::assertEquals('prometheus:counter:hyperf_metric{counter}', $method->invoke(new Redis(new \Redis()), $data)); - - // 兼容 < v3.1 - Redis::setPrefix('PROMETHEUS_'); - $method = new ReflectionMethod(Redis::class, 'toMetricKey'); - $method->setAccessible(true); - self::assertEquals('PROMETHEUS_:counter:hyperf_metric{counter}', $method->invoke(new Redis(new \Redis()), $data)); } public function testGetMetricGatherKey() { $method = new ReflectionMethod(Redis::class, 'getMetricGatherKey'); - $method->setAccessible(true); - self::assertEquals('PROMETHEUS_counter_METRIC_KEYS{counter}', $method->invoke(new Redis(new \Redis()), Counter::TYPE)); + self::assertEquals('prometheus:counter:metric_keys{counter}', $method->invoke(new Redis(new \Redis()), Counter::TYPE)); } public function testCollectSamples() @@ -105,7 +97,6 @@ public function testCollectSamples() ); $method = new ReflectionMethod(Redis::class, 'collectSamples'); - $method->setAccessible(true); $result = $method->invoke(new Redis($redis), Counter::TYPE); self::assertEquals([ @@ -158,7 +149,6 @@ public function testCollectSamplesLabelNameNotMatch() ); $method = new ReflectionMethod(Redis::class, 'collectSamples'); - $method->setAccessible(true); $result = $method->invoke(new Redis($redis), Counter::TYPE); self::assertEquals([ @@ -202,7 +192,6 @@ public function testCollectHistograms() ); $method = new ReflectionMethod(Redis::class, 'collectHistograms'); - $method->setAccessible(true); $result = $method->invoke(new Redis($redis), Histogram::TYPE); self::assertEquals([ @@ -307,7 +296,6 @@ public function testCollectHistogramsLabelNotMatch() ); $method = new ReflectionMethod(Redis::class, 'collectHistograms'); - $method->setAccessible(true); $result = $method->invoke(new Redis($redis), Histogram::TYPE); self::assertEquals([ diff --git a/tests/Adapter/RemoteProxy/MetricCollectorTest.php b/tests/Adapter/RemoteProxy/MetricCollectorTest.php new file mode 100644 index 000000000..e971f5c86 --- /dev/null +++ b/tests/Adapter/RemoteProxy/MetricCollectorTest.php @@ -0,0 +1,82 @@ +assertSame(0, count($collector->getBuffer())); + + $collector->add($data = new stdClass()); + + $this->assertSame(1, count($collector->getBuffer())); + } + + public function testFlush() + { + $this->mockProcessCollector(); + + $collector = new MetricCollector(100); + $collector->add(new stdClass()); + $collector->flush(); + + $this->assertSame(0, count($collector->getBuffer())); + } + + public function testAddDataWithFlush() + { + $this->mockProcessCollector(); + + $collector = new MetricCollector(1); + $collector->add(new stdClass()); + + $this->assertSame(0, count($collector->getBuffer())); + } + + protected function mockProcessCollector() + { + if ($this->processMocked) { + return; + } + + $process = Mockery::mock(Process::class); + $process->shouldReceive('write'); + + ProcessCollector::add('metric', $process); + + $this->processMocked = true; + } +} diff --git a/tests/Cases/MetricFactoryPickerTest.php b/tests/Cases/MetricFactoryPickerTest.php index 55ffe1806..ff7af2472 100644 --- a/tests/Cases/MetricFactoryPickerTest.php +++ b/tests/Cases/MetricFactoryPickerTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Cases; use Hyperf\Config\Config; @@ -21,12 +22,15 @@ use Hyperf\Metric\MetricFactoryPicker; use Hyperf\Process\ProcessCollector; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; +use Swoole\Process; /** * @internal * @coversNothing */ +#[CoversNothing] class MetricFactoryPickerTest extends TestCase { protected function tearDown(): void @@ -96,7 +100,7 @@ public function testProxy() ], ], ]); - ProcessCollector::add('dummy', Mockery::mock(\Swoole\Process::class)); + ProcessCollector::add('dummy', Mockery::mock(Process::class)); $container = Mockery::mock(Container::class); $container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config); $container->shouldReceive('get')->with(RemoteFactory::class)->andReturn(Mockery::mock(RemoteFactory::class)); @@ -123,7 +127,7 @@ public function testMetricProcess() ], ], ]); - ProcessCollector::add('dummy', Mockery::mock(\Swoole\Process::class)); + ProcessCollector::add('dummy', Mockery::mock(Process::class)); $container = Mockery::mock(Container::class); $container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config); $container->shouldReceive('get')->with(PrometheusFactory::class)->andReturn(Mockery::mock(PrometheusFactory::class)); diff --git a/tests/Cases/MetricFactoryTest.php b/tests/Cases/MetricFactoryTest.php index 1f63c5c7d..becb28b9c 100644 --- a/tests/Cases/MetricFactoryTest.php +++ b/tests/Cases/MetricFactoryTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Cases; use Hyperf\Config\Config; @@ -18,11 +19,17 @@ use Hyperf\Metric\Adapter\Prometheus\Constants; use Hyperf\Metric\Adapter\Prometheus\MetricFactory as PrometheusFactory; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use Prometheus\CollectorRegistry; use ReflectionClass; use ReflectionMethod; +/** + * @internal + * @coversNothing + */ +#[CoversNothing] /** * @internal * @coversNothing @@ -55,7 +62,6 @@ public function testPrometheusGetUri() $p = new PrometheusFactory($config, $r, $c, $l, new ServerFactory($l)); $ref = new ReflectionClass($p); $method = $ref->getMethod('getUri'); - $method->setAccessible(true); $this->assertStringContainsString('http://127.0.0.1/metrics/job/metric/ip/', $method->invokeArgs($p, ['127.0.0.1', 'metric'])); $this->assertStringContainsString('https://127.0.0.1/metrics/job/metric/ip/', $method->invokeArgs($p, ['https://127.0.0.1', 'metric'])); $this->assertStringContainsString('http://127.0.0.1:8080/metrics/job/metric/ip/', $method->invokeArgs($p, ['127.0.0.1:8080', 'metric'])); @@ -81,7 +87,6 @@ public function testGetNamespace() $l = Mockery::mock(StdoutLoggerInterface::class); $p = new PrometheusFactory($config, $r, $c, $l, new ServerFactory($l)); $method = new ReflectionMethod(PrometheusFactory::class, 'getNamespace'); - $method->setAccessible(true); $this->assertEquals('hello__world_', $method->invoke($p)); } } diff --git a/tests/Cases/OnWorkerStartTest.php b/tests/Cases/OnWorkerStartTest.php index 14b5d4b65..43ca97b83 100644 --- a/tests/Cases/OnWorkerStartTest.php +++ b/tests/Cases/OnWorkerStartTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Cases; use Hyperf\Config\Config; @@ -18,6 +19,7 @@ use Hyperf\Metric\Contract\MetricFactoryInterface; use Hyperf\Metric\Listener\OnWorkerStart; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use Psr\EventDispatcher\EventDispatcherInterface; @@ -25,6 +27,7 @@ * @internal * @coversNothing */ +#[CoversNothing] class OnWorkerStartTest extends TestCase { protected function tearDown(): void @@ -50,7 +53,7 @@ public function testHandle() $l = new OnWorkerStart($container); - $l->process(new class() { + $l->process(new class { public $workerId = 1; }); @@ -72,7 +75,7 @@ public function testFireEvent() $container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config); $container->shouldReceive('get')->with(MetricFactoryInterface::class)->andReturn($factory); $container->shouldReceive('get')->with(EventDispatcherInterface::class)->andReturn( - new class() { + new class { public function dispatch() { return true; @@ -80,10 +83,10 @@ public function dispatch() } )->once(); $l = new OnWorkerStart($container); - $l->process(new class() { + $l->process(new class { public $workerId = 0; }); - $l->process(new class() { + $l->process(new class { public $workerId = 1; }); $this->assertTrue(true); @@ -103,7 +106,7 @@ public function testNotFireEvent() $container->shouldReceive('get')->with(ConfigInterface::class)->andReturn($config); $container->shouldReceive('get')->with(MetricFactoryInterface::class)->andReturn($factory); $l = new OnWorkerStart($container); - $l->process(new class() { + $l->process(new class { public $workerId = 0; }); $this->assertTrue(true); diff --git a/tests/Cases/SqlSanitizerTest.php b/tests/Cases/SqlSanitizerTest.php new file mode 100644 index 000000000..652907672 --- /dev/null +++ b/tests/Cases/SqlSanitizerTest.php @@ -0,0 +1,77 @@ +sanitize('select * from `users` where `id` in (200093484)') + ); + + self::assertSame( + 'select * from `bin_codes` where `bin_codes`.`bin` in (?)', + $sanitizer->sanitize('select * from `bin_codes` where `bin_codes`.`bin` in (?)') + ); + + self::assertSame( + 'select * from `card_tokens` where (`card_id` = ?)', + $sanitizer->sanitize('select * from `card_tokens` where (`card_id` = ?)') + ); + + self::assertSame( + 'select * from `cards` where `owner_id` not in (?, ?)', + $sanitizer->sanitize('select * from `cards` where `owner_id` not in (1260361, 903023958)') + ); + + self::assertSame( + 'select * from `cards` where `owner_id` not in (?, ?, ?)', + $sanitizer->sanitize('select * from `cards` where `owner_id` not in (1260361, 903023958, 880427302)') + ); + } + + public function testSanitizeLimitAndOffset(): void + { + $sanitizer = new SqlSanitizer(); + + self::assertSame( + 'select * from `cards` where `user_id` in (?) LIMIT ?', + $sanitizer->sanitize('select * from `cards` where `user_id` in (1) LIMIT 100') + ); + + self::assertSame( + 'select * from `cards` where `user_id` in (?) LIMIT ? OFFSET ?', + $sanitizer->sanitize('select * from `cards` where `user_id` in (1) LIMIT 100 OFFSET 100') + ); + + self::assertSame( + 'select * from `cards` where `user_id` in (?) limit ?', + $sanitizer->sanitize('select * from `cards` where `user_id` in (1) limit 100') + ); + + self::assertSame( + 'select * from `cards` where `user_id` in (?) limit ? offset ?', + $sanitizer->sanitize('select * from `cards` where `user_id` in (1) limit 100 offset 100') + ); + } +} diff --git a/tests/Cases/TimerTest.php b/tests/Cases/TimerTest.php index d1040e27d..673ed20ac 100644 --- a/tests/Cases/TimerTest.php +++ b/tests/Cases/TimerTest.php @@ -2,13 +2,14 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ + namespace HyperfTest\Metric\Cases; use Hyperf\Context\ApplicationContext; @@ -17,12 +18,14 @@ use Hyperf\Metric\Contract\MetricFactoryInterface; use Hyperf\Metric\Timer; use Mockery; +use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; /** * @internal * @coversNothing */ +#[CoversNothing] class TimerTest extends TestCase { protected function tearDown(): void @@ -58,7 +61,7 @@ public function testEndNotCalled() private function mockContainer() { $container = Mockery::mock(Container::class); - $container->shouldReceive('make')->with(MetricFactoryInterface::class, [])->andReturn(new class() { + $container->shouldReceive('make')->with(MetricFactoryInterface::class, [])->andReturn(new class { public function makeHistogram($name, $labels) { $histogram = Mockery::mock(HistogramInterface::class); diff --git a/tests/Cases/UriTest.php b/tests/Cases/UriTest.php new file mode 100644 index 000000000..2db72cfea --- /dev/null +++ b/tests/Cases/UriTest.php @@ -0,0 +1,245 @@ +', Uri::sanitize('/v2/test/123')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/123/bar')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/123/bar/456/')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/123/456')); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/123/456/')); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/123/456/789')); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/123/456/789/')); + } + + public function testSanitizePhoneNumber(): void + { + $phoneNumber = '+5511983999292'; + $phoneNumber2 = '+9607392675'; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$phoneNumber}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$phoneNumber}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$phoneNumber}/bar/{$phoneNumber2}/")); + self::assertSame('/v5/test//', Uri::sanitize("/v5/test/$phoneNumber/$phoneNumber2")); + self::assertSame('/v6/test///', Uri::sanitize("/v6/test/$phoneNumber/$phoneNumber2/")); + self::assertSame('/v7/test///', Uri::sanitize("/v7/test/$phoneNumber/$phoneNumber2/$phoneNumber")); + self::assertSame('/v8/test////', Uri::sanitize("/v8/test/$phoneNumber/$phoneNumber2/$phoneNumber/")); + } + + public function testSanitizeLicensePlatesStrings(): void + { + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize('/v2/test/PET9D49')); + self::assertSame('/v2/test/', Uri::sanitize('/v2/test/PET9349')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/PET9D49/bar')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/PET9349/bar')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/PET9D49/bar/PET9D49/')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/PET9349/bar/PET9349/')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/PET9D49/PET9D49')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/PET9349/PET9349')); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/PET9D49/PET9D49/')); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/PET9349/PET9349/')); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/PET9D49/PET9D49/PET9D49')); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/PET9349/PET9349/PET9349')); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/PET9D49/PET9D49/PET9D49/')); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/PET9349/PET9349/PET9349/')); + } + + public function testClearUriUuids(): void + { + $uuid = '123e4567-e89b-12d3-a456-426614174000'; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$uuid}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$uuid}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$uuid}/bar/{$uuid}/")); + self::assertSame('/v5/test//', Uri::sanitize("/v5/test/{$uuid}/{$uuid}")); + self::assertSame('/v6/test///', Uri::sanitize("/v6/test/{$uuid}/{$uuid}/")); + self::assertSame('/v7/test///', Uri::sanitize("/v7/test/{$uuid}/{$uuid}/{$uuid}")); + self::assertSame('/v8/test////', Uri::sanitize("/v8/test/{$uuid}/{$uuid}/{$uuid}/")); + } + + public function testClearUriOids(): void + { + $oid = '650229807612bba4984d1fc7'; + $oidShort = '65022612bba84d1f'; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$oid}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$oid}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$oid}/bar/{$oid}/")); + self::assertSame('/v5/test//', Uri::sanitize("/v5/test/{$oid}/{$oid}")); + self::assertSame('/v6/test///', Uri::sanitize("/v6/test/{$oid}/{$oid}/")); + self::assertSame('/v7/test///', Uri::sanitize("/v7/test/{$oid}/{$oid}/{$oid}")); + self::assertSame('/v8/test////', Uri::sanitize("/v8/test/{$oid}/{$oid}/{$oid}/")); + self::assertSame('/v9/test//bar/', Uri::sanitize("/v9/test/{$oidShort}/bar/12345")); + } + + public function testAddsInitialSlash(): void + { + self::assertSame('/v1/', Uri::sanitize('/v1/')); + self::assertSame('/v1', Uri::sanitize('v1')); + self::assertSame('/v1/', Uri::sanitize('v1/')); + self::assertSame('/v1/test/', Uri::sanitize('/v1/test/')); + self::assertSame('/v1/test', Uri::sanitize('v1/test')); + self::assertSame('/v1/test/', Uri::sanitize('v1/test/')); + } + + public function testAndroidId(): void + { + $this->markTestSkipped(); + + self::assertSame('/device//user/', Uri::sanitize('/devices/a436d9ffefef80e8/user/999')); + self::assertSame('/device//user/', Uri::sanitize('/devices/7b5d68f217d90ff5/user/999')); + self::assertSame('/device//user/', Uri::sanitize('/devices/dc900fb903cc308c/user/999')); + self::assertSame('/device//user/', Uri::sanitize('/devices/86d144c9078c8176/user/999')); + self::assertSame('/device//user/', Uri::sanitize('/devices/86d144c9078c8176/user/8045169')); + } + + public function testSanitizeHashsStrings(): void + { + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize('/v2/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110')); + self::assertSame('/v2/test/', Uri::sanitize('/v2/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/81FE8BFE87576C3ECB22426F8E57847382917ACF/bar')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/bar')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/bar/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/bar/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220')); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/')); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/')); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110')); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220')); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/141da78905dcaa7ed8d4da7c3f49a2415ebdc110/')); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/7110EDA4D09E062AA5E4A390B0A572AC0D2C0220/')); + } + + public function testSanitizeEndToEndId(): void + { + $e2eid = 'E99999999202401010000abcDEF12345'; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$e2eid}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$e2eid}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$e2eid}/bar/{$e2eid}/")); + self::assertSame('/v5/test//', Uri::sanitize("/v5/test/{$e2eid}/{$e2eid}")); + self::assertSame('/v6/test///', Uri::sanitize("/v6/test/{$e2eid}/{$e2eid}/")); + self::assertSame('/v7/test///', Uri::sanitize("/v7/test/{$e2eid}/{$e2eid}/{$e2eid}")); + self::assertSame('/v8/test////', Uri::sanitize("/v8/test/{$e2eid}/{$e2eid}/{$e2eid}/")); + } + + public function testWithMaskParams(): void + { + $uriMask = [ + '/\/[a-f0-9]{64}/i' => '/', + ]; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test', $uriMask)); + self::assertSame('/v2/test/', Uri::sanitize('/v2/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7', $uriMask)); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/bar', $uriMask)); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/bar/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/', $uriMask)); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7', $uriMask)); + self::assertSame('/v6/test///', Uri::sanitize('/v6/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/', $uriMask)); + self::assertSame('/v7/test///', Uri::sanitize('/v7/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7', $uriMask)); + self::assertSame('/v8/test////', Uri::sanitize('/v8/test/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/54cf575c04fdef4667094b6fc4fab8014dd3fa53576b644ec399452c43b5e7f7/', $uriMask)); + } + + public function testClearUriExternalIds(): void + { + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v1/test/', Uri::sanitize('/v1/test/RR2101818220123720H9KJTERfw1a')); + self::assertSame('/v3/test//bar', Uri::sanitize('/v3/test/RN2401818220250720G4KJTQyU6Ds/bar')); + self::assertSame('/v4/test//bar//', Uri::sanitize('/v4/test/RR2101818220123720H9KJTERfw1a/bar/RN2401818220250720G4KJTQyU6Ds/')); + self::assertSame('/v5/test//', Uri::sanitize('/v5/test/RR2101818220123720H9KJTERfw1a/RN2401818220250720G4KJTQyU6Ds')); + self::assertSame('/v7/test////', Uri::sanitize('/v7/test/RR2101818220123720H9KJTERfw1a/RN2001818220123720H9KJTERBd52/RR2123818220123730H9KJTERBd52/')); + self::assertSame('/v9/test//bar/', Uri::sanitize('/v9/test/RR2101818220123720H9KJTERfw1a/bar/12345')); + } + + public function testSanitizeEmail(): void + { + $email = 'abcdwxyz@fghijk.com'; + $email2 = 'elmnopq@rstuvw.com.br'; + + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$email}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$email}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$email}/bar/{$email2}/")); + self::assertSame('/v5/test//', Uri::sanitize("/v5/test/$email/$email2")); + self::assertSame('/v6/test///', Uri::sanitize("/v6/test/$email/$email2/")); + self::assertSame('/v7/test///', Uri::sanitize("/v7/test/$email/$email2/$email")); + self::assertSame('/v8/test////', Uri::sanitize("/v8/test/$email/$email2/$email/")); + } + + public function testClearUriPrefixedId(): void + { + // Casos de teste específicos solicitados + $ecosystemId1 = 'ECOSYSTEM-PPF-0100206721_003'; + $ecosystemId2 = 'ECOSYSTEM-EPF-0100308183_001'; + $ecosystemId3 = 'ECOSYSTEM-ESF-105454545'; + $billUuid = 'BILL-1811cd92-ed15-4b8a-a571-6cfa44002703'; + + // Testes básicos + self::assertSame('/v1/test', Uri::sanitize('/v1/test')); + + // Testes com ECOSYSTEM-PPF-0100206721_003 + self::assertSame('/v2/test/', Uri::sanitize("/v2/test/{$ecosystemId1}")); + self::assertSame('/v3/test//bar', Uri::sanitize("/v3/test/{$ecosystemId1}/bar")); + self::assertSame('/v4/test//bar//', Uri::sanitize("/v4/test/{$ecosystemId1}/bar/{$ecosystemId1}/")); + + // Testes com ECOSYSTEM-EPF-0100308183_001 + self::assertSame('/v5/test/', Uri::sanitize("/v5/test/{$ecosystemId2}")); + self::assertSame('/v6/test//details', Uri::sanitize("/v6/test/{$ecosystemId2}/details")); + self::assertSame('/v7/test//', Uri::sanitize("/v7/test/{$ecosystemId2}/{$ecosystemId1}")); + + // Testes com ECOSYSTEM-ESF-105454545 + self::assertSame('/v8/test/', Uri::sanitize("/v8/test/{$ecosystemId3}")); + self::assertSame('/v9/test//config', Uri::sanitize("/v9/test/{$ecosystemId3}/config")); + + // Testes com BILL-1811cd92-ed15-4b8a-a571-6cfa44002703 + self::assertSame('/v10/test/', Uri::sanitize("/v10/test/{$billUuid}")); + self::assertSame('/v11/test//profile', Uri::sanitize("/v11/test/{$billUuid}/profile")); + self::assertSame('/v12/test//bar//', Uri::sanitize("/v12/test/{$billUuid}/bar/{$billUuid}/")); + + // Testes mistos entre os IDs + self::assertSame('/v13/test//', Uri::sanitize("/v13/test/{$billUuid}/{$ecosystemId3}")); + self::assertSame('/v14/test///', Uri::sanitize("/v14/test/{$ecosystemId1}/{$ecosystemId2}/{$billUuid}")); + self::assertSame('/v15/test////', Uri::sanitize("/v15/test/{$ecosystemId3}/{$billUuid}/{$ecosystemId1}/")); + + // Casos edge: diferentes contextos de API + self::assertSame('/users//profile', Uri::sanitize("/users/{$billUuid}/profile")); + self::assertSame('/api/v1/bills//details', Uri::sanitize("/api/v1/bills/{$billUuid}/details")); + self::assertSame('/ecosystems//platform/', Uri::sanitize("/ecosystems/{$ecosystemId1}/platform/{$ecosystemId2}")); + self::assertSame('/companies//admin//settings', Uri::sanitize("/companies/{$billUuid}/admin/{$ecosystemId3}/settings")); + + // Casos críticos: evitar falsos positivos + self::assertSame('/pic-pay/entry/id/', Uri::sanitize("/pic-pay/entry/id/{$ecosystemId3}")); + self::assertSame('/api-gateway/service/', Uri::sanitize("/api-gateway/service/{$ecosystemId2}")); + self::assertSame('/health-check/status/', Uri::sanitize("/health-check/status/{$billUuid}")); + + // Teste sem barra final + self::assertSame('/test/', Uri::sanitize("/test/{$billUuid}")); + self::assertSame('/ecosystem/', Uri::sanitize("/ecosystem/{$ecosystemId1}")); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d191304d9..ebf621972 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,11 +2,13 @@ declare(strict_types=1); /** - * This file is part of Hyperf. + * This file is part of Hyperf + OpenCodeCo * - * @link https://www.hyperf.io + * @link https://opencodeco.dev * @document https://hyperf.wiki - * @contact group@hyperf.io - * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + * @contact leo@opencodeco.dev + * @license https://github.com/opencodeco/hyperf-metric/blob/main/LICENSE */ -require_once dirname(__DIR__) . '/vendor/autoload.php'; +define('BASE_PATH', dirname(__DIR__, 1)); + +require_once BASE_PATH . '/vendor/autoload.php'; diff --git a/tests/ci.ini b/tests/ci.ini deleted file mode 100644 index 4ee69abc2..000000000 --- a/tests/ci.ini +++ /dev/null @@ -1,8 +0,0 @@ -[opcache] -opcache.enable_cli=1 - -[redis] -extension = "redis.so" - -[swoole] -extension = "swoole.so" diff --git a/tests/swoole.install.sh b/tests/swoole.install.sh deleted file mode 100644 index 04bedf4aa..000000000 --- a/tests/swoole.install.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -wget https://github.com/swoole/swoole-src/archive/v${SW_VERSION}.tar.gz -O swoole.tar.gz -mkdir -p swoole -tar -xf swoole.tar.gz -C swoole --strip-components=1 -rm swoole.tar.gz -cd swoole -phpize -./configure --enable-openssl --enable-mysqlnd -make -j$(nproc) -make install