commit 0b2299c42717541679318e39ddab591f9c14d2fc Author: ykxiao Date: Tue Jul 8 14:59:47 2025 +0800 协程版仓库后端项目 diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..252252d --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,52 @@ +# Dev Container Dockerfile +# +# @link https://www.hyperf.io +# @document https://hyperf.wiki +# @contact group@hyperf.io +# @license https://github.com/hyperf/hyperf/blob/master/LICENSE + +FROM hyperf/hyperf:8.3-alpine-v3.19-swoole +LABEL maintainer="Hyperf Developers " version="1.0" license="MIT" app.name="Hyperf" + +## +# ---------- env settings ---------- +## +# --build-arg timezone=Asia/Shanghai +ARG timezone + +ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \ + APP_ENV=dev \ + SCAN_CACHEABLE=(false) + +# update +RUN set -ex \ + # show php version and extensions + && php -v \ + && php -m \ + && php --ri swoole \ + # ---------- some config ---------- + && cd /etc/php* \ + # - config PHP + && { \ + echo "upload_max_filesize=128M"; \ + echo "post_max_size=128M"; \ + echo "memory_limit=1G"; \ + echo "date.timezone=${TIMEZONE}"; \ + } | tee conf.d/99_overrides.ini \ + # - config timezone + && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ + && echo "${TIMEZONE}" > /etc/timezone \ + # ---------- clear works ---------- + && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ + && echo -e "\033[42;37m Build Completed :).\033[0m\n" + +WORKDIR /opt/www + +# Composer Cache +# COPY ./composer.* /opt/www/ +# RUN composer install --no-dev --no-scripts + +COPY . /opt/www +RUN composer install && php bin/hyperf.php + +EXPOSE 9501 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..c0d2f54 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,7 @@ +{ + "build": { + "context": "..", + "dockerfile": "./Dockerfile" + }, + "forwardPorts": [9501] +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1f9e66f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +** +!app/ +!bin/ +!config/ +!composer.* diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6879583 --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +APP_NAME=skeleton +APP_ENV=dev + +DB_DRIVER=mysql +DB_HOST=localhost +DB_PORT=3306 +DB_DATABASE=hyperf +DB_USERNAME=root +DB_PASSWORD= +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_ci +DB_PREFIX= + +REDIS_HOST=localhost +REDIS_AUTH=(null) +REDIS_PORT=6379 +REDIS_DB=0 \ No newline at end of file diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile new file mode 100644 index 0000000..2485958 --- /dev/null +++ b/.github/workflows/Dockerfile @@ -0,0 +1,54 @@ +# Default Dockerfile +# +# @link https://www.hyperf.io +# @document https://hyperf.wiki +# @contact group@hyperf.io +# @license https://github.com/hyperf/hyperf/blob/master/LICENSE + +FROM hyperf/hyperf:8.3-alpine-v3.19-swoole +LABEL maintainer="Hyperf Developers " version="1.0" license="MIT" app.name="Hyperf" + +## +# ---------- env settings ---------- +## +# --build-arg timezone=Asia/Shanghai +ARG timezone + +ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \ + APP_ENV=prod \ + SCAN_CACHEABLE=(true) + +# update +RUN set -ex \ + # show php version and extensions + && php -v \ + && php -m \ + && php --ri swoole \ + # ---------- some config ---------- + && cd /etc/php* \ + # - config PHP + && { \ + echo "upload_max_filesize=128M"; \ + echo "post_max_size=128M"; \ + echo "memory_limit=1G"; \ + echo "date.timezone=${TIMEZONE}"; \ + } | tee conf.d/99_overrides.ini \ + # - config timezone + && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ + && echo "${TIMEZONE}" > /etc/timezone \ + # ---------- clear works ---------- + && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ + && echo -e "\033[42;37m Build Completed :).\033[0m\n" + +WORKDIR /opt/www + +# Composer Cache +# COPY ./composer.* /opt/www/ +# RUN composer install --no-dev --no-scripts + +COPY . /opt/www +RUN print "\n" | composer install -o && php bin/hyperf.php + +EXPOSE 9501 + +ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0ca82fa --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,12 @@ +name: Build Docker + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Build + run: cp -rf .github/workflows/Dockerfile . && docker build -t hyperf . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0f7d23f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,25 @@ +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 new file mode 100644 index 0000000..c69291b --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.buildpath +.settings/ +.project +*.patch +.idea/ +.git/ +runtime/ +vendor/ +.phpintel/ +.env +.DS_Store +.phpunit* +*.cache +.vscode/ +/phpstan.neon +/phpunit.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..a5fccae --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,57 @@ +# usermod -aG docker gitlab-runner + +stages: + - build + - deploy + +variables: + PROJECT_NAME: hyperf + REGISTRY_URL: registry-docker.org + +build_test_docker: + stage: build + before_script: +# - git submodule sync --recursive +# - git submodule update --init --recursive + script: + - docker build . -t $PROJECT_NAME + - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:test + - docker push $REGISTRY_URL/$PROJECT_NAME:test + only: + - test + tags: + - builder + +deploy_test_docker: + stage: deploy + script: + - docker stack deploy -c deploy.test.yml --with-registry-auth $PROJECT_NAME + only: + - test + tags: + - test + +build_docker: + stage: build + before_script: +# - git submodule sync --recursive +# - git submodule update --init --recursive + script: + - docker build . -t $PROJECT_NAME + - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME + - docker tag $PROJECT_NAME $REGISTRY_URL/$PROJECT_NAME:latest + - docker push $REGISTRY_URL/$PROJECT_NAME:$CI_COMMIT_REF_NAME + - docker push $REGISTRY_URL/$PROJECT_NAME:latest + only: + - tags + tags: + - builder + +deploy_docker: + stage: deploy + script: + - echo SUCCESS + only: + - tags + tags: + - builder diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..204686a --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,106 @@ +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', + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => null, + ], + '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', + ], + '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, + 'single_line_empty_body' => false, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('public') + ->exclude('runtime') + ->exclude('vendor') + ->in(__DIR__) + ) + ->setUsingCache(false); diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php new file mode 100644 index 0000000..c8b6300 --- /dev/null +++ b/.phpstorm.meta.php @@ -0,0 +1,12 @@ + '@'])); + override(\Hyperf\Context\Context::get(0), map(['' => '@'])); + override(\make(0), map(['' => '@'])); + override(\di(0), map(['' => '@'])); + override(\Hyperf\Support\make(0), map(['' => '@'])); + override(\Hyperf\Support\optional(0), type(0)); + override(\Hyperf\Tappable\tap(0), type(0)); +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4905614 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,54 @@ +# Default Dockerfile +# +# @link https://www.hyperf.io +# @document https://hyperf.wiki +# @contact group@hyperf.io +# @license https://github.com/hyperf/hyperf/blob/master/LICENSE + +FROM hyperf/hyperf:8.3-alpine-v3.19-swoole +LABEL maintainer="Hyperf Developers " version="1.0" license="MIT" app.name="Hyperf" + +## +# ---------- env settings ---------- +## +# --build-arg timezone=Asia/Shanghai +ARG timezone + +ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \ + APP_ENV=prod \ + SCAN_CACHEABLE=(true) + +# update +RUN set -ex \ + # show php version and extensions + && php -v \ + && php -m \ + && php --ri swoole \ + # ---------- some config ---------- + && cd /etc/php* \ + # - config PHP + && { \ + echo "upload_max_filesize=128M"; \ + echo "post_max_size=128M"; \ + echo "memory_limit=1G"; \ + echo "date.timezone=${TIMEZONE}"; \ + } | tee conf.d/99_overrides.ini \ + # - config timezone + && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ + && echo "${TIMEZONE}" > /etc/timezone \ + # ---------- clear works ---------- + && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ + && echo -e "\033[42;37m Build Completed :).\033[0m\n" + +WORKDIR /opt/www + +# Composer Cache +# COPY ./composer.* /opt/www/ +# RUN composer install --no-dev --no-scripts + +COPY . /opt/www +RUN composer install --no-dev -o && php bin/hyperf.php + +EXPOSE 9501 + +ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c35d3f5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Hyperf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d7a10d --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# Introduction + +This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework. + +# Requirements + +Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows. + +The various versions of Dockerfile have been prepared for you in the [hyperf/hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf/hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run. + +When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements: + + - PHP >= 8.1 + - Any of the following network engines + - Swoole PHP extension >= 5.0,with `swoole.use_shortname` set to `Off` in your `php.ini` + - Swow PHP extension >= 1.3 + - JSON PHP extension + - Pcntl PHP extension + - OpenSSL PHP extension (If you need to use the HTTPS) + - PDO PHP extension (If you need to use the MySQL Client) + - Redis PHP extension (If you need to use the Redis Client) + - Protobuf PHP extension (If you need to use the gRPC Server or Client) + +# Installation using Composer + +The easiest way to create a new Hyperf project is to use [Composer](https://getcomposer.org/). If you don't have it already installed, then please install as per [the documentation](https://getcomposer.org/download/). + +To create your new Hyperf project: + +```bash +composer create-project hyperf/hyperf-skeleton path/to/install +``` + +If your development environment is based on Docker you can use the official Composer image to create a new Hyperf project: + +```bash +docker run --rm -it -v $(pwd):/app composer create-project --ignore-platform-reqs hyperf/hyperf-skeleton path/to/install +``` + +# Getting started + +Once installed, you can run the server immediately using the command below. + +```bash +cd path/to/install +php bin/hyperf.php start +``` + +Or if in a Docker based environment you can use the `docker-compose.yml` provided by the template: + +```bash +cd path/to/install +docker-compose up +``` + +This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/` which will bring up Hyperf default home page. + +## Hints + +- A nice tip is to rename `hyperf-skeleton` of files like `composer.json` and `docker-compose.yml` to your actual project name. +- Take a look at `config/routes.php` and `app/Controller/IndexController.php` to see an example of a HTTP entrypoint. + +**Remember:** you can always replace the contents of this README.md file to something that fits your project description. diff --git a/app/Amqp/Consumer/AliSlsConsumer.php b/app/Amqp/Consumer/AliSlsConsumer.php new file mode 100644 index 0000000..1f8b658 --- /dev/null +++ b/app/Amqp/Consumer/AliSlsConsumer.php @@ -0,0 +1,34 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +#[Consumer(exchange: 'wh_ali_sls', routingKey: 'wh_ali_sls_key', queue: 'wh_ali_sls_queue', name: "AliSlsConsumer", nums: 5)] +class AliSlsConsumer extends BaseConsumer +{ + #[Inject] + protected AliLogsSignService $aliLogsSignService; + public function handle($data): Result + { + $this->aliLogsSignService->putWebTracking($data); + + return Result::ACK; + } +} diff --git a/app/Amqp/Consumer/BaseConsumer.php b/app/Amqp/Consumer/BaseConsumer.php new file mode 100644 index 0000000..0b397db --- /dev/null +++ b/app/Amqp/Consumer/BaseConsumer.php @@ -0,0 +1,89 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Amqp\Consumer; + +use Hyperf\Amqp\Message\ConsumerMessage; +use App\Context\QueueContext; +use Hyperf\Amqp\Result; +use Hyperf\DbConnection\Db; +use PhpAmqpLib\Exception\AMQPChannelClosedException; +use PhpAmqpLib\Message\AMQPMessage; +use App\Log\Log; +use Exception; +use PhpAmqpLib\Exception\AMQPConnectionClosedException; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:18 + * Description: 消费者抽象基类. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +abstract class BaseConsumer extends ConsumerMessage +{ + public function consumeMessage($data, AMQPMessage $message): Result + { + $consumerClass = get_class($this); + + // 设置用户信息上下文信息 + if (!empty($data['user'])) { + QueueContext::setUser($data['user']); + } + if (!empty($company = $data['company'])) { + QueueContext::setCompanyInfo($company); + } + + Db::beginTransaction(); + + try { + $handle = $this->handle($data); + + Db::commit(); + + return $handle; + } catch (AMQPChannelClosedException|AMQPConnectionClosedException $e) { + Log::get('queue', 'queue')->error("AMQP通道关闭异常 ($consumerClass): " . $e->getMessage(), [ + 'data' => $data, + 'exception' => $e, + ]); + + Db::rollBack(); + + // 可选:重连逻辑 or 丢弃 + return Result::ACK; // 或 NACK + } catch (Exception $e) { + Log::get('queue', 'queue')->error("AMQP消费者异常 ($consumerClass): " . $e->getMessage(), [ + 'data' => $data, + 'exception' => $e, + ]); + + Db::rollBack(); + + return Result::ACK; + } + } + + /** + * 子类实现的核心处理逻辑 + * @param mixed $data + * @return Result + */ + abstract protected function handle(mixed $data): Result; +} \ No newline at end of file diff --git a/app/Amqp/Consumer/UserImportConsumer.php b/app/Amqp/Consumer/UserImportConsumer.php new file mode 100644 index 0000000..595ce02 --- /dev/null +++ b/app/Amqp/Consumer/UserImportConsumer.php @@ -0,0 +1,19 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Amqp\Producer; + +use App\Context\UserContext; +use Hyperf\Amqp\Message\ProducerMessage; + +/** + * Author: ykxiao + * Date: 2025/6/6 + * Time: 上午9:57 + * Description: amqp生产者抽象基类. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +abstract class BaseProducer extends ProducerMessage +{ + public function __construct(array $data) + { + // 设置用户信息上下文信息 + if (UserContext::hasCurrentUser()) { + $data['user'] = UserContext::getCurrentUser(); + } + + $this->payload = $data; + $this->properties['delivery_mode'] = 2; // 消息持久化 + } +} \ No newline at end of file diff --git a/app/Amqp/Producer/UserImportProducer.php b/app/Amqp/Producer/UserImportProducer.php new file mode 100644 index 0000000..9d20d2b --- /dev/null +++ b/app/Amqp/Producer/UserImportProducer.php @@ -0,0 +1,13 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Aspect; + +use Hyperf\DbConnection\Db; +use Hyperf\Di\Aop\AbstractAspect; +use Hyperf\Di\Annotation\Aspect; +use Hyperf\Di\Aop\ProceedingJoinPoint; +use Throwable; + +#[Aspect] +class TransactionalAspect extends AbstractAspect +{ + public array $classes = [ + 'App\Controller\*', + ]; + + public array $annotations = [ + ]; + + /** + * 处理方法执行过程,通过AOP的方式对方法执行进行事务控制。 + * + * @param ProceedingJoinPoint $proceedingJoinPoint AOP中的连接点对象,代表正在执行的方法 + * @return mixed 返回执行方法的结果 + * @throws Throwable 如果执行过程中发生异常,则抛出 + */ + public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed + { + Db::beginTransaction(); // 开始事务 + try { + $result = $proceedingJoinPoint->process(); // 执行目标方法 + + Db::commit(); // 方法执行成功,提交事务 + + return $result; + } catch (Throwable $e) { + Db::rollback(); // 发生异常,回滚事务 + + throw $e; // 重新抛出捕获的异常 + } + } +} \ No newline at end of file diff --git a/app/Constants/AbsConst.php b/app/Constants/AbsConst.php new file mode 100644 index 0000000..101d0a5 --- /dev/null +++ b/app/Constants/AbsConst.php @@ -0,0 +1,38 @@ + $value) { + // 确保获取的是当前常量对应的消息 + $message = $value['message'] ?? ''; + $list[] = [ + 'label' => $message, + 'value' => $name, + ]; + } + } + return $list; + } +} diff --git a/app/Constants/ActiveStatusConst.php b/app/Constants/ActiveStatusConst.php new file mode 100644 index 0000000..3258ccd --- /dev/null +++ b/app/Constants/ActiveStatusConst.php @@ -0,0 +1,27 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Context; + +use Hyperf\Context\Context; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:19 + * Description: 队列上下文 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class QueueContext +{ + private const string USER_KEY = 'queue.user'; + + private const string COMPANY_KEY = 'company'; + + public static function setUser(array $user): void + { + Context::set(self::USER_KEY, $user); + } + + public static function getUser(): ?array + { + return Context::get(self::USER_KEY); + } + + /** + * 设置当前公司信息 + * @param array $companyInfo + * @return void + */ + public static function setCompanyInfo(array $companyInfo): void + { + Context::set(self::COMPANY_KEY, $companyInfo); + } + + /** + * 获取当前公司信息 + * @return array|null + */ + public static function getCompanyInfo(): ?array + { + return Context::get(self::COMPANY_KEY); + } + + public static function clear(): void + { + Context::destroy(self::USER_KEY); + } +} \ No newline at end of file diff --git a/app/Context/UserContext.php b/app/Context/UserContext.php new file mode 100644 index 0000000..f0dcdd9 --- /dev/null +++ b/app/Context/UserContext.php @@ -0,0 +1,86 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Context; + +use App\Repository\Company\FirstCompanyRepository; +use Exception; +use Hyperf\Context\Context; +use function Hyperf\Support\make; + +class UserContext +{ + private const string USER_KEY = 'user'; + + private const string TOKEN_KEY = 'token'; + + /** + * 设置当前用户信息到 Context + * + * @param array|string|int $user 用户信息数组 + * @throws Exception + */ + public static function setCurrentUser(array|string|int $user): void + { + $companyRepository = make(FirstCompanyRepository::class); + if (!empty($companyInfo = $companyRepository->getCompanyByFullName($user['user']['full_name']))) { + $user['company'] = $companyInfo; + } + + Context::set(self::USER_KEY, $user); + } + + /** + * 从 Context 获取当前用户信息 + * + * @return array|null 返回用户信息数组或 null 如果未找到 + */ + public static function getCurrentUser(): ?array + { + return Context::get(self::USER_KEY); + } + + public static function hasCurrentUser(): bool + { + return Context::has(self::USER_KEY); + } + + /** + * 设置当前用户令牌 + * @param string $token + * @return void + */ + public static function setCurrentToken(string $token): void + { + Context::set(self::TOKEN_KEY, $token); + } + + /** + * 从 Context 获取当前用户令牌 + * @return string|null + */ + public static function getCurrentToken(): ?string + { + return Context::get(self::TOKEN_KEY); + } + + /** + * 清除当前用户信息 + */ + public static function clearCurrentUser(): void + { + Context::set(self::USER_KEY, null); + } +} \ No newline at end of file diff --git a/app/Controller/AbstractController.php b/app/Controller/AbstractController.php new file mode 100644 index 0000000..4aaa379 --- /dev/null +++ b/app/Controller/AbstractController.php @@ -0,0 +1,86 @@ +request->all(); + return [$params['page'] ?? 1, $params['pageSize'] ?? 100]; + } + + /** + * 获取当前用户令牌 + * @return string|null + */ + public function token(): ?string + { + return UserContext::getCurrentToken(); + } + + /** + * 获取当前用户信息 + * @return array + */ + public function user(): array + { + return UserContext::getCurrentUser() ?? []; + } + + /** + * 获取当前公司信息 + * @return array + */ + public function company(): array + { + return $this->user()['company'] ?? []; + } + + /** + * 操作日志. + * @param string $log + * @param int $source + */ + protected function opLogs(string $log, int $source = 0): void + { + $this->opLogsService->operatorLogs($log, $source); + } +} diff --git a/app/Controller/CompanyController.php b/app/Controller/CompanyController.php new file mode 100644 index 0000000..6ea413f --- /dev/null +++ b/app/Controller/CompanyController.php @@ -0,0 +1,43 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Controller; + +use App\Repository\Company\CompanyRepository; +use App\Request\CompanyRequest; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpMessage\Server\Response; +use Hyperf\Validation\Annotation\Scene; + +class CompanyController extends AbstractController +{ + #[Inject] + protected CompanyRepository $companyRepository; + + /** + * 添加公司. + * @param CompanyRequest $request + * @return Response + */ + #[Scene(scene: 'addCompany', argument: 'request')] + public function addCompany(CompanyRequest $request): Response + { + $data = $request->all(); + + $this->companyRepository->add($data); + + return $this->apiResponse->success(); + } +} \ No newline at end of file diff --git a/app/Controller/FirstCompanyController.php b/app/Controller/FirstCompanyController.php new file mode 100644 index 0000000..f59fdae --- /dev/null +++ b/app/Controller/FirstCompanyController.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Controller; + +use App\Repository\Company\FirstCompanyRepository; +use App\Request\FirstCompanyRequest; +use Exception; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpMessage\Server\Response; +use Hyperf\Validation\Annotation\Scene; + +class FirstCompanyController extends AbstractController +{ + #[Inject] + protected FirstCompanyRepository $firstCompanyRepository; + + /** + * 添加公司. + * @param FirstCompanyRequest $request + * @return Response + * @throws Exception + */ + #[Scene(scene: 'addFirstCompany', argument: 'request')] + public function addFirstCompany(FirstCompanyRequest $request): Response + { + $data = $request->all(); + + $this->firstCompanyRepository->addCompany($data); + + return $this->apiResponse->success(); + } +} \ No newline at end of file diff --git a/app/Controller/PurchaseController.php b/app/Controller/PurchaseController.php new file mode 100644 index 0000000..6869e21 --- /dev/null +++ b/app/Controller/PurchaseController.php @@ -0,0 +1,52 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Controller; + +use App\Repository\Purchase\PurchaseRepository; +use App\Request\PurchaseRequest; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpMessage\Server\Response; +use Hyperf\Validation\Annotation\Scene; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午5:42 + * Description: 采购单入库管理. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class PurchaseController extends AbstractController +{ + #[Inject] + protected PurchaseRepository $purchaseRepository; + + /** + * 新增采购单入库单 + * @param PurchaseRequest $request + * @return Response + */ + #[Scene(scene: 'addPurchase', argument: '')] + public function addPurchase(PurchaseRequest $request): Response + { + $this->purchaseRepository->addPurchase($request->all()); + + return $this->apiResponse->success(); + } +} \ No newline at end of file diff --git a/app/Controller/RoleController.php b/app/Controller/RoleController.php new file mode 100644 index 0000000..e3f359c --- /dev/null +++ b/app/Controller/RoleController.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Controller; + +use App\JsonRpc\UserAuthServiceInterface; +use App\Request\RoleRequest; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpMessage\Server\Response; +use Hyperf\Validation\Annotation\Scene; + +class RoleController extends AbstractController +{ + #[Inject] + protected UserAuthServiceInterface $userAuthServiceInterface; + + /** + * 添加角色. + * @param RoleRequest $request + * @return Response + */ + #[Scene(scene: 'addRole', argument: 'request')] + public function addRole(RoleRequest $request): Response + { + $params = $request->all(); + + $data = [ + 'companyInfo' => $this->company(), + 'id' => $params['id'] ?? null, + 'role_name' => $params['role_name'], + 'active_status' => $params['active_status'], + 'sort' => $params['sort'], + ]; + // 添加角色. + $this->userAuthServiceInterface->addRole($data); + + return $this->apiResponse->success(); + } +} \ No newline at end of file diff --git a/app/Controller/UserController.php b/app/Controller/UserController.php new file mode 100644 index 0000000..62a59ac --- /dev/null +++ b/app/Controller/UserController.php @@ -0,0 +1,110 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Controller; + +use App\Amqp\Producer\UserImportProducer; +use App\Constants\UserTypeConst; +use App\Context\UserContext; +use App\JsonRpc\UserAuthServiceInterface; +use App\Request\UserRequest; +use Exception; +use Hyperf\Amqp\Producer; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpMessage\Server\Response; +use Hyperf\Validation\Annotation\Scene; + +class UserController extends AbstractController +{ + #[Inject] + protected UserAuthServiceInterface $userAuthService; + + #[Inject] + protected Producer $producer; + + /** + * 用户登录. + * @param UserRequest $request + * @return Response + * @throws Exception + */ + #[Scene(scene: 'userLogin', argument: 'request')] + public function userLogin(UserRequest $request): Response + { + $rpcUser = $this->userAuthService->userLogin([ + 'login_name' => $request->input('login_name'), + 'password' => $request->input('password'), + ]); + $user = $rpcUser['result'] ?? []; + if (empty($user)) { + return $this->apiResponse->error('用户名不存在'); + } + + // 设置用户信息上下文 + UserContext::setCurrentUser($user['user']); + + $this->opLogs('[用户登录]登录名 ' . $request->input('login_name')); + + return $this->apiResponse->success($user); + } + + /** + * 添加用户. + * @param UserRequest $request + * @return Response + */ + #[Scene(scene: 'addUser', argument: 'request')] + public function addUser(UserRequest $request): Response + { + $data = $request->all(); + $data['token'] = $this->token(); + $data['user_type'] = UserTypeConst::SYSTEM_USER; + $data['companyInfo'] = $this->company(); + $data['role_ids'] = $request->input('role_ids', []); // 角色ID列表 + + $this->userAuthService->addUser($data); + + return $this->apiResponse->success(); + } + + /** + * 获取用户列表. + * @param UserRequest $request + * @return Response + */ + #[Scene(scene: 'getUserList', argument: 'request')] + public function getUserList(UserRequest $request): Response + { + $data = [ + 'companyInfo' => $this->company(), + 'userInfo' => UserContext::getCurrentUser(), + 'getPage' => $this->getPage(), + 'params' => $request->all() + ]; + + $rpcResult = $this->userAuthService->userList($data); + + return $this->apiResponse->success($rpcResult['result']); + } + + public function importUser(): Response + { + $data = []; + + $this->producer->produce(new UserImportProducer($data)); + + return $this->apiResponse->success(); + } +} \ No newline at end of file diff --git a/app/Dao/AbstractDao.php b/app/Dao/AbstractDao.php new file mode 100644 index 0000000..3c23842 --- /dev/null +++ b/app/Dao/AbstractDao.php @@ -0,0 +1,432 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Dao; + +use App\Model\Model; +use App\Service\Trait\ColumnConfigTrait; +use Exception; +use Hyperf\Collection\Collection; +use Hyperf\Database\Model\Builder; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpServer\Contract\RequestInterface; + +/** + * Author: ykxiao + * Date: 2025/2/28 + * Time: 上午8:32 + * Description: AbstractDao. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +abstract class AbstractDao +{ + use ColumnConfigTrait; + + // 支持的表达式 - 白名单操作符 + protected static array $OPERATORS_THAT_SUPPORT_VALUES = [ + // 比较运算符 + '=', '<', '<=', '>', '>=', '<>', '!=', + + // 逻辑运算符 + 'between', 'not between', 'in', 'not in', 'like', 'is null', 'is not null', + ]; + + #[Inject] + protected RequestInterface $request; + + private int|string $keyId; + + private array $queryResult; + + /** + * @return Model + */ + abstract protected function getModel(): string; + + /** + * 数据操作. + */ + public function builder(): Builder + { + return $this->getModel()::query(); + } + + /** + * 实例化. + */ + public function make(): AbstractDao + { + return new $this(); + } + + /** + * 记录查询. + * @throws Exception + */ + public function qInfo(array $params = []): Builder + { + $query = $this->builder(); + $params = $params ?: $this->request->all(); + if (!empty($params['ids']) && is_array($params['ids'])) { + $query->whereIn('id', $params['ids']); + } else { + $query->where('id', intval($params['id'])); + } + if (!$query->exists()) { + throw new Exception('记录不存在'); + } + return $query; + } + + /** + * 通用创建&更新. + * @param array $data 需要新增更新的数据 + * @param array $updateCondition 更新条件 + * @return $this + * @throws Exception + */ + public function commonCreate(array $data = [], array $updateCondition = []): AbstractDao + { + $ignoreUpdateFields = ['id', 'company_id', 'creator_id', 'creator_name']; // 不允许更新的字段 + + // 1:根据条件更新或创建 + if (!empty($updateCondition)) { + $updateData = array_diff_key($data, array_flip($ignoreUpdateFields)); + $this->builder()->updateOrCreate($updateCondition, $updateData); + + // 为保证查询条件一致,重新构造查询 + $query = $this->builder()->where($updateCondition); + $records = $query->get(); + + $this->queryResult = $records->count() > 1 + ? $records->toArray() + : $records->first()?->toArray(); + + return $this; + } + + // 2:根据主键 ID 更新 + if (!empty($data['id'])) { + $this->keyId = $data['id']; + $query = $this->qInfo($data); + $query->lockForUpdate()->first(); // 获取锁 + + $updateData = array_diff_key($data, array_flip($ignoreUpdateFields)); + + $res = $query->update($updateData); + if (!$res) { + throw new Exception('数据更新失败'); + } + + // 更新后重新查询,避免条件变化导致查询不到 + $this->queryResult = $this->builder()->where('id', $this->keyId)->first()?->toArray(); + return $this; + } + + // 3:创建新记录 + $res = $this->builder()->create($data); + if (!$res) { + throw new Exception('数据新增失败'); + } + + $this->keyId = $res->getKey(); + $this->queryResult = $res->toArray(); + + return $this; + } + + /** + * 返回更新&新增主键. + */ + public function getKey(): int + { + return $this->keyId; + } + + /** + * 返回数据库操作结果. + */ + public function result(): array + { + return $this->queryResult; + } + + /** + * 数据验证 + */ + public function verifyData(Builder $builder, array $params = []): Builder + { + $map = []; + $condition = []; + if (!empty($params['id']) && is_numeric($params['id'])) { + $condition = ['id' => $params['id']]; + } + foreach ($condition as $k => $v) { + $map[] = [$k, '!=', $v]; + } + return clone $builder->where($map); + } + + /** + * 更新状态 + * @throws Exception + */ + public function updateStatus(): null|object + { + $params = $this->request->all(); + $query = $this->qInfo()->lockForUpdate(); + $info = $query->first(); + if ($info['active_status'] == $params['status']) { + throw new Exception('状态不对,请确认'); + } + $query->update(['active_status' => $params['status']]); + return $info; + } + + /*************************************************************************************** + * 构建查询数据条件参数. + * $params = [ + * 'mail_sync_id' => 123, + * 'sn' => ['operator' => '!=', 'value' => 'ABC123'], + * 'aliid' => ['operator' => 'like', 'value' => '%example%'], + * 'serial_number' => ['operator' => '>', 'value' => 100], + * 'ali_model' => 'ModelX', + * 'model' => 'XYZ', + * 'date' => ['operator' => 'between', 'value' => ['2023-01-01', '2023-01-31']], + * 'id' => [ + * ['operator' => '>=', 'value' => 10], + * ['operator' => '<=', 'value' => 100] + * ], + * 'status' => ['operator' => 'in', 'value' => ['active', 'pending']], + * ]; + ************************************************************************************* + * @throws Exception + */ + public static function daoBuildWhere(Builder $builder, array $params, array $fields): Builder + { + if (empty($params)) return $builder; // 如果没有参数,直接返回 + // 用于存储所有 like 条件 + $likeConditions = []; + + foreach ($fields as $field) { + // 跳过空参数 + if (!isset($params[$field]) || $params[$field] === '') { + continue; + } + + $param = $params[$field]; + // 如果参数是数组 + if (is_array($param)) { + // 处理同一个字段的多个条件 + if (isset($param[0]) && is_array($param[0])) { + self::addMultipleConditions($builder, $field, $param); + } else { + // 处理单个条件 + self::handleSingleCondition($builder, $likeConditions, $field, $param); + } + } else { + // 处理字符串条件,字符串条件,强制使用绑定参数 + $builder->where($field, '=', $param); + } + } + + // 应用所有 like 条件 + self::applyLikeConditions($builder, $likeConditions); + + // 添加排序功能 + if (!empty($params['sort_orders'])) { + self::applySortOrders($builder, $params['sort_orders'], $fields); + } + + return $builder; + } + + private static function addMultipleConditions(Builder $builder, string $field, array $conditions): void + { + // 处理同一个字段的多个条件 + $builder->where(/** + * @throws Exception + */ function ($query) use ($field, $conditions) { + foreach ($conditions as $condition) { + // 应用每个条件 + self::applyCondition($query, $field, $condition); + } + }); + } + + private static function handleSingleCondition(Builder $builder, array &$likeConditions, string $field, array $param): void + { + // 收集 like 条件或处理其他单个条件 + if (isset($param['operator']) && strtolower($param['operator']) === 'like') { + // 如果是 like 条件,将其添加到 likeConditions 数组中 + $likeConditions[] = ['field' => $field, 'condition' => $param]; + } else { + // 否则,直接应用条件 + $builder->where( + /** + * @throws Exception + */ function ($query) use ($field, $param) { + self::applyCondition($query, $field, $param); + }); + } + } + + private static function applyLikeConditions(Builder $builder, array $likeConditions): void + { + // 应用所有 like 条件 + if (!empty($likeConditions)) { + $builder->where(function ($query) use ($likeConditions) { + foreach ($likeConditions as $likeCondition) { + if (empty($likeCondition['condition']['value'])) continue; + // 使用 orWhere 添加每个 like 条件 + $query->orWhere($likeCondition['field'], 'like', $likeCondition['condition']['value']); + } + }); + } + } + + /** + * 应用排序功能. + * @param Builder $builder + * @param array $sortOrders + * @param array $fields + * @return void + * @throws Exception + */ + private static function applySortOrders(Builder $builder, array $sortOrders, array $fields): void + { + foreach ($sortOrders as $field => $sortOrder) { + if (!in_array($sortOrder, ['asc', 'desc'])) { + throw new Exception('排序方式不正确'); + } + if (!in_array($field, $fields)) { + throw new Exception('排序字段不正确'); + } + $builder->orderBy($field, $sortOrder); + } + } + + /** + * 应用单个字段的查询条件. + * 调用方式 + * (builder,'name','='|['operate'=>'bett']). + * @throws Exception + */ + private static function applyCondition(Builder &$builder, string $field, mixed $condition): void + { + if (is_array($condition) && isset($condition['operator']) && isset($condition['value'])) { + if (empty($condition['value'])) { + return; + } + + $operator = strtolower($condition['operator']); + if (!in_array($operator, self::$OPERATORS_THAT_SUPPORT_VALUES)) { + throw new Exception('不支持的查询表达式: ' . $condition['operator']); + } + $builder = match ($operator) { + 'between' => $builder->whereBetween($field, $condition['value']), + 'not between' => $builder->whereNotBetween($field, $condition['value']), + 'in' => $builder->whereIn($field, $condition['value']), + 'not in' => $builder->whereNotIn($field, $condition['value']), + 'is null' => $builder->whereNull($field), + 'is not null' => $builder->whereNotNull($field), + 'like' => $builder->orWhere($field, 'like', $condition['value']), + default => $builder->where($field, $operator, $condition['value']), + }; + } else { + $builder->where($field, '=', $condition); + } + } + + /** + * 获取字段列表(公共). + * @param Builder $builder + * @param array $params + * @param array $fields + * @param string|array $addSelect + * @return array + * @throws Exception + */ + public function selectFields(Builder $builder, array $params, array $fields = [], string|array $addSelect = ''): array + { + self::daoBuildWhere($builder, $params, $fields); + + $field = $params['field'] ?? ''; + if (!in_array($field, $fields)) { + throw new Exception('字段参数错误'); + } + + $data = $builder->select(['id', $field]); + if (!empty($addSelect)) { + $data = $data->addSelect($addSelect); + } + return $data->get()->filter(function ($item) use ($field) { + // 过滤空值但不过滤布尔值 + return !empty($item[$field]) || is_bool($item[$field]); + })->unique($field)->values()->toArray(); + } + + /** + * 分页处理函数. + * + * 本函数用于对给定的Builder或Collection对象进行分页处理,并返回分页后的数据及其它相关信息。 + * + * @param Builder|Collection $builder 可以是Eloquent Builder对象或Collection对象 + * @param array $params 包含分页参数的数组,比如页码和每页数量 + * @return array 返回一个包含分页数据、字段配置、过滤条件、表格设置等信息的数组 + * @throws Exception + */ + public function paginate(Builder|Collection $builder, array $params = []): array + { + try { + // 从参数中获取页码和每页数量,未指定则默认值 + $page = empty($params['page']) ? 1 : (int)$params['page']; + $page_size = empty($params['pageSize']) ? 100 : (int)$params['pageSize']; + // 计算跳过的记录数 + $skip = ($page - 1) * $page_size; + // 获取总记录数 + $total = $builder->count(); + // 计算总页数,若记录数为0,则页数为0 + $pageSize = $total == 0 ? 0 : (int)ceil($total / $page_size); + // 根据Builder类型获取分页后的数据 + if ($builder instanceof Collection) { + // 对Collection对象进行分页 + $rows = $builder->values()->slice($skip, $page_size)->values(); + } else { + // 对Builder对象进行分页查询 + $rows = $builder->skip($skip)->take($page_size)->orderBy('id', 'desc')->get(); + } + + // 获取列配置信息 + $columnConfig = $this->getColumnConfig(); + $tableConfig = $this->getTableConfig(); + + return compact( + 'rows', + 'page', + 'total', + 'pageSize', + 'columnConfig', + 'tableConfig' + ); + } catch (Exception $e) { + throw new Exception($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/Dao/Company/CompanyDao.php b/app/Dao/Company/CompanyDao.php new file mode 100644 index 0000000..52232eb --- /dev/null +++ b/app/Dao/Company/CompanyDao.php @@ -0,0 +1,38 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Dao\Company; + +use App\Dao\AbstractDao; +use App\Model\Company; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午6:00 + * Description: CompanyDao类用于提供公司相关的数据访问和操作。它继承自AbstractDao类,并实现了CompanyDao接口。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class CompanyDao extends AbstractDao +{ + public function getModel(): string + { + return Company::class; + } +} \ No newline at end of file diff --git a/app/Dao/Company/FirstCompanyDao.php b/app/Dao/Company/FirstCompanyDao.php new file mode 100644 index 0000000..416f70c --- /dev/null +++ b/app/Dao/Company/FirstCompanyDao.php @@ -0,0 +1,60 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Dao\Company; + +use App\Dao\AbstractDao; +use App\Model\FirstCompany; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午9:25 + * Description: 平台公司数据访问层. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class FirstCompanyDao extends AbstractDao +{ + public function getModel(): string + { + return FirstCompany::class; + } + + public function getFields(): array + { + return [ + 'id', + 'domain', + 'name', + 'full_name', + 'company_type', + 'address', + 'logo', + 'owner', // 公司负责人 + 'id_card', // 法人身份证 + 'mobile', + 'org_code', + 'remark', + 'active_status', + 'activation_date', + 'created_at', + 'updated_at', + ]; + } +} \ No newline at end of file diff --git a/app/Dao/Purchase/PurchaseDao.php b/app/Dao/Purchase/PurchaseDao.php new file mode 100644 index 0000000..b42f52c --- /dev/null +++ b/app/Dao/Purchase/PurchaseDao.php @@ -0,0 +1,38 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Dao\Purchase; + +use App\Dao\AbstractDao; +use App\Model\Purchase; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午5:27 + * Description: 采购单入库单数据访问层. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class PurchaseDao extends AbstractDao +{ + public function getModel(): string + { + return Purchase::class; + } +} \ No newline at end of file diff --git a/app/Exception/ApiException.php b/app/Exception/ApiException.php new file mode 100644 index 0000000..17ad55d --- /dev/null +++ b/app/Exception/ApiException.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Exception; + +use Hyperf\Server\Exception\ServerException; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:19 + * Description: 业务异常 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class ApiException extends ServerException +{ +} \ No newline at end of file diff --git a/app/Exception/BusinessException.php b/app/Exception/BusinessException.php new file mode 100644 index 0000000..043add2 --- /dev/null +++ b/app/Exception/BusinessException.php @@ -0,0 +1,29 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Exception\Handler; + +use App\Exception\ApiException; +use App\Log\Log; +use Hyperf\Context\ApplicationContext; +use Hyperf\ExceptionHandler\ExceptionHandler; +use Hyperf\HttpMessage\Stream\SwooleStream; +use Hyperf\Validation\ValidationException; +use Psr\Http\Message\ResponseInterface; +use Throwable; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午8:54 + * Description: 统一异常处理 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class ApiExceptionHandler extends ExceptionHandler +{ + public function __construct(protected ApplicationContext $context) + { + } + + /** + * 处理异常 + * @param Throwable $throwable + * @param ResponseInterface $response + * @return ResponseInterface + */ + public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface + { + $errorData = $this->getErrorData($throwable); + + // 记录日志 + Log::get('default', 'default')->error($errorData['logMessage']); + + // 阻止异常冒泡 + $this->stopPropagation(); + + return $response->withStatus(200) + ->withHeader('Content-Type', 'application/json') + ->withBody(new SwooleStream(json_encode($errorData['responseData'], JSON_UNESCAPED_UNICODE))); + } + + public function isValid(Throwable $throwable): bool + { + return $throwable instanceof ApiException || $throwable instanceof ValidationException; + } + + /** + * 获取错误. + */ + protected function getErrorData(Throwable $throwable): array + { + $code = $throwable->getCode(); + $errorFile = $throwable->getFile(); + $errorLine = $throwable->getLine(); + $errorMessage = $throwable->getMessage(); + + if ($throwable instanceof ValidationException) { + $errors = $throwable->validator->errors()->toArray(); + $errorMessage = reset($errors)[0]; + } + + $responseData = [ + 'code' => $code, + 'message' => $errorMessage, + ]; + + $logMessage = sprintf('%s %s %s %s', $code, $errorFile, $errorLine, $errorMessage); + + return ['responseData' => $responseData, 'logMessage' => $logMessage]; + } +} \ No newline at end of file diff --git a/app/Exception/Handler/AppExceptionHandler.php b/app/Exception/Handler/AppExceptionHandler.php new file mode 100644 index 0000000..889c5d4 --- /dev/null +++ b/app/Exception/Handler/AppExceptionHandler.php @@ -0,0 +1,97 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class AppExceptionHandler extends ExceptionHandler +{ + public function __construct(protected StdoutLoggerInterface $logger) + { + } + + public function handle(Throwable $throwable, ResponseInterface $response): MessageInterface|ResponseInterface + { + $this->logException($throwable); + + if ($throwable instanceof RateLimitException) { + return $this->handleRateLimitException($response); + } + + return $this->handleOtherExceptions($throwable, $response); + } + + public function isValid(Throwable $throwable): bool + { + return ! $throwable instanceof ApiException; + } + + protected function createResponseBody($message, $code): StreamInterface + { + $data = [ + 'code' => $code, + 'message' => $message, + ]; + return new SwooleStream(json_encode($data, JSON_UNESCAPED_UNICODE)); + } + + protected function logException(Throwable $throwable): void + { + $this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile())); + $this->logger->error($throwable->getTraceAsString()); + } + + protected function handleRateLimitException(ResponseInterface $response): ResponseInterface + { + $message = '触发请求频率限流规则'; + return $response->withStatus(429) + ->withHeader('Content-Type', 'application/json') + ->withBody($this->createResponseBody($message, 429)); + } + + protected function handleOtherExceptions(Throwable $throwable, ResponseInterface $response): ResponseInterface + { + $message = $throwable->getMessage(); + + if (env('APP_ENV') === 'production' && ! $throwable instanceof ValidationException) { + return $response->withStatus(200) + ->withHeader('Content-Type', 'application/json') + ->withBody($this->createResponseBody($message, 0)); + } + + return $response->withHeader('Server', 'mes-auto') + ->withStatus(200) + ->withBody($this->createResponseBody($message, 0)); + } +} diff --git a/app/Job/BaseJob.php b/app/Job/BaseJob.php new file mode 100644 index 0000000..13f2ae0 --- /dev/null +++ b/app/Job/BaseJob.php @@ -0,0 +1,83 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Job; + +use App\Context\QueueContext; +use App\Log\Log; +use Exception; +use Hyperf\AsyncQueue\Job; +use Hyperf\DbConnection\Db; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午10:57 + * Description: Job基础任务类. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +abstract class BaseJob extends Job +{ + public function __construct(public array $data) + { + } + + public function handle(): void + { + // 设置用户信息上下文信息 + if (!empty($user = $this->data['user'])) { + QueueContext::setUser($user); + } + + if (!empty($company = $this->data['company'])) { + QueueContext::setCompanyInfo($company); + } + + // 运行业务逻辑, 总是在事务中执行,保证事务的原子性 + Db::beginTransaction(); + try { + $this->process(); + + Db::commit(); + } catch (Exception $e) { + Db::rollBack(); + $this->logError($e); + } + } + + /** + * 子类必须实现的业务逻辑处理方法 + */ + abstract protected function process(): void; + + /** + * 日志记录,可按需扩展日志通道 + */ + protected function logError(Exception $e): void + { + Log::get('queue', 'queue')->error(sprintf( + "[%s] %s in %s:%d\n%s", + static::class, + $e->getMessage(), + $e->getFile(), + $e->getLine(), + $e->getTraceAsString() + )); + } +} \ No newline at end of file diff --git a/app/Job/ColumnConfigJob.php b/app/Job/ColumnConfigJob.php new file mode 100755 index 0000000..3584c55 --- /dev/null +++ b/app/Job/ColumnConfigJob.php @@ -0,0 +1,141 @@ + $user, 'method' => $method, 'params' => $params] = $this->data; + + // 提交了保存列配置 + if (!isset($params['save_column'])) return; + if ($params['save_column'] === false) { + $this->deleteColumnConfig($user, $method); + return; + } + + // 获取默认配置, 没有配置则不处理 + $configList = config('column_config.' . $method) ?? []; + if (empty($configList)) return; + + $submitConfig = $params['column_config']; + $submittedMap = collect($submitConfig)->keyBy('prop')->toArray(); + + $parallel = new Parallel(); + + foreach ($configList as $key => $value) { + $parallel->add(function () use ($key, $value, $submittedMap, $user) { + $value['sort'] = $key + 1; + + // 存在前端提交的列 + if (isset($submittedMap[$value['prop']])) { + $merged = array_merge([ + 'condition' => 'like', + 'search_type' => 'text', + 'is_search' => 1, + 'sortable' => 0, + ], $value, $submittedMap[$value['prop']]); + + return $this->prepareConfig($merged, $user); + } + + // 否则删除该列配置 + ColumnConfig::query()->withoutGlobalScope(CompanyScope::class) + ->where([ + 'prop' => $value['prop'], + 'method' => $this->data['method'], + 'creator_id' => $user['id'], + ]) + ->forceDelete(); + + return null; + }); + } + + // 执行并获取所有结果 + $results = $parallel->wait(); + + // 过滤非 null 的更新数据 + $updates = array_filter($results); + + if (!empty($updates)) { + $this->updateOrCreateColumnConfigs($updates, $method, $user); + } + } + + /** + * 更新或创建列配置. + */ + private function updateOrCreateColumnConfigs(array $configs, string $method, array $creator): void + { + // 默认配置key值 + $defaultKeys = (new ColumnConfig())->getFillable(); + + // 删除$configs里不存在$defaultKeys里的字段,防止前端传递的额外字段导致更新失败 + $configs = array_map(function ($config) use ($defaultKeys) { + $newConfig = array_intersect_key($config, array_flip($defaultKeys)); + $newConfig['sort'] = $config['sort'] ?? 0; + return $newConfig; + }, $configs); + + // 添加公共字段 + foreach ($configs as &$config) { + $config['company_id'] = $creator['company_id'] ?? 0; + $config['method'] = $method; + $config['creator_id'] = $creator['id']; + $config['creator_name'] = $creator['name']; + $config['created_at'] = $config['updated_at'] = time(); + } + unset($config); + + $updateKeys = array_keys($configs[0]); + // 删除不需要更新的字段 + unset( + $updateKeys[array_search('creator_name', $updateKeys, true)], + $updateKeys[array_search('prop', $updateKeys, true)], + $updateKeys[array_search('method', $updateKeys, true)], + $updateKeys[array_search('creator_id', $updateKeys, true)], + ); + + // 批量插入或更新 + ColumnConfig::query()->withoutGlobalScope(CompanyScope::class) + ->upsert($configs, ['prop', 'method', 'creator_id'], array_values($updateKeys)); + } + + /** + * 删除列配置. + */ + private function deleteColumnConfig(array $user, string $method): void + { + ColumnConfig::query()->withoutGlobalScope(CompanyScope::class) + ->where(['method' => $method, 'creator_id' => $user['id']]) + ->forceDelete(); + } + + private function prepareConfig(array $config, array $user): array + { + return array_merge($config, [ + 'company_id' => $user['company_id'] ?? 0, + 'creator_id' => $user['id'], + 'creator_name' => $user['name'], + ]); + } +} diff --git a/app/Job/OpLogsJob.php b/app/Job/OpLogsJob.php new file mode 100755 index 0000000..a9f948b --- /dev/null +++ b/app/Job/OpLogsJob.php @@ -0,0 +1,87 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class OpLogsJob extends BaseJob +{ + /** + * 处理日志记录逻辑。 + * 该方法首先尝试获取日志操作信息,如果信息不为空,则根据这些信息填充操作日志数组, + * 包括日志类型、标题、计时器以及来源信息。随后,它将尝试获取当前用户信息,并最后创建操作日志记录。 + * + * @return void 该方法没有返回值。 + * @throws Exception + */ + protected function process(): void + { + // 尝试获取日志操作信息 + $logAction = $this->getLogAction(); + // 如果日志操作信息为空,则直接返回,不进行后续操作 + if ($logAction->isEmpty()) { + return; + } + + $rpcResult = make(EasyAppServiceInterface::class)->getClientIPInfo(['ip' => $this->data['ip']]); + + // 构建请求日志消息 + $clientIPInfo = $rpcResult['result']['ip_info'] ?? ''; + + // 从日志操作信息中提取日志类型,并保存到操作日志数组中 + $type = $logAction->first()['id'] ?? 0; + $this->data['type'] = $type; + // 同样从日志操作信息中提取日志标题,并保存 + $this->data['log_title'] = $logAction->first()['name'] ?? ''; + // 初始化计时器 + $this->data['timer'] = 0; + // 设置日志来源,优先使用已存在的来源信息,如果不存在,则尝试从路由前缀获取来源信息 + $this->data['source'] = $this->data['source'] ?: $this->getRoutePrefix(); + // 查询IP属地,并保存到操作日志数组中 + $this->data['location'] = $clientIPInfo; + + // 创建操作日志记录 + OperatorLogs::query()->create($this->data); + } + + + private function getLogAction(): Collection + { + $defineLogs = config('op_logs'); + return collect($defineLogs)->where('action', '=', $this->data['action']); + } + + /** + * 获取路由前缀. + */ + private function getRoutePrefix(): int + { + $arr = explode('/', $this->data['route']); + $res = $arr[0] ?? ''; + return match ($res) { + 'api' => SourceConst::SOURCE_PC, + 'mobile' => SourceConst::SOURCE_MOBILE, + default => 0, + }; + } +} diff --git a/app/Job/RequestWriteLogsJob.php b/app/Job/RequestWriteLogsJob.php new file mode 100644 index 0000000..2dbb96b --- /dev/null +++ b/app/Job/RequestWriteLogsJob.php @@ -0,0 +1,54 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class RequestWriteLogsJob extends BaseJob +{ + protected function process(): void + { + $params = $this->data['params']; // 提取请求参数 + + // 从参数中删除敏感信息 + foreach ($params as $key => $value) { + if (in_array($key, ['password', 'pwd', 'pwd_conf', 'original_pwd'])) { + unset($params[$key]); + } + } + + $rpcResult = make(EasyAppServiceInterface::class)->getClientIPInfo([ + 'ip' => $this->data['client_ip'] + ]); + + $clientIPInfo = $rpcResult['result']['ip_info'] ?? ''; + + $logMessage = sprintf('%s %s %s', + $this->data['client_ip'] . ' ' . $clientIPInfo, + $this->data['method'], + $this->data['uri'] + ); + if (!empty($params)) { + $logMessage .= ' params: ' . json_encode($params, JSON_UNESCAPED_UNICODE); + } + + // 记录日志 + $log = Log::get('request', 'request'); + $log->info($logMessage); + } +} diff --git a/app/JsonRpc/EasyAppServiceConsumer.php b/app/JsonRpc/EasyAppServiceConsumer.php new file mode 100644 index 0000000..b9a34d3 --- /dev/null +++ b/app/JsonRpc/EasyAppServiceConsumer.php @@ -0,0 +1,37 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +use Hyperf\RpcClient\AbstractServiceClient; + +class EasyAppServiceConsumer extends AbstractServiceClient implements EasyAppServiceInterface +{ + // 定义对应服务提供者的服务名 + protected string $serviceName = 'EasyAppService'; + + // 定义对应服务提供者的服务协议 + protected string $protocol = 'jsonrpc-http'; + + /** + * 获取客户端IP信息 + * @param array $params + * @return array + */ + public function getClientIpInfo(array $params): array + { + return $this->__request(__FUNCTION__, $params); + } +} \ No newline at end of file diff --git a/app/JsonRpc/EasyAppServiceInterface.php b/app/JsonRpc/EasyAppServiceInterface.php new file mode 100644 index 0000000..d2411a7 --- /dev/null +++ b/app/JsonRpc/EasyAppServiceInterface.php @@ -0,0 +1,26 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +interface EasyAppServiceInterface +{ + /** + * 获取客户端IP信息 + * @param array $params + * @return array + */ + public function getClientIpInfo(array $params): array; +} \ No newline at end of file diff --git a/app/JsonRpc/InventoryServiceConsumer.php b/app/JsonRpc/InventoryServiceConsumer.php new file mode 100644 index 0000000..c2db2d8 --- /dev/null +++ b/app/JsonRpc/InventoryServiceConsumer.php @@ -0,0 +1,33 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +use Hyperf\RpcClient\AbstractServiceClient; + +class InventoryServiceConsumer extends AbstractServiceClient implements InventoryServiceInterface +{ + protected string $serviceName = 'InventoryService'; + + protected string $protocol = 'jsonrpc-http'; + + /** + * 新增库存-手动单条. + */ + public function addInventory(array $data): void + { + $this->__request(__FUNCTION__, $data); + } +} \ No newline at end of file diff --git a/app/JsonRpc/InventoryServiceInterface.php b/app/JsonRpc/InventoryServiceInterface.php new file mode 100644 index 0000000..9920dc4 --- /dev/null +++ b/app/JsonRpc/InventoryServiceInterface.php @@ -0,0 +1,26 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +interface InventoryServiceInterface +{ + /** + * 新增库存-手动单条. + * @param array $data + * @return void + */ + public function addInventory(array $data): void; +} \ No newline at end of file diff --git a/app/JsonRpc/UserAuthServiceConsumer.php b/app/JsonRpc/UserAuthServiceConsumer.php new file mode 100644 index 0000000..45fbcc6 --- /dev/null +++ b/app/JsonRpc/UserAuthServiceConsumer.php @@ -0,0 +1,86 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +use Hyperf\RpcClient\AbstractServiceClient; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午8:37 + * Description: 用户服务。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class UserAuthServiceConsumer extends AbstractServiceClient implements UserAuthServiceInterface +{ + protected string $serviceName = 'UserAuthService'; + + protected string $protocol = 'jsonrpc-http'; + + /** + * 用户登录 + * @param array $data + * @return array + */ + public function userLogin(array $data): array + { + return $this->__request(__FUNCTION__, $data); + } + + /** + * 添加用户. + * @param array $data + * @return void + */ + public function addUser(array $data): void + { + $this->__request(__FUNCTION__, $data); + } + + /** + * 获取用户信息 + * @param array $data + * @return array + */ + public function userInfoByToken(array $data): array + { + return $this->__request(__FUNCTION__, $data); + } + + /** + * 添加角色. + * @param array $data + * @return void + */ + public function addRole(array $data): void + { + $this->__request(__FUNCTION__, $data); + } + + /** + * 获取用户列表. + * @param array $data + * @return array + */ + public function userList(array $data): array + { + return $this->__request(__FUNCTION__, $data); + } +} \ No newline at end of file diff --git a/app/JsonRpc/UserAuthServiceInterface.php b/app/JsonRpc/UserAuthServiceInterface.php new file mode 100644 index 0000000..cf681fe --- /dev/null +++ b/app/JsonRpc/UserAuthServiceInterface.php @@ -0,0 +1,52 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\JsonRpc; + +interface UserAuthServiceInterface +{ + /** + * 用户登录 + * @param array $data + * @return array + */ + public function userLogin(array $data): array; + + /** + * 新增用户. + */ + public function addUser(array $data): void; + + /** + * 获取用户信息 + * @param array $data + * @return array + */ + public function userInfoByToken(array $data): array; + + /** + * 添加角色. + * @param array $data + * @return void + */ + public function addRole(array $data): void; + + /** + * 获取用户列表. + * @param array $data + * @return array + */ + public function userList(array $data): array; +} \ No newline at end of file diff --git a/app/Listener/AutoMainFieldsListener.php b/app/Listener/AutoMainFieldsListener.php new file mode 100755 index 0000000..1097b72 --- /dev/null +++ b/app/Listener/AutoMainFieldsListener.php @@ -0,0 +1,72 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +#[Listener] +class AutoMainFieldsListener implements ListenerInterface +{ + public function __construct(protected ContainerInterface $container) + { + } + + public function listen(): array + { + return [ + Creating::class, + Saving::class, + ]; + } + + public function process(object $event): void + { + /** + * 在模型创建或保存事件中,自动设置模型的company_id和creator_id等相关字段。 + * 这个逻辑只在用户上下文存在,且事件为Creating或Saving时触发。 + * + * @param object $event 事件对象,预期为Creating或Saving事件之一。 + * @return void + */ + + $user = QueueContext::getUser() ?? UserContext::getCurrentUser(); + $company = $user['company'] ?? []; + + $model = $event->getModel(); + // 判断事件类型是否符合条件,以及用户上下文是否存在 + if (!($event instanceof Creating || $event instanceof Saving) || !$user) { + return; + } + $schema = $model->getConnection()->getSchemaBuilder(); + + // 检查模型表是否有company_id字段,若有,则设置company_id + if ($schema->hasColumn($model->getTable(), 'company_id')) { + $model->company_id = $model->company_id ?? $company['id'] ?? 0; + } + + // 检查模型表是否有creator_id和creator_name字段,若有,则设置对应的值 + if ($schema->hasColumn($model->getTable(), 'creator_id')) { + $model->creator_id ??= $user['id']; + $model->creator_name ??= $user['name'] ?? ''; + } + } +} diff --git a/app/Listener/DbQueryExecutedListener.php b/app/Listener/DbQueryExecutedListener.php new file mode 100644 index 0000000..b7666ab --- /dev/null +++ b/app/Listener/DbQueryExecutedListener.php @@ -0,0 +1,80 @@ +logger = $container->get(LoggerFactory::class)->get('sql', 'sql'); + } + + public function listen(): array + { + return [ + QueryExecuted::class, + ]; + } + + /** + * @param object $event + */ + public function process(object $event): void + { + /** + * 处理QueryExecuted事件,记录查询的SQL和执行时间。 + * + * @param QueryExecuted $event 该事件对象包含执行的SQL语句、绑定参数和执行时间 + */ + if ($event instanceof QueryExecuted) { + $sql = $event->sql; // 获取执行的SQL语句 + + // 检查绑定参数是否为关联数组,如果不是,将 "?" 替换为实际的参数值 + if (!Arr::isAssoc($event->bindings)) { + $position = 0; // 初始化绑定参数的搜索位置 + foreach ($event->bindings as $value) { // 遍历绑定参数 + $position = strpos($sql, '?', $position); // 查找下一个 "?" 位置 + if ($position === false) { // 如果找不到 "?",则退出循环 + break; + } + $value = "'$value'"; // 将参数值包裹在单引号中 + $sql = substr_replace($sql, $value, $position, 1); // 替换 "?" 为实际参数值 + $position += strlen($value); // 更新搜索位置 + } + } + + // 使用logger记录SQL语句和执行时间 + $this->logger->info(sprintf('[%s] %s', $event->time, $sql)); + } + } +} diff --git a/app/Listener/QueueHandleListener.php b/app/Listener/QueueHandleListener.php new file mode 100644 index 0000000..9e250ba --- /dev/null +++ b/app/Listener/QueueHandleListener.php @@ -0,0 +1,74 @@ +logger = $container->get(LoggerFactory::class)->get('queue'); + } + + public function listen(): array + { + return [ + AfterHandle::class, + BeforeHandle::class, + FailedHandle::class, + RetryHandle::class, + ]; + } + + public function process(object $event): void + { + if ($event instanceof Event && $event->getMessage()->job()) { + $job = $event->getMessage()->job(); + $jobClass = get_class($job); + if ($job instanceof AnnotationJob) { + $jobClass = sprintf('Job[%s@%s]', $job->class, $job->method); + } + $date = date('Y-m-d H:i:s'); + + switch (true) { + case $event instanceof BeforeHandle: + $this->logger->info(sprintf('[%s] Processing %s.', $date, $jobClass)); + break; + case $event instanceof AfterHandle: + $this->logger->info(sprintf('[%s] Processed %s.', $date, $jobClass)); + break; + case $event instanceof FailedHandle: + $this->logger->error(sprintf('[%s] Failed %s.', $date, $jobClass)); + $this->logger->error((string) $event->getThrowable()); + break; + case $event instanceof RetryHandle: + $this->logger->warning(sprintf('[%s] Retried %s.', $date, $jobClass)); + break; + } + } + } +} diff --git a/app/Listener/ResumeExitCoordinatorListener.php b/app/Listener/ResumeExitCoordinatorListener.php new file mode 100644 index 0000000..eff2e0b --- /dev/null +++ b/app/Listener/ResumeExitCoordinatorListener.php @@ -0,0 +1,35 @@ +resume(); + } +} diff --git a/app/Log/AliSlsHandler.php b/app/Log/AliSlsHandler.php new file mode 100644 index 0000000..b7742ca --- /dev/null +++ b/app/Log/AliSlsHandler.php @@ -0,0 +1,46 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Log; + +use App\Amqp\Producer\AliSlsProducer; +use Hyperf\Amqp\Producer; +use Hyperf\Di\Annotation\Inject; +use Monolog\Handler\AbstractProcessingHandler; +use Monolog\LogRecord; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:19 + * Description: 阿里云日志服务处理器. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class AliSlsHandler extends AbstractProcessingHandler +{ + #[Inject] + protected Producer $producer; + + protected function write(LogRecord $record): void + { + $logs = ['channel' => $record['channel'] ?? '', 'formatted' => $record['formatted'] ?? '']; + $message = new AliSlsProducer($logs); + $this->producer->produce($message, true); + } +} \ No newline at end of file diff --git a/app/Log/AppendRequestIdProcessor.php b/app/Log/AppendRequestIdProcessor.php new file mode 100644 index 0000000..93100d3 --- /dev/null +++ b/app/Log/AppendRequestIdProcessor.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Log; + +use Hyperf\Context\Context; +use Hyperf\Coroutine\Coroutine; +use Monolog\LogRecord; +use Monolog\Processor\ProcessorInterface; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:19 + * Description: 添加请求ID和协程ID + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class AppendRequestIdProcessor implements ProcessorInterface +{ + public const string REQUEST_ID = 'log.request.id'; + + public function __invoke(LogRecord $record): array|LogRecord + { + $record['extra']['request_id'] = Context::getOrSet(self::REQUEST_ID, uniqid('xw_cloud')); + $record['extra']['coroutine_id'] = Coroutine::id(); + return $record; + } +} \ No newline at end of file diff --git a/app/Log/Log.php b/app/Log/Log.php new file mode 100644 index 0000000..03f9c4d --- /dev/null +++ b/app/Log/Log.php @@ -0,0 +1,62 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Log; + +use App\Exception\ApiException; +use Hyperf\Context\ApplicationContext; +use Hyperf\Di\Annotation\Inject; +use Hyperf\Logger\LoggerFactory; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; +use function Hyperf\Support\make; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:19 + * Description: 日志记录器类。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class Log +{ + #[Inject] + protected LoggerInterface $logger; + + /** + * 根据提供的名称和分组获取日志记录器实例。 + * + * @param string $name 日志记录器的名称,默认为'app'。 + * @param string $group 日志记录器的分组,默认为'job'。 + * @return LoggerInterface 返回一个日志记录器实例。 + */ + public static function get(string $name = 'app', string $group = 'job'): LoggerInterface + { + try { + // 尝试从应用上下文容器中获取LoggerFactory实例,并进一步获取指定名称和分组的日志记录器 + return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name, $group); + } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { + // 如果在获取过程中发生异常,使用默认的日志记录器记录错误信息,并抛出ApiException + $logs = make(LoggerFactory::class)->get('default'); + $logs->error($e->getMessage()); + throw new ApiException($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/Log/StdoutLoggerFactory.php b/app/Log/StdoutLoggerFactory.php new file mode 100644 index 0000000..12185b1 --- /dev/null +++ b/app/Log/StdoutLoggerFactory.php @@ -0,0 +1,48 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Log; + +use Hyperf\Context\ApplicationContext; +use Hyperf\Logger\LoggerFactory; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午6:04 + * Description: 创建一个日志记录器 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class StdoutLoggerFactory +{ + /** + * @param ContainerInterface $container + * @return LoggerInterface + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function __invoke(ContainerInterface $container): LoggerInterface + { + return ApplicationContext::getContainer()->get(LoggerFactory::class)->get(); + } +} \ No newline at end of file diff --git a/app/Middleware/CheckTokenMiddleware.php b/app/Middleware/CheckTokenMiddleware.php new file mode 100644 index 0000000..2681cf6 --- /dev/null +++ b/app/Middleware/CheckTokenMiddleware.php @@ -0,0 +1,77 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Middleware; + +use App\Context\UserContext; +use App\Exception\ApiException; +use App\JsonRpc\UserAuthServiceInterface; +use App\Repository\Company\FirstCompanyRepository; +use Exception; +use Hyperf\Di\Annotation\Inject; +use Psr\Container\ContainerInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface; + +/** + * Author: ykxiao + * Date: 2025/6/4 + * Time: 下午2:43 + * Description: 验证Token中间件. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class CheckTokenMiddleware implements MiddlewareInterface +{ + #[Inject] + protected UserAuthServiceInterface $userAuthServiceInterface; + + public function __construct(protected ContainerInterface $container) + { + } + + /** + * @throws Exception + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $token = $this->extractToken($request); + + $rpcResult = $this->userAuthServiceInterface->userInfoByToken(['token' => $token]); + + $userInfo = $rpcResult['result']['user'] ?? []; + if (!$userInfo) { + throw new ApiException('用户信息不存在', 401); + } + + UserContext::setCurrentUser($userInfo); + + return $handler->handle($request); + } + + protected function extractToken(ServerRequestInterface $request): string + { + $authorizationHeader = $request->getHeaderLine('Authorization') ?? ''; + if (!$authorizationHeader) { + throw new ApiException('授权标头无效', 401); + } + return str_starts_with($authorizationHeader, 'Bearer ') ? substr($authorizationHeader, 7) : ''; + } +} \ No newline at end of file diff --git a/app/Middleware/RequestLogsMiddleware.php b/app/Middleware/RequestLogsMiddleware.php new file mode 100644 index 0000000..a79255c --- /dev/null +++ b/app/Middleware/RequestLogsMiddleware.php @@ -0,0 +1,70 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Middleware; + +use App\Service\QueueService; +use App\Service\SysService; +use Hyperf\Di\Annotation\Inject; +use Psr\Container\ContainerInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午10:44 + * Description: 请求日志中间件 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class RequestLogsMiddleware implements MiddlewareInterface +{ + #[Inject] + protected QueueService $queueService; + + #[Inject] + protected SysService $sysService; + + public function __construct(protected ContainerInterface $container) + { + } + + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $method = $request->getMethod(); // 请求方法 + $uri = $request->getUri()->getPath(); // 请求的URI路径 + $params = $request->getMethod() === 'POST' ? $request->getParsedBody() : $request->getQueryParams(); + + $clientIp = $this->sysService->getClientIpInfo($request); + + $data = [ + 'params' => $params, + 'method' => $method, + 'uri' => $uri, + 'client_ip' => $clientIp, + ]; + + // 添加请求日志,存储到队列中 + $this->queueService->make($data)->writeRequestLogs(); + + return $handler->handle($request); + } +} \ No newline at end of file diff --git a/app/Model/ColumnConfig.php b/app/Model/ColumnConfig.php new file mode 100755 index 0000000..794ee20 --- /dev/null +++ b/app/Model/ColumnConfig.php @@ -0,0 +1,49 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +class ColumnConfig extends Model +{ + protected ?string $table = 'column_config'; + + protected array $fillable = [ + 'company_id', + 'method', + 'prop', + 'label', + 'sortable', + 'sort', + 'width', + 'hide', + 'fix', + 'filter', + 'is_search', + 'search_type', + 'condition', + 'creator_id', + 'creator_name', + ]; + + protected array $casts = [ + 'created_at' => 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + 'sortable' => 'boolean', + 'hide' => 'boolean', + 'fix' => 'boolean', + 'filter' => 'boolean', + 'is_search' => 'boolean', + ]; +} \ No newline at end of file diff --git a/app/Model/Company.php b/app/Model/Company.php new file mode 100644 index 0000000..4436d54 --- /dev/null +++ b/app/Model/Company.php @@ -0,0 +1,27 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +class Company extends Model +{ + protected ?string $table = 'company'; + + protected array $fillable = [ + 'company_type', + 'name', + 'status', + ]; +} \ No newline at end of file diff --git a/app/Model/FirstCompany.php b/app/Model/FirstCompany.php new file mode 100644 index 0000000..a3cb0e8 --- /dev/null +++ b/app/Model/FirstCompany.php @@ -0,0 +1,37 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +class FirstCompany extends Model +{ + protected ?string $table = 'first_company'; + + protected array $fillable = [ + 'domain', + 'name', + 'full_name', + 'company_type', + 'address', + 'logo', + 'owner', // 公司负责人 + 'id_card', // 法人身份证 + 'mobile', + 'org_code', + 'remark', + 'active_status', + 'activation_date', + ]; +} \ No newline at end of file diff --git a/app/Model/Model.php b/app/Model/Model.php new file mode 100644 index 0000000..0afaf93 --- /dev/null +++ b/app/Model/Model.php @@ -0,0 +1,27 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +use Hyperf\Database\Model\Builder; +use Hyperf\Database\Model\SoftDeletingScope; + +class OperatorLogs extends Model +{ + protected ?string $table = 'operator_logs'; + + protected array $fillable = [ + 'company_id', + 'location', + 'type', + 'log_title', + 'route', + 'params', + 'ip', + 'source', + 'timer', + 'agent', + 'remark', + 'creator_id', + 'creator_name', + ]; + + protected array $casts = [ + 'created_at' => 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + 'params' => 'json', + ]; + + public function setIpAttribute(mixed $value): void + { + $this->attributes['ip'] = sprintf('%u', ip2long($value)); + } + + public function getIpAttribute(mixed $value): string + { + return long2ip($value); + } + + // 忽略软删除 + public function newQuery(bool $cache = false): Builder + { + $builder = parent::newQuery(); + return $builder->withoutGlobalScope(SoftDeletingScope::class); + } +} \ No newline at end of file diff --git a/app/Model/Purchase.php b/app/Model/Purchase.php new file mode 100644 index 0000000..d5a7534 --- /dev/null +++ b/app/Model/Purchase.php @@ -0,0 +1,43 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +class Purchase extends Model +{ + protected ?string $table = 'purchase'; + + protected array $fillable = [ + 'purchase_sn', + 'warehouse_ids', + 'contract_sn', + 'purchase_time', + 'customer_type', + 'container_type', + 'container_count', + 'original_count', + 'original_cube', + 'receiving_container', + 'receiving_count', + 'receiving_cube', + 'kz_company_id', + 'kz_company_name', + 'sh_company_id', + 'sh_company_name', + 'remark', + 'is_from_erp', + 'erp_return_id', + ]; +} \ No newline at end of file diff --git a/app/Model/TableConfig.php b/app/Model/TableConfig.php new file mode 100755 index 0000000..419a5ad --- /dev/null +++ b/app/Model/TableConfig.php @@ -0,0 +1,34 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Model; + +class TableConfig extends Model +{ + protected ?string $table = 'table_config'; + + protected array $fillable = [ + 'company_id', + 'method', + 'size', + 'config', + ]; + + protected array $casts = [ + 'created_at' => 'datetime:Y-m-d H:i:s', + 'updated_at' => 'datetime:Y-m-d H:i:s', + 'config' => 'json', + ]; +} \ No newline at end of file diff --git a/app/Process/AsyncQueueConsumer.php b/app/Process/AsyncQueueConsumer.php new file mode 100644 index 0000000..2f6af52 --- /dev/null +++ b/app/Process/AsyncQueueConsumer.php @@ -0,0 +1,21 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); +/** + * This file is part of Hyperf. + * + * @link https://www.hyperf.io + * @document https://hyperf.wiki + * @contact group@hyperf.io + * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + */ + +namespace App\Repository; + +use App\Service\Trait\ColumnConfigTrait; + +/** + * Author: ykxiao + * Date: 2024/12/24 + * Time: 下午3:06 + * Description: BaseRepository类用于提供一个基本的仓库模式实现。它包含一个DAO(数据访问对象)属性,并允许通过魔术方法动态调用DAO上的方法。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class AbstractRepository +{ + use ColumnConfigTrait; + + /** + * 存储数据访问对象的属性。 + * @var string + */ + protected mixed $dao; + + /** + * 当尝试调用不存在的实例方法时,自动调用此方法。 + * 允许通过对象的动态方法调用DAO上的相应方法。 + * @param string $name 被调用的方法名 + * @param array $arguments 被调用方法的参数数组 + * @return mixed 返回DAO方法的执行结果 + */ + public function __call(string $name, array $arguments) + { + // 动态调用DAO上的方法。 + return call_user_func_array([$this->dao, $name], $arguments); + } + + /** + * 设置DAO对象。 + * 用于设置存储数据访问对象的属性。 + * @param string $dao 数据访问对象的实例 + */ + public function setDao(string $dao): void + { + $this->dao = $dao; + } +} diff --git a/app/Repository/Company/CompanyRepository.php b/app/Repository/Company/CompanyRepository.php new file mode 100644 index 0000000..7a08e20 --- /dev/null +++ b/app/Repository/Company/CompanyRepository.php @@ -0,0 +1,87 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Repository\Company; + +use App\Dao\Company\CompanyDao; +use App\Repository\AbstractRepository; +use Exception; +use function Hyperf\Collection\collect; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午6:01 + * Description: CompanyRepository类用于提供公司相关的数据访问和操作。它继承自AbstractRepository类,并实现了CompanyDao接口。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class CompanyRepository extends AbstractRepository +{ + public function __construct(CompanyDao $dao) + { + $this->dao = $dao; + } + + /** + * 添加公司。 + * @param array $data + * @return void + * @throws Exception + */ + public function add(array $data): void + { + $count = $this->dao->builder(); + if (!empty($data['id'])) { + $count->where('id', '!=', $data['id']); + } + + // 重复验证邮箱和手机号码 + $make = $this->dao->make(); + $verify = $make->verifyData(clone $count); + $collect = clone collect($verify->get()); + + $errors = []; + if ($collect->where('name', '=', $data['name'])->isNotEmpty()) { + $errors[] = '公司名称已存在'; + } + if (!empty($errors)) { + throw new Exception(implode(',', $errors)); + } + + $this->dao->commonCreate($this->paramsData($data)); + } + + /** + * 处理参数数据。 + * @param array $params + * @return array + */ + private function paramsData(array $params): array + { + if (empty($params['id'])) { + return $params; + } + return [ + 'id' => $params['id'], + 'company_type' => $params['company_type'], // 公司类别:1开证 2收货 + 'name' => $params['name'], // 公司名称 + 'status' => $params['status'] // 状态:0禁用 1启用 + ]; + } +} \ No newline at end of file diff --git a/app/Repository/Company/FirstCompanyRepository.php b/app/Repository/Company/FirstCompanyRepository.php new file mode 100644 index 0000000..61dccb7 --- /dev/null +++ b/app/Repository/Company/FirstCompanyRepository.php @@ -0,0 +1,111 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Repository\Company; + +use App\Dao\Company\FirstCompanyDao; +use App\Repository\AbstractRepository; +use Carbon\Carbon; +use Exception; +use function Hyperf\Collection\collect; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午9:26 + * Description: 平台公司数据仓库类. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class FirstCompanyRepository extends AbstractRepository +{ + public function __construct(FirstCompanyDao $dao) + { + $this->dao = $dao; + } + + /** + * 新增公司. + * @throws Exception + */ + public function addCompany(array $data): void + { + $count = $this->dao->builder(); + + // 重复字段验证 + $make = $this->dao->make(); + $verify = $make->verifyData(clone $count, $data); + $collect = clone collect($verify->get()); + + $errors = []; + if ($collect->where('name', '=', $data['name'])->isNotEmpty()) { + $errors[] = '公司简称已存在'; + } + if ($collect->where('full_name', '=', $data['full_name'])->isNotEmpty()) { + $errors[] = '公司全称已存在'; + } + if ($collect->where('mobile', '=', $data['mobile'])->isNotEmpty()) { + $errors[] = '负责人手机已存在'; + } + if (!empty($errors)) { + throw new Exception(implode(',', $errors)); + } + + $this->dao->commonCreate($this->paramsData($data)); + } + + /** + * 参数处理. + */ + private function paramsData(array $params): array + { + if (empty($params['id'])) { + return $params; + } + + return [ + 'id' => $params['id'], + 'domain' => $params['domain'], + 'name' => $params['name'], + 'full_name' => $params['full_name'], + 'company_type' => $params['company_type'], + 'address' => $params['address'] ?? '', + 'logo' => $params['logo'] ?? '', + 'owner' => $params['owner'] ?? '', // 公司负责人 + 'id_card' => $params['id_card'] ?? '', // 法人身份证 + 'mobile' => $params['mobile'], + 'org_code' => $params['org_code'] ?? '', + 'remark' => $params['remark'] ?? '', + 'active_status' => $params['active_status'], + 'activation_date' => Carbon::parse($params['activation_date'])->timestamp, + ]; + } + + /** + * 根据公司全称获取公司信息. + * @param string $fullName + * @return array|null + */ + public function getCompanyByFullName(string $fullName): ?array + { + return $this->dao->builder() + ->select($this->dao->getFields()) + ->where('full_name', '=', $fullName) + ->first()?->toArray(); + } +} \ No newline at end of file diff --git a/app/Repository/Purchase/PurchaseRepository.php b/app/Repository/Purchase/PurchaseRepository.php new file mode 100644 index 0000000..bf59776 --- /dev/null +++ b/app/Repository/Purchase/PurchaseRepository.php @@ -0,0 +1,43 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Repository\Purchase; + +use App\Dao\Purchase\PurchaseDao; +use App\Repository\AbstractRepository; + +/** + * Author: ykxiao + * Date: 2025/6/5 + * Time: 下午5:32 + * Description: PurchaseRepository类用于提供采购相关的数据访问和操作。它继承自AbstractRepository类,并实现了PurchaseDao接口。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class PurchaseRepository extends AbstractRepository +{ + public function __construct(PurchaseDao $dao) + { + $this->dao = $dao; + } + + public function addPurchase(array $data): void + { + + } +} \ No newline at end of file diff --git a/app/Request/AbstractRequest.php b/app/Request/AbstractRequest.php new file mode 100644 index 0000000..3f2a814 --- /dev/null +++ b/app/Request/AbstractRequest.php @@ -0,0 +1,37 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +use Hyperf\Validation\Request\FormRequest; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午8:24 + * Description: 请求基类。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +abstract class AbstractRequest extends FormRequest +{ + public function authorize(): bool + { + return true; + } +} \ No newline at end of file diff --git a/app/Request/CompanyRequest.php b/app/Request/CompanyRequest.php new file mode 100644 index 0000000..5960a0e --- /dev/null +++ b/app/Request/CompanyRequest.php @@ -0,0 +1,51 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +use App\Constants\ActiveStatusConst; +use App\Constants\CompanyTypeConst; + +class CompanyRequest extends AbstractRequest +{ + public array $scenes = [ + 'addCompany' => [ + 'id', + 'company_type', + 'name', + 'status', + ], + ]; + + public function rules(): array + { + return [ + 'id' => 'integer', + 'company_type' => 'required|in:' . implode(',', array_column(CompanyTypeConst::getConstantsList(), 'value')), + 'name' => 'required|string|max:128', + 'status' => 'integer|in:0,1', + ]; + } + + public function attributes(): array + { + return [ + 'id' => '公司ID', + 'company_type' => '公司类型', + 'name' => '公司名称', + 'status' => '状态', + ]; + } +} \ No newline at end of file diff --git a/app/Request/FirstCompanyRequest.php b/app/Request/FirstCompanyRequest.php new file mode 100644 index 0000000..cf75f91 --- /dev/null +++ b/app/Request/FirstCompanyRequest.php @@ -0,0 +1,89 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +class FirstCompanyRequest extends AbstractRequest +{ + public array $scenes = [ + 'addFirstCompany' => [ + 'domain', + 'name', + 'full_name', + 'company_type', + 'address', + 'logo', + 'owner', // 公司负责人 + 'id_card', // 法人身份证 + 'mobile', + 'org_code', + 'remark', + 'active_status', + 'activation_date', + ], + ]; + + public function rules(): array + { + return [ + 'id' => 'integer', + 'name' => 'required|string|max:60', + // 域名只能是英文、数字、下划线、短横线 + 'domain' => 'required|string|max:100|regex:/^[a-zA-Z0-9_-]+$/', + 'full_name' => 'required|string|max:255', + 'company_type' => 'required|in:1,2', + 'address' => 'required|string|max:255', + 'logo' => 'string|max:255', + 'owner' => 'required|string|max:45', + 'id_card' => 'string|max:18', + // 验证手机号,加正则验证 + 'mobile' => 'required|string|max:11|regex:/^1[3-9]\d{9}$/', + 'org_code' => 'string|max:64', + 'remark' => 'string|max:255', + 'active_status' => 'required|integer|in:0,1', + // 激活日期:不能小于当前时间 + 'activation_date' => 'date|date_format:Y-m-d|after_or_equal:today', + ]; + } + + public function attributes(): array + { + return [ + 'id' => '公司ID', + 'name' => '公司名称', + 'domain' => '公司域名', + 'full_name' => '公司全称', + 'company_type' => '公司类型', + 'address' => '公司地址', + 'logo' => '公司logo', + 'owner' => '公司负责人', + 'id_card' => '法人身份证', + 'mobile' => '手机号码', + 'org_code' => '组织机构代码', + 'remark' => '备注', + 'active_status' => '激活状态', + 'activation_date' => '激活日期', + ]; + } + + public function messages(): array + { + return [ + 'domain.regex' => '只能是英文、数字、下划线、短横线', + 'mobile.regex' => '手机号码格式不正确', + 'activation_date.after_or_equal' => '激活日期不能小于当前时间', + ]; + } +} \ No newline at end of file diff --git a/app/Request/PurchaseRequest.php b/app/Request/PurchaseRequest.php new file mode 100644 index 0000000..b0636aa --- /dev/null +++ b/app/Request/PurchaseRequest.php @@ -0,0 +1,84 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +class PurchaseRequest extends AbstractRequest +{ + public array $scenes = [ + 'userLogin' => ['login_name', 'password'], + 'addUser' => [ + 'login_name', // 登录用户名 + 'password' => 'string|between:6,15', // 密码 + 'dept_id', // 部门ID + 'department', // 部门名称 + 'emp_id', // 员工工号 + 'name', // 姓名 + 'mobile', // 手机号 + 'email', // 邮箱地址 + 'avatar', // 头像 + 'active_status', // 状态 0禁用 1启用 + 'remark', // 备注 + 'role_ids', // 角色ID列表 + 'role_ids.*' // 角色ID + ], + 'getUserList' => [ + 'page', // 页码 + 'pageSize', // 页大小 + ] + ]; + + public function rules(): array + { + return [ + 'login_name' => 'required|string|regex:/^[a-zA-Z0-9_]+$/|between:3,20', + 'password' => 'required|string|between:6,15', + 'dept_id' => 'integer|min:1', + 'department' => 'string|between:2,20', + 'emp_id' => 'integer|min:1', + 'name' => 'string|between:2,20', + 'mobile' => 'string|between:11,11', + 'email' => 'string|between:6,30', + 'avatar' => 'string|between:1,255', + 'active_status' => 'in:0,1', + 'remark' => 'string|between:1,255', + 'role_ids' => 'array', + 'role_ids.*' => 'integer|min:1|distinct', + 'page' => 'integer|min:1', + 'pageSize' => 'integer|min:1', + ]; + } + + public function attributes(): array + { + return [ + 'login_name' => '登录账号', + 'password' => '登录密码', + 'dept_id' => '部门ID', + 'department' => '部门名称', + 'emp_id' => '员工工号', + 'name' => '姓名', + 'mobile' => '手机号', + 'email' => '邮箱地址', + 'avatar' => '头像', + 'active_status' => '状态', + 'remark' => '备注', + 'role_ids' => '角色ID列表', + 'role_ids.*' => '角色ID', + 'page' => '页码', + 'pageSize' => '页大小', + ]; + } +} \ No newline at end of file diff --git a/app/Request/RoleRequest.php b/app/Request/RoleRequest.php new file mode 100644 index 0000000..96b5697 --- /dev/null +++ b/app/Request/RoleRequest.php @@ -0,0 +1,48 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +class RoleRequest extends AbstractRequest +{ + public array $scenes = [ + 'addRole' => [ + 'id', + 'role_name', + 'active_status', + 'sort', + ], + ]; + + public function rules(): array + { + return [ + 'id' => 'integer', + 'role_name' => 'required|string', + 'active_status' => 'required|integer', + 'sort' => 'required|integer', + ]; + } + + public function attributes(): array + { + return [ + 'id' => '角色ID', + 'role_name' => '角色名称', + 'active_status' => '角色状态', + 'sort' => '排序', + ]; + } +} \ No newline at end of file diff --git a/app/Request/UserRequest.php b/app/Request/UserRequest.php new file mode 100644 index 0000000..12018a6 --- /dev/null +++ b/app/Request/UserRequest.php @@ -0,0 +1,84 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Request; + +class UserRequest extends AbstractRequest +{ + public array $scenes = [ + 'userLogin' => ['login_name', 'password'], + 'addUser' => [ + 'login_name', // 登录用户名 + 'password' => 'string|between:6,15', // 密码 + 'dept_id', // 部门ID + 'department', // 部门名称 + 'emp_id', // 员工工号 + 'name', // 姓名 + 'mobile', // 手机号 + 'email', // 邮箱地址 + 'avatar', // 头像 + 'active_status', // 状态 0禁用 1启用 + 'remark', // 备注 + 'role_ids', // 角色ID列表 + 'role_ids.*' // 角色ID + ], + 'getUserList' => [ + 'page', // 页码 + 'pageSize', // 页大小 + ] + ]; + + public function rules(): array + { + return [ + 'login_name' => 'required|string|regex:/^[a-zA-Z0-9_]+$/|between:3,20', + 'password' => 'required|string|between:6,15', + 'dept_id' => 'integer|min:1', + 'department' => 'string|between:2,20', + 'emp_id' => 'integer|min:1', + 'name' => 'string|between:2,20', + 'mobile' => 'string|between:11,11', + 'email' => 'string|between:6,30', + 'avatar' => 'string|between:1,255', + 'active_status' => 'in:0,1', + 'remark' => 'string|between:1,255', + 'role_ids' => 'array', + 'role_ids.*' => 'integer|min:1|distinct', + 'page' => 'integer|min:1', + 'pageSize' => 'integer|min:1', + ]; + } + + public function attributes(): array + { + return [ + 'login_name' => '登录账号', + 'password' => '登录密码', + 'dept_id' => '部门ID', + 'department' => '部门名称', + 'emp_id' => '员工工号', + 'name' => '姓名', + 'mobile' => '手机号', + 'email' => '邮箱地址', + 'avatar' => '头像', + 'active_status' => '状态', + 'remark' => '备注', + 'role_ids' => '角色ID列表', + 'role_ids.*' => '角色ID', + 'page' => '页码', + 'pageSize' => '页大小', + ]; + } +} \ No newline at end of file diff --git a/app/Scope/CompanyScope.php b/app/Scope/CompanyScope.php new file mode 100755 index 0000000..26ec9f9 --- /dev/null +++ b/app/Scope/CompanyScope.php @@ -0,0 +1,73 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Scope; + +use App\Context\QueueContext; +use App\Context\UserContext; +use App\Utils\TableUtils; +use Exception; +use Hyperf\Database\Model\Builder; +use Hyperf\Database\Model\Model; +use Hyperf\Database\Model\Scope; +use Hyperf\Di\Annotation\Inject; +use Hyperf\Redis\Redis; + +/** + * Author: ykxiao + * Date: 2025/5/7 + * Time: 下午4:38 + * Description: 作用域类,用于限制查询结果为当前公司、供应商的记录。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class CompanyScope implements Scope +{ + use TableUtils; + + #[Inject] + protected Redis $redis; + + /** + * 将当前用户所属公司的条件应用于查询构建器。 + * + * @param Builder $builder 查询构建器实例。 + * @param Model $model 模型实例,通常是想要应用作用域的模型。 + * @return Builder 应用了作用域条件的查询构建器实例。 + * @throws Exception + */ + public function apply(Builder $builder, Model $model): Builder + { + // 尝试从上下文中获取当前用户信息 + $user = QueueContext::getUser() ?? UserContext::getCurrentUser(); + $company = $user['company']; + // 如果没有找到用户信息,则不应用任何条件,直接返回查询构建器 + if (!$user || !$company) { + return $builder; + } + + // 如果存在 company_id,应用企业作用域 + if (!empty($companyId = $company['id'] ?? null)) { + return self::hasColumn($model, 'company_id') + ? $builder->where($model->getTable() . '.company_id', $companyId) + : $builder; + } + + return $builder; + } +} \ No newline at end of file diff --git a/app/Service/AliLogsSignService.php b/app/Service/AliLogsSignService.php new file mode 100644 index 0000000..817c1bd --- /dev/null +++ b/app/Service/AliLogsSignService.php @@ -0,0 +1,158 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Service; + +use Hyperf\Config\Annotation\Value; +use Hyperf\Di\Annotation\Inject; +use Hyperf\Guzzle\ClientFactory; +use function Hyperf\Coroutine\co; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午7:18 + * Description: 阿里云日志服务. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class AliLogsSignService +{ + protected const string LOG_SIGNATURE_METHOD = 'hmac-sha1'; + + protected const string LOG_API_VERSION = '0.6.0'; + + #[Value('alibaba.accessKeyId')] + protected string $accessKeyId; + + #[Value('alibaba.accessKeySecret')] + protected string $accessKeySecret; + + #[Value('alibaba.logs')] + protected array $logs; + + #[Inject] + protected ClientFactory $clientFactory; + + /** + * 签名及请求头拼接. + * @param mixed $method + * @param mixed $uri + * @param mixed $params + * @param mixed $body + * @param mixed $logProject + * @param mixed $logEndpoint + */ + public function buildHeaders( + string $method, + string $uri, + array $params, + string $body, + string|object $logProject, + string $logEndpoint + ): array + { + $headers = [ + 'x-log-signaturemethod' => self::LOG_SIGNATURE_METHOD, + 'x-log-apiversion' => self::LOG_API_VERSION, + 'Host' => sprintf('%s.%s', $logProject, $logEndpoint), + 'Content-Type' => 'application/json', + ]; + $contentLength = 0; + $contentMd5 = ''; + if (!empty($body) && strlen($body) > 0) { + $contentLength = strlen($body); + $contentMd5 = strtoupper(md5($body)); + $headers['Content-MD5'] = $contentMd5; + } + // date + setlocale(LC_TIME, 'en_US'); + $date = gmdate('D, d M Y H:i:s \G\M\T', time()); + $headers['Date'] = $date; + $headers['Content-Length'] = (string)$contentLength; + $contentType = $headers['Content-Type']; + $message = $method . "\n" . $contentMd5 . "\n" . $contentType . "\n" . $date . "\n"; + // header + $filterHeaders = []; + foreach ($headers as $key => $val) { + if (str_starts_with($key, 'x-log-') || str_starts_with($key, 'x-acs-')) { + $filterHeaders[$key] = $val; + } + } + ksort($filterHeaders); + foreach ($filterHeaders as $key => $val) { + $message .= $key . ':' . $val . "\n"; + } + // uri and params + $message .= $uri; + if (sizeof($params) > 0) { + $message .= '?'; + } + ksort($params); + $sep = ''; + foreach ($params as $key => $val) { + $message .= $sep . $key . '=' . $val; + $sep = '&'; + } + // signature & authorization + $signature = $this->generateSignature($message); + $auth = 'LOG ' . $this->accessKeyId . ':' . $signature; + $headers['Authorization'] = $auth; + return $headers; + } + + /** + * 实现调用PutWebTracking接口将多条日志合并进行采集. + */ + public function putWebTracking(array $record): void + { + $logEndpoint = $this->logs['log_endpoint']; + $logProject = $this->logs['log_project']; + $logStores = $this->logs['log_store']; + $params = []; + $body = [ + '__topic__' => 'mes api logs', + '__source__' => 'admin api', + '__logs__' => [ + ['Logs' => $record['formatted']], + ], + '__tags__' => [ + 'mes' => $record['channel'], + ], + ]; + $body = json_encode($body); + + $sign_url = sprintf('/logstores/%s/track', $logStores); + $headers = $this->buildHeaders('POST', $sign_url, $params, $body, $logProject, $logEndpoint); + $options = [ + 'headers' => $headers, + 'body' => $body, + 'query' => $params, + ]; + $url = sprintf('https://%s.%s/logstores/%s/track', $logProject, $logEndpoint, $logStores); + $client = $this->clientFactory->create(); + co(function () use ($client, $url, $options) { + $client->request('POST', $url, $options); + }); + } + + protected function generateSignature(string $message): string + { + return base64_encode(hash_hmac('sha1', $message, $this->accessKeySecret, true)); + } +} \ No newline at end of file diff --git a/app/Service/MigrateService.php b/app/Service/MigrateService.php new file mode 100644 index 0000000..0168bdc --- /dev/null +++ b/app/Service/MigrateService.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Service; + +use Hyperf\Database\Schema\Blueprint; + +class MigrateService +{ + /*** + * 在创建的时候自动添加如下字段 + * @param Blueprint $blueprint + * @return Blueprint + */ + public static function migrateCreateInfo(Blueprint $blueprint): Blueprint + { + $blueprint->integer('creator_id')->default(0)->unsigned()->comment('创建人ID'); + $blueprint->string('creator_name', 45)->default('')->comment('创建人姓名'); + $blueprint->integer('created_at')->default(0)->unsigned()->comment('创建时间'); + $blueprint->integer('updated_at')->default(0)->unsigned()->comment('更新时间'); + $blueprint->integer('deleted_at')->nullable()->unsigned()->comment('软删除时间'); + return $blueprint; + } + + public static function migrateTime(Blueprint $blueprint): Blueprint + { + $blueprint->integer('created_at')->default(0)->unsigned()->comment('创建时间'); + $blueprint->integer('updated_at')->default(0)->unsigned()->comment('更新时间'); + $blueprint->integer('deleted_at')->nullable()->unsigned()->comment('软删除时间'); + return $blueprint; + } +} \ No newline at end of file diff --git a/app/Service/OpLogsService.php b/app/Service/OpLogsService.php new file mode 100755 index 0000000..8add9b8 --- /dev/null +++ b/app/Service/OpLogsService.php @@ -0,0 +1,121 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); +/** + * This file is part of Hyperf. + * + * @link https://www.hyperf.io + * @document https://hyperf.wiki + * @contact group@hyperf.io + * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + */ + +namespace App\Service; + +use App\Context\QueueContext; +use App\Context\UserContext; +use Hyperf\Collection\Arr; +use Hyperf\HttpServer\Contract\RequestInterface; +use Hyperf\HttpServer\Router\Dispatched; + +use function Hyperf\Support\make; + +/** + * Author: ykxiao + * Date: 2024/12/25 + * Time: 上午9:37 + * Description: 操作日志服务类。 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class OpLogsService +{ + /** + * 记录操作日志。 + * + * 该方法用于记录与请求相关联的操作日志,包括操作动作、路由、参数、IP地址、用户代理等信息。 + * 允许通过$logStream参数传递额外的备注信息,并可选择指定日志的来源。 + * + * @param string $logStream 日志流或额外的备注信息,默认为空字符串 + * @param null|int $source 日志来源的标识,默认为0 + */ + public function operatorLogs(string $logStream = '', ?int $source = 0): void + { + // 创建请求对象 + $request = make(RequestInterface::class); + // 尝试从请求中获取调度信息 + $dispatched = $request->getAttribute(Dispatched::class); + + // 如果不存在调度信息,则不记录日志 + if (! $dispatched instanceof Dispatched) { + return; + } + + // 解析路由处理器信息 + $handler = $dispatched->handler->callback ?? null; + [$routeControllerName, $routeActionName] = $handler; + // 提取控制器名称 + $controllerName = Arr::last(explode('\\', $routeControllerName)); + // 组装当前执行的动作字符串 + $currAction = $controllerName . '@' . $routeActionName; + + // 过滤敏感参数后收集请求信息 + $params = $this->filterSensitiveParams($request->all()); + $clientIP = $this->getClientIP($request); + $agent = $request->getHeaderLine('User-Agent'); + + // 准备日志数据 + $data = [ + 'action' => $currAction, + 'route' => $request->path(), + 'params' => $params, + 'ip' => $clientIP, + 'agent' => $agent, + 'remark' => $logStream, + 'source' => $source, + ]; + // 将日志数据加入队列,以便后续处理 + make(QueueService::class)->make($data)->opLogs(); + } + + /** + * 过滤敏感参数. + */ + protected function filterSensitiveParams(array $params): array + { + $sensitiveKeys = ['password', 'pwd', 'pwd_conf', 'original_pwd', 'old_pwd', 'new_pwd', 'conf_pwd']; + + foreach ($sensitiveKeys as $key) { + Arr::forget($params, $key); + } + + return $params; + } + + /** + * 获取客户端 IP. + */ + protected function getClientIP(RequestInterface $request): string + { + $realIP = $request->getHeaderLine('x-real-ip'); + $forwardedFor = $request->getHeaderLine('x-forwarded-for'); + + $clientIP = $realIP ?: $forwardedFor; + return $clientIP ?: '127.0.0.1'; + } +} diff --git a/app/Service/QueueService.php b/app/Service/QueueService.php new file mode 100644 index 0000000..2af2249 --- /dev/null +++ b/app/Service/QueueService.php @@ -0,0 +1,92 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Service; + +use App\Context\UserContext; +use App\Job\ColumnConfigJob; +use App\Job\OpLogsJob; +use App\Job\RequestWriteLogsJob; +use Hyperf\Amqp\Producer; +use Hyperf\AsyncQueue\Driver\DriverFactory; +use Hyperf\AsyncQueue\Driver\DriverInterface; +use Hyperf\Di\Annotation\Inject; + +class QueueService +{ + // 存储配置参数 + protected array $params = []; + + // 当前操作的函数名 + protected string $function = ''; + + // 队列驱动实例 + protected DriverInterface $driver; + + // 生产者实例,用于发送消息 + #[Inject] + protected Producer $producer; + + /** + * 构造函数,初始化队列服务。 + * + * @param DriverFactory $driverFactory 驱动工厂,用于获取具体的队列驱动实例 + */ + public function __construct(DriverFactory $driverFactory) + { + $this->driver = $driverFactory->get('whf'); + } + + /** + * 创建队列任务并执行。 + * + * @param array $params + * @return QueueService + */ + public function make(array $params): static + { + // 将当前用户信息添加到参数中 + $params['user'] = UserContext::getCurrentUser(); + + $this->params = $params; + return $this; + } + + /** + * 将请求日志写入文件。 + * + */ + public function writeRequestLogs(): void + { + $this->driver->push(new RequestWriteLogsJob($this->params)); + } + + /** + * 列配置保存. + */ + public function saveColumnConfig(): void + { + $this->driver->push(new ColumnConfigJob($this->params)); + } + + /** + * 将操作日志推送到队列中. + */ + public function opLogs(): void + { + // 将操作日志封装为OpLogsJob任务,并推送到驱动器对应的队列中 + $this->driver->push(new OpLogsJob($this->params)); + } +} \ No newline at end of file diff --git a/app/Service/SysService.php b/app/Service/SysService.php new file mode 100644 index 0000000..085260d --- /dev/null +++ b/app/Service/SysService.php @@ -0,0 +1,48 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Service; + +use Psr\Http\Message\ServerRequestInterface; + +/** + * Author: ykxiao + * Date: 2025/6/4 + * Time: 上午10:19 + * Description: 系统服务 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class SysService +{ + /** + * 获取客户端IP信息 + * @param ServerRequestInterface $request + * @return string + */ + public function getClientIpInfo(ServerRequestInterface $request): string + { + // 尝试从请求头获取客户端真实IP或转发的IP + $realIP = $request->getHeaderLine('x-real-ip'); + $forwardedFor = $request->getHeaderLine('x-forwarded-for'); + // 确定客户端IP,优先使用 x-real-ip,其次是 x-forwarded-for,最后是默认IP + $clientIP = $realIP ?: $forwardedFor; + + return $clientIP ?: '127.0.0.1'; + } +} \ No newline at end of file diff --git a/app/Service/Trait/ColumnConfigTrait.php b/app/Service/Trait/ColumnConfigTrait.php new file mode 100755 index 0000000..82bde65 --- /dev/null +++ b/app/Service/Trait/ColumnConfigTrait.php @@ -0,0 +1,147 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); +/** + * This file is part of Hyperf. + * + * @link https://www.hyperf.io + * @document https://hyperf.wiki + * @contact group@hyperf.io + * @license https://github.com/hyperf/hyperf/blob/master/LICENSE + */ + +namespace App\Service\Trait; + +use App\Context\UserContext; +use App\Model\ColumnConfig; +use App\Model\TableConfig; +use App\Service\QueueService; +use Exception; +use Hyperf\Di\Annotation\Inject; +use Hyperf\HttpServer\Router\Dispatched; +use Hyperf\Stringable\Str; +use Psr\Http\Message\ServerRequestInterface; + +use function Hyperf\Collection\collect; +use function Hyperf\Config\config; + +trait ColumnConfigTrait +{ + #[Inject] + protected QueueService $queueService; + + #[Inject] + protected ServerRequestInterface $clientRequest; + + /** + * 获取列配置. + * @throws Exception + */ + public function getColumnConfig(): array + { + $user = UserContext::getCurrentUser(); + if (! $user) { + return []; + } + + $method = Str::snake($this->getCurrentAction()); + $this->saveColumnConfig($user, $method, $this->clientRequest->getParsedBody()); + + $this->saveTableConfig($user); + // 从数据库中查询对应的列配置详情 + $fields = ColumnConfig::query() + ->where(['creator_id' => $user['id'], 'method' => $method]) + ->select(['prop', 'label', 'sortable', 'sort', 'width', 'hide', 'fix', 'filter', 'is_search', 'search_type', 'condition']) + ->orderBy('sort') + ->get(); + return $fields->isNotEmpty() ? $fields->toArray() : $this->getDefaultConfig($method); + } + + /** + * 获取表格配置. + * @throws Exception + */ + public function getTableConfig(): array + { + $user = UserContext::getCurrentUser(); + if (! $user) { + return []; + } + + $config = TableConfig::query() + ->where(['creator_id' => $user['id'], 'method' => Str::snake($this->getCurrentAction())]) + ->select(['size', 'config']) + ->first(); + + return $config ? $config->toArray() : []; + } + + /** + * 获取默认配置. + */ + private function getDefaultConfig(string $method): array + { + $configList = config('column_config.' . $method); + if (empty($configList)) { + return []; + } + + return collect($configList)->map(function ($item, $key) { + $item['sort'] = $key + 1; + return $item; + })->toArray(); + } + + /** + * 获取当前请求所匹配的方法. + * @throws Exception + */ + private function getCurrentAction(): string + { + $dispatched = $this->clientRequest->getAttribute(Dispatched::class); + return $dispatched->handler->callback[1] ?? ''; + } + + /** + * 保存列配置. + * @throws Exception + */ + private function saveColumnConfig(array $user, string $method, array $params): void + { + $this->queueService->make(compact('user', 'method', 'params'))->saveColumnConfig(); + } + + /** + * @throws Exception + */ + private function saveTableConfig(array $user): void + { + $body = $this->clientRequest->getParsedBody(); + if (empty($body['table_config'])) { + return; + } + $query = TableConfig::query(); + $params = $body['table_config']; + $method = Str::snake($this->getCurrentAction()); + $query->updateOrCreate( + ['creator_id' => $user['id'], 'method' => $method], + [ + 'method' => $method, + 'size' => $params['size'] ?? 'medium', + 'config' => $params['config'] ?? [], + ], + ); + } +} diff --git a/app/Utils/ApiResponse.php b/app/Utils/ApiResponse.php new file mode 100644 index 0000000..7fcf9a0 --- /dev/null +++ b/app/Utils/ApiResponse.php @@ -0,0 +1,119 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Utils; + +use Hyperf\HttpMessage\Server\Response; +use Hyperf\HttpMessage\Stream\SwooleStream; + +/** + * Author: ykxiao + * Date: 2025/6/3 + * Time: 下午8:31 + * Description: A utility class for creating API responses. + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +class ApiResponse +{ + protected string $token = ''; // Stores the authorization token + + protected Response $response; // Holds the response object + + /** + * Constructor to initialize ApiResponse object with a response object. + * + * @param Response $response the response object to be used for sending API responses + */ + public function __construct(Response $response) + { + $this->response = $response; + } + + /** + * Creates a successful API response with optional data, message, and status code. + * + * @param array $data the data to be returned in the response + * @param string $message a success message to be returned + * @param int $code the HTTP status code for the response + * @return Response the constructed response with success data + */ + public function success(array $data = [], string $message = 'Success', int $code = 200): Response + { + $result = [ + 'code' => $code, + 'message' => $message, + 'data' => $data, + ]; + + return self::jsonResponse($result); + } + + /** + * Creates an error API response with an error message, optional data, and status code. + * + * @param string $message the error message to be returned + * @param int $code the HTTP status code for the error response + * @param null $data optional additional data to be returned with the error + * @return Response the constructed response with error data + */ + public function error(string $message, int $code = 400, $data = null): Response + { + $result = [ + 'code' => $code, + 'message' => $message, + 'data' => $data, + ]; + + return self::jsonResponse($result); + } + + /** + * Sets an authorization token to be included in the response headers. + * + * @param string $token the authorization token + * @return static the current instance of ApiResponse with the token set + */ + public function setToken(string $token): static + { + $this->token = $token; + return $this; + } + + /** + * Converts data into a JSON response with an optional status code. + * If a token has been set, it includes the token in the authorization header. + * + * @param array $data the data to encode into JSON and send in the response + * @param int $statusCode the HTTP status code for the response + * @return Response the constructed JSON response + */ + public function jsonResponse(array $data, int $statusCode = 200): Response + { + $response = $this->response; + if ($this->token) { + // Adds authorization header to the response if a token is set + $response->withHeader('Authorization', 'Bearer ' . $this->token); + } + // Constructs and returns the response with the specified data and headers + return $response + ->withStatus($statusCode) + ->withHeader('Content-Type', 'application/json') + ->withBody(new SwooleStream(json_encode($data))); + } +} \ No newline at end of file diff --git a/app/Utils/TableUtils.php b/app/Utils/TableUtils.php new file mode 100644 index 0000000..b5dbebe --- /dev/null +++ b/app/Utils/TableUtils.php @@ -0,0 +1,81 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace App\Utils; + +use App\Exception\ApiException; +use App\Model\Model; +use Hyperf\Context\ApplicationContext; +use Hyperf\DbConnection\Db; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use Psr\SimpleCache\CacheInterface; +use Psr\SimpleCache\InvalidArgumentException; + +/** + * Author: ykxiao + * Date: 2025/5/6 + * Time: 下午10:44 + * Description: 表工具类, 用于判断表是否存在某个字段 + * + * (c) ykxiao + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ +trait TableUtils +{ + /** + * 检查数据表是否包含指定列。 + * + * @param Model|string $modelOrTable + * @param string $column 列名称。 + * @return bool 如果数据表包含指定列,则返回 true;否则返回 false。 + */ + public static function hasColumn(Model|string $modelOrTable, string $column): bool + { + try { + if ($modelOrTable instanceof Model) { + $connection = $modelOrTable->getConnection(); + $tableName = $modelOrTable->getTable(); + } else { + // 如果是字符串表名,默认使用全局连接 + $connection = Db::connection(); + $tableName = $modelOrTable; + } + + // 获取前缀(手动拼接) + $prefix = $connection->getConfig('prefix') ?? ''; + $fullTable = $prefix . $tableName; + + // 使用缓存避免频繁查询 + $cacheKey = "table_column_exists:$fullTable:$column"; + /** @var CacheInterface $cache */ + $cache = ApplicationContext::getContainer()->get(CacheInterface::class); + if (($exists = $cache->get($cacheKey)) !== null) { + return $exists; + } + + // 执行 SHOW COLUMNS + $result = $connection->select("SHOW COLUMNS FROM `$fullTable` LIKE '" . addslashes($column) . "'"); + $exists = !empty($result); + + $cache->set($cacheKey, $exists, 3600); + return $exists; + } catch (ContainerExceptionInterface|NotFoundExceptionInterface|InvalidArgumentException $e) { + throw new ApiException($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/bin/hyperf.php b/bin/hyperf.php new file mode 100644 index 0000000..20f439a --- /dev/null +++ b/bin/hyperf.php @@ -0,0 +1,25 @@ +#!/usr/bin/env php +get(Hyperf\Contract\ApplicationInterface::class); + $application->run(); +})(); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..e21d799 --- /dev/null +++ b/composer.json @@ -0,0 +1,89 @@ +{ + "name": "hyperf/hyperf-skeleton", + "type": "project", + "keywords": [ + "php", + "swoole", + "framework", + "hyperf", + "microservice", + "middleware" + ], + "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", + "license": "Apache-2.0", + "require": { + "php": ">=8.3", + "hyperf/amqp": "~3.1.0", + "hyperf/async-queue": "~3.1.0", + "hyperf/cache": "~3.1.0", + "hyperf/command": "~3.1.0", + "hyperf/config": "~3.1.0", + "hyperf/constants": "~3.1.0", + "hyperf/database": "~3.1.0", + "hyperf/db-connection": "~3.1.0", + "hyperf/engine": "^2.10", + "hyperf/framework": "~3.1.0", + "hyperf/guzzle": "~3.1.0", + "hyperf/http-server": "~3.1.0", + "hyperf/json-rpc": "^3.1", + "hyperf/logger": "~3.1.0", + "hyperf/memory": "~3.1.0", + "hyperf/model-cache": "~3.1.0", + "hyperf/process": "~3.1.0", + "hyperf/rate-limit": "^3.1", + "hyperf/redis": "~3.1.0", + "hyperf/rpc": "~3.1.0", + "hyperf/rpc-client": "^3.1", + "hyperf/rpc-server": "~3.1.0", + "hyperf/service-governance-nacos": "^3.1", + "hyperf/validation": "^3.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "hyperf/devtool": "~3.1.0", + "hyperf/testing": "~3.1.0", + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^1.0", + "swoole/ide-helper": "^5.0" + }, + "suggest": { + "ext-openssl": "Required to use HTTPS.", + "ext-json": "Required to use JSON.", + "ext-pdo": "Required to use MySQL Client.", + "ext-pdo_mysql": "Required to use MySQL Client.", + "ext-redis": "Required to use Redis Client." + }, + "autoload": { + "psr-4": { + "App\\": "app/" + }, + "files": [] + }, + "autoload-dev": { + "psr-4": { + "HyperfTest\\": "./test/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "extra": [], + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-autoload-dump": [ + "rm -rf runtime/container" + ], + "test": "co-phpunit --prepend test/bootstrap.php --colors=always", + "cs-fix": "php-cs-fixer fix $1", + "analyse": "phpstan analyse --memory-limit 300M", + "start": [ + "Composer\\Config::disableProcessTimeout", + "php ./bin/hyperf.php start" + ] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..146ca92 --- /dev/null +++ b/composer.lock @@ -0,0 +1,11009 @@ +{ + "_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": "018dd94af05c929f1855f246d354e89c", + "packages": [ + { + "name": "carbonphp/carbon-doctrine-types", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/dbal": "<4.0.0 || >=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + }, + "time": "2025-04-07T20:06:18+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "doctrine/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": "doctrine/lexer", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", + "reference": "861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/2.1.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:35:39+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.2.6", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7", + "reference": "e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2|^2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.2.6" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-06-01T07:04:22+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": "graham-campbell/result-type", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:45:45+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.9.3" + }, + "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": "2025-03-27T13:37:11+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.2.0" + }, + "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": "2025-03-27T13:27:01+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.7.1" + }, + "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": "2025-03-27T12:30:47+00:00" + }, + { + "name": "hyperf/amqp", + "version": "v3.1.50", + "source": { + "type": "git", + "url": "https://github.com/hyperf/amqp.git", + "reference": "db5e24822f2dcc3af055b5c985702f59901be380" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/amqp/zipball/db5e24822f2dcc3af055b5c985702f59901be380", + "reference": "db5e24822f2dcc3af055b5c985702f59901be380", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "hyperf/pool": "~3.1.0", + "hyperf/process": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "php-amqplib/php-amqplib": "^3.5", + "psr/container": "^1.0 || ^2.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "suggest": { + "hyperf/di": "Required to use annotations.", + "hyperf/event": "Declare queue and start consumers automatically." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Amqp\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Amqp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A amqplib for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "AMQP", + "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": "2025-01-08T08:57:09+00:00" + }, + { + "name": "hyperf/async-queue", + "version": "v3.1.51", + "source": { + "type": "git", + "url": "https://github.com/hyperf/async-queue.git", + "reference": "29f49ba266dd0a5763e2c4d8edfe5a448f944ff0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/async-queue/zipball/29f49ba266dd0a5763e2c4d8edfe5a448f944ff0", + "reference": "29f49ba266dd0a5763e2c4d8edfe5a448f944ff0", + "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": { + "hyperf": { + "config": "Hyperf\\AsyncQueue\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2025-01-14T06:55:15+00:00" + }, + { + "name": "hyperf/cache", + "version": "v3.1.43", + "source": { + "type": "git", + "url": "https://github.com/hyperf/cache.git", + "reference": "1e3cc54cee776c8d32cf40912dee5d366383bc33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/cache/zipball/1e3cc54cee776c8d32cf40912dee5d366383bc33", + "reference": "1e3cc54cee776c8d32cf40912dee5d366383bc33", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/collection": "~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/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "suggest": { + "hyperf/di": "Use cache annotations.", + "hyperf/event": "Use listener to delete annotation cache." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Cache\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A cache component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "cache", + "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-10-09T10:22:39+00:00" + }, + { + "name": "hyperf/code-parser", + "version": "v3.1.52", + "source": { + "type": "git", + "url": "https://github.com/hyperf/code-parser.git", + "reference": "340fb9902465bfc6d26d8b5a6d8d369590ea6e57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/code-parser/zipball/340fb9902465bfc6d26d8b5a6d8d369590ea6e57", + "reference": "340fb9902465bfc6d26d8b5a6d8d369590ea6e57", + "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": "2025-02-27T07:40:13+00:00" + }, + { + "name": "hyperf/codec", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/codec.git", + "reference": "effc71c25e2d53c00fcf41da8bca083ac8a0db0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/codec/zipball/effc71c25e2d53c00fcf41da8bca083ac8a0db0e", + "reference": "effc71c25e2d53c00fcf41da8bca083ac8a0db0e", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/collection", + "version": "v3.1.52", + "source": { + "type": "git", + "url": "https://github.com/hyperf/collection.git", + "reference": "a56bfce5002c7d69838f7e82184a2e135e98e80a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/collection/zipball/a56bfce5002c7d69838f7e82184a2e135e98e80a", + "reference": "a56bfce5002c7d69838f7e82184a2e135e98e80a", + "shasum": "" + }, + "require": { + "hyperf/conditionable": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/stringable": "~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": "2025-02-17T03:58:59+00:00" + }, + { + "name": "hyperf/command", + "version": "v3.1.51", + "source": { + "type": "git", + "url": "https://github.com/hyperf/command.git", + "reference": "e71af684e6f01140221b608b3d4f4cf6f78144fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/command/zipball/e71af684e6f01140221b608b3d4f4cf6f78144fe", + "reference": "e71af684e6f01140221b608b3d4f4cf6f78144fe", + "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": { + "hyperf": { + "config": "Hyperf\\Command\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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.51" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-02-06T03:40:37+00:00" + }, + { + "name": "hyperf/conditionable", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/conditionable.git", + "reference": "dec9dec9dbde14e20f3d7ba000c3302381019de1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/conditionable/zipball/dec9dec9dbde14e20f3d7ba000c3302381019de1", + "reference": "dec9dec9dbde14e20f3d7ba000c3302381019de1", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/config", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/config.git", + "reference": "1df5e310aab752d6195f89f5cc98daf3cdc4bb6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/config/zipball/1df5e310aab752d6195f89f5cc98daf3cdc4bb6e", + "reference": "1df5e310aab752d6195f89f5cc98daf3cdc4bb6e", + "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": { + "hyperf": { + "config": "Hyperf\\Config\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/constants", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/constants.git", + "reference": "e1e1184779cd163f9603ce234e1ecccb6fe382ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/constants/zipball/e1e1184779cd163f9603ce234e1ecccb6fe382ae", + "reference": "e1e1184779cd163f9603ce234e1ecccb6fe382ae", + "shasum": "" + }, + "require": { + "hyperf/di": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "hyperf/translation": "Required to use translation." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Constants\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Constants\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A constants component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "constants", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/context", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/context.git", + "reference": "ac666862d644db7d813342c880826a1fda599bdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/context/zipball/ac666862d644db7d813342c880826a1fda599bdf", + "reference": "ac666862d644db7d813342c880826a1fda599bdf", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/contract", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/contract.git", + "reference": "6ef2c7f98917c52ccda3a37ae65b190848dde6c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/contract/zipball/6ef2c7f98917c52ccda3a37ae65b190848dde6c4", + "reference": "6ef2c7f98917c52ccda3a37ae65b190848dde6c4", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/coordinator", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/coordinator.git", + "reference": "a0497d2a260f166ab53fed2eca6bb4e48b49ef56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/coordinator/zipball/a0497d2a260f166ab53fed2eca6bb4e48b49ef56", + "reference": "a0497d2a260f166ab53fed2eca6bb4e48b49ef56", + "shasum": "" + }, + "require": { + "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\\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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/coroutine", + "version": "v3.1.54", + "source": { + "type": "git", + "url": "https://github.com/hyperf/coroutine.git", + "reference": "5b474c4bb46be015f1340939d92931b96a0b0cad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/coroutine/zipball/5b474c4bb46be015f1340939d92931b96a0b0cad", + "reference": "5b474c4bb46be015f1340939d92931b96a0b0cad", + "shasum": "" + }, + "require": { + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/engine": "^2.14.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": "2025-04-14T01:38:29+00:00" + }, + { + "name": "hyperf/database", + "version": "v3.1.54", + "source": { + "type": "git", + "url": "https://github.com/hyperf/database.git", + "reference": "efae6d4694652fe3bb61e2f39c7f0a2e6813762d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/database/zipball/efae6d4694652fe3bb61e2f39c7f0a2e6813762d", + "reference": "efae6d4694652fe3bb61e2f39c7f0a2e6813762d", + "shasum": "" + }, + "require": { + "hyperf/code-parser": "~3.1.0", + "hyperf/collection": "~3.1.23", + "hyperf/conditionable": "~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).", + "hyperf/paginator": "Required to paginate the result set (~3.1.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": "2025-04-14T01:39:13+00:00" + }, + { + "name": "hyperf/db-connection", + "version": "v3.1.44", + "source": { + "type": "git", + "url": "https://github.com/hyperf/db-connection.git", + "reference": "95dbb713fda5556106b803d0201e1631645985b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/db-connection/zipball/95dbb713fda5556106b803d0201e1631645985b5", + "reference": "95dbb713fda5556106b803d0201e1631645985b5", + "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": { + "hyperf": { + "config": "Hyperf\\DbConnection\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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-10-11T08:58:16+00:00" + }, + { + "name": "hyperf/di", + "version": "v3.1.53", + "source": { + "type": "git", + "url": "https://github.com/hyperf/di.git", + "reference": "13a89409da739102c7fc308ef53bdd2694cb220b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/di/zipball/13a89409da739102c7fc308ef53bdd2694cb220b", + "reference": "13a89409da739102c7fc308ef53bdd2694cb220b", + "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": { + "hyperf": { + "config": "Hyperf\\Di\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2025-04-03T08:36:04+00:00" + }, + { + "name": "hyperf/dispatcher", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/dispatcher.git", + "reference": "5cbdfd586bb8c3bbbabed5a23cec7faf52b744b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/dispatcher/zipball/5cbdfd586bb8c3bbbabed5a23cec7faf52b744b0", + "reference": "5cbdfd586bb8c3bbbabed5a23cec7faf52b744b0", + "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": { + "hyperf": { + "config": "Hyperf\\Dispatcher\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/engine", + "version": "v2.14.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/engine.git", + "reference": "74ec5130fa0838e285a24292a232ce455edccff8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/engine/zipball/74ec5130fa0838e285a24292a232ce455edccff8", + "reference": "74ec5130fa0838e285a24292a232ce455edccff8", + "shasum": "" + }, + "require": { + "hyperf/engine-contract": "~1.13.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": "5.*" + }, + "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": { + "hyperf": { + "config": "Hyperf\\Engine\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "2.14-dev" + } + }, + "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.14.0" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-04-13T15:11:22+00:00" + }, + { + "name": "hyperf/engine-contract", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/engine-contract.git", + "reference": "26a18ec0375147546bf9702b0fd737fdd2cec1d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/engine-contract/zipball/26a18ec0375147546bf9702b0fd737fdd2cec1d6", + "reference": "26a18ec0375147546bf9702b0fd737fdd2cec1d6", + "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.11-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.13.0" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-04-13T14:48:14+00:00" + }, + { + "name": "hyperf/event", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/event.git", + "reference": "2b5fbbc94674a1a5e1622896eb3f7ecc80aa38c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/event/zipball/2b5fbbc94674a1a5e1622896eb3f7ecc80aa38c4", + "reference": "2b5fbbc94674a1a5e1622896eb3f7ecc80aa38c4", + "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": { + "hyperf": { + "config": "Hyperf\\Event\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/exception-handler", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/exception-handler.git", + "reference": "df2135fb0ffe0bb61032911038aea6488077cdef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/exception-handler/zipball/df2135fb0ffe0bb61032911038aea6488077cdef", + "reference": "df2135fb0ffe0bb61032911038aea6488077cdef", + "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": { + "hyperf": { + "config": "Hyperf\\ExceptionHandler\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/framework", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/framework.git", + "reference": "7b317d3891698a1eb0308e7306730d2ada1d6ff4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/framework/zipball/7b317d3891698a1eb0308e7306730d2ada1d6ff4", + "reference": "7b317d3891698a1eb0308e7306730d2ada1d6ff4", + "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": { + "hyperf": { + "config": "Hyperf\\Framework\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/guzzle", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/guzzle.git", + "reference": "fe838557530bf7b2d39dc604563c3a3ff8d5618f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/guzzle/zipball/fe838557530bf7b2d39dc604563c3a3ff8d5618f", + "reference": "fe838557530bf7b2d39dc604563c3a3ff8d5618f", + "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": { + "hyperf": { + "config": "Hyperf\\Guzzle\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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.42" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/http-message", + "version": "v3.1.48", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-message.git", + "reference": "534ce81af0feaa0c4a9e132af1c6a9c5527a8d85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/http-message/zipball/534ce81af0feaa0c4a9e132af1c6a9c5527a8d85", + "reference": "534ce81af0feaa0c4a9e132af1c6a9c5527a8d85", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/engine": "^2.11", + "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": { + "hyperf": { + "config": "Hyperf\\HttpMessage\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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.48" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-12-05T02:41:08+00:00" + }, + { + "name": "hyperf/http-server", + "version": "v3.1.55", + "source": { + "type": "git", + "url": "https://github.com/hyperf/http-server.git", + "reference": "96a1d80cd9482942899d7068af0e6ecb78d382ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/http-server/zipball/96a1d80cd9482942899d7068af0e6ecb78d382ce", + "reference": "96a1d80cd9482942899d7068af0e6ecb78d382ce", + "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": { + "hyperf": { + "config": "Hyperf\\HttpServer\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2025-05-14T07:44:25+00:00" + }, + { + "name": "hyperf/json-rpc", + "version": "v3.1.47", + "source": { + "type": "git", + "url": "https://github.com/hyperf/json-rpc.git", + "reference": "daa987e9e58fcbbf676ae266de2d428301a74d1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/json-rpc/zipball/daa987e9e58fcbbf676ae266de2d428301a74d1b", + "reference": "daa987e9e58fcbbf676ae266de2d428301a74d1b", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/context": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/engine": "^2.0", + "hyperf/http-message": "~3.1.0", + "hyperf/load-balancer": "~3.1.0", + "hyperf/rpc": "~3.1.0", + "hyperf/serializer": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0", + "swow/psr7-plus": "^1.0" + }, + "suggest": { + "hyperf/event": "Register the objects to ProtocolManager automatically.", + "hyperf/framework": "Register the objects to ProtocolManager automatically.", + "hyperf/guzzle": "Required to use JSON RPC with HTTP protocol.", + "hyperf/rpc-client": "Reqiured to use JSON RPC in hyperf rpc client.", + "hyperf/rpc-server": "Reqiured to use JSON RPC in hyperf rpc server." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\JsonRpc\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\JsonRpc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A JSON RPC component for Hyperf RPC Server or Client.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "json-rpc", + "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-11-28T01:51:55+00:00" + }, + { + "name": "hyperf/load-balancer", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/load-balancer.git", + "reference": "13d23eae71f917df4df54f7439076360dc5f9cc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/load-balancer/zipball/13d23eae71f917df4df54f7439076360dc5f9cc0", + "reference": "13d23eae71f917df4df54f7439076360dc5f9cc0", + "shasum": "" + }, + "require": { + "hyperf/coordinator": "~3.1.0", + "hyperf/coroutine": "~3.1.0", + "markrogoyski/math-php": "^2.0", + "php": ">=8.1", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\LoadBalancer\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\LoadBalancer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A load balancer library for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "load-balancer", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/logger", + "version": "v3.1.55", + "source": { + "type": "git", + "url": "https://github.com/hyperf/logger.git", + "reference": "8a80e2fab1521a08e2b8061a5dd65f5105f88ed6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/logger/zipball/8a80e2fab1521a08e2b8061a5dd65f5105f88ed6", + "reference": "8a80e2fab1521a08e2b8061a5dd65f5105f88ed6", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "monolog/monolog": "^2.7 || ^3.1", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Logger\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Logger\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A logger component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "logger", + "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": "2025-05-14T08:25:19+00:00" + }, + { + "name": "hyperf/macroable", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/macroable.git", + "reference": "0be650165b9e8ea073e199fac788ece70f16b6a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/macroable/zipball/0be650165b9e8ea073e199fac788ece70f16b6a4", + "reference": "0be650165b9e8ea073e199fac788ece70f16b6a4", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/memory", + "version": "v3.1.53", + "source": { + "type": "git", + "url": "https://github.com/hyperf/memory.git", + "reference": "74a3093ee766e18f912269f6846a63ae21a4360b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/memory/zipball/74a3093ee766e18f912269f6846a63ae21a4360b", + "reference": "74a3093ee766e18f912269f6846a63ae21a4360b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Memory\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Memory\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An independent component that use to operate and manage memory.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "memory", + "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": "2025-04-03T09:12:55+00:00" + }, + { + "name": "hyperf/model-cache", + "version": "v3.1.51", + "source": { + "type": "git", + "url": "https://github.com/hyperf/model-cache.git", + "reference": "70d1c97364cccef852c505a7eb1fcbfd8a62c1ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/model-cache/zipball/70d1c97364cccef852c505a7eb1fcbfd8a62c1ec", + "reference": "70d1c97364cccef852c505a7eb1fcbfd8a62c1ec", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/db-connection": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "suggest": { + "hyperf/event": "Required to use DeleteCacheListener." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\ModelCache\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ModelCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A model cache component for hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "model-cache", + "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": "2025-02-06T07:02:37+00:00" + }, + { + "name": "hyperf/model-listener", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/model-listener.git", + "reference": "0181882fb6034cf2eac81b84b5c65c187af9f3a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/model-listener/zipball/0181882fb6034cf2eac81b84b5c65c187af9f3a4", + "reference": "0181882fb6034cf2eac81b84b5c65c187af9f3a4", + "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": { + "hyperf": { + "config": "Hyperf\\ModelListener\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/nacos", + "version": "v3.1.52", + "source": { + "type": "git", + "url": "https://github.com/hyperf/nacos.git", + "reference": "6d4bd0551ce4d4581ebe126c3e47962ce72baa01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/nacos/zipball/6d4bd0551ce4d4581ebe126c3e47962ce72baa01", + "reference": "6d4bd0551ce4d4581ebe126c3e47962ce72baa01", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.5 || ^7.0", + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "jetbrains/phpstorm-attributes": "^1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Nacos\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Nacos\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Nacos SDK", + "keywords": [ + "hyperf", + "nacos", + "php" + ], + "support": { + "issues": "https://github.com/hyperf/nacos/issues", + "source": "https://github.com/hyperf/nacos/tree/v3.1.52" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-02-27T06:49:30+00:00" + }, + { + "name": "hyperf/pipeline", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/pipeline.git", + "reference": "096d9a9f87ddea33209f134d30ae8d8867a195c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/pipeline/zipball/096d9a9f87ddea33209f134d30ae8d8867a195c7", + "reference": "096d9a9f87ddea33209f134d30ae8d8867a195c7", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/pool", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/pool.git", + "reference": "004dd811bf760ea0032913a31284102742abb737" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/pool/zipball/004dd811bf760ea0032913a31284102742abb737", + "reference": "004dd811bf760ea0032913a31284102742abb737", + "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" + }, + "suggest": { + "psr/event-dispatcher": "Required to use events." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Pool\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/process", + "version": "v3.1.48", + "source": { + "type": "git", + "url": "https://github.com/hyperf/process.git", + "reference": "8d68398bdb4f2623af1bec846399b6ce29bd7d2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/process/zipball/8d68398bdb4f2623af1bec846399b6ce29bd7d2c", + "reference": "8d68398bdb4f2623af1bec846399b6ce29bd7d2c", + "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": { + "hyperf": { + "config": "Hyperf\\Process\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-12-02T10:54:30+00:00" + }, + { + "name": "hyperf/rate-limit", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/rate-limit.git", + "reference": "72767891017ad44420b80a9c4b9cbb7f009c3676" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/rate-limit/zipball/72767891017ad44420b80a9c4b9cbb7f009c3676", + "reference": "72767891017ad44420b80a9c4b9cbb7f009c3676", + "shasum": "" + }, + "require": { + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "hyperf/token-bucket": "^2.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" + }, + "suggest": { + "hyperf/contract": "Required to use annotations.", + "hyperf/di": "Required to use annotations.", + "hyperf/http-server": "Required to use annotations.", + "hyperf/redis": "Required to use RedisStorage." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\RateLimit\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\RateLimit\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A rate limiter implemented for Hyperf or other coroutine framework", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "rate-limiter", + "token-bucket" + ], + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/redis", + "version": "v3.1.53", + "source": { + "type": "git", + "url": "https://github.com/hyperf/redis.git", + "reference": "d481e97926d8e12b41bfeb1ebf5d88e66482da64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/redis/zipball/d481e97926d8e12b41bfeb1ebf5d88e66482da64", + "reference": "d481e97926d8e12b41bfeb1ebf5d88e66482da64", + "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": { + "hyperf": { + "config": "Hyperf\\Redis\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2025-04-03T07:31:20+00:00" + }, + { + "name": "hyperf/rpc", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/rpc.git", + "reference": "90e97635c0e3c5080e422abdfc1399fd57ee204f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/rpc/zipball/90e97635c0e3c5080e422abdfc1399fd57ee204f", + "reference": "90e97635c0e3c5080e422abdfc1399fd57ee204f", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "jetbrains/phpstorm-attributes": "^1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "hyperf": [], + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Rpc\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A rpc basic library for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "rpc", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/rpc-client", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/rpc-client.git", + "reference": "40f38de55fffcd8d77e683d69a812913cc1ce201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/rpc-client/zipball/40f38de55fffcd8d77e683d69a812913cc1ce201", + "reference": "40f38de55fffcd8d77e683d69a812913cc1ce201", + "shasum": "" + }, + "require": { + "hyperf/code-parser": "~3.1.0", + "hyperf/load-balancer": "~3.1.0", + "hyperf/rpc": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "jetbrains/phpstorm-attributes": "^1.0", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0" + }, + "suggest": { + "hyperf/di": "For better container experience.", + "hyperf/pool": "Required to use connection pool.", + "hyperf/service-governance": "Required to fetch the nodes info from service governance." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\RpcClient\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\RpcClient\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An abstract rpc server component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "json-rpc", + "php", + "rpc", + "rpc-client", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/rpc-server", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/rpc-server.git", + "reference": "5647c5fd54342fe96aa2198e7fdeb8ee50cfc30c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/rpc-server/zipball/5647c5fd54342fe96aa2198e7fdeb8ee50cfc30c", + "reference": "5647c5fd54342fe96aa2198e7fdeb8ee50cfc30c", + "shasum": "" + }, + "require": { + "hyperf/http-server": "~3.1.0", + "hyperf/rpc": "~3.1.0", + "php": ">=8.1" + }, + "suggest": { + "hyperf/di": "Required to use annotations." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\RpcServer\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\RpcServer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An abstract rpc server component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "rpc", + "rpc-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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/serializer", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/serializer.git", + "reference": "03c8a4840e0a7be83670c2fb0f850a2204fad076" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/serializer/zipball/03c8a4840e0a7be83670c2fb0f850a2204fad076", + "reference": "03c8a4840e0a7be83670c2fb0f850a2204fad076", + "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": { + "hyperf": { + "config": "Hyperf\\Serializer\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/server", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/server.git", + "reference": "e10c5ce6d9b72d3ca9ad16d36977e2e64d975460" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/server/zipball/e10c5ce6d9b72d3ca9ad16d36977e2e64d975460", + "reference": "e10c5ce6d9b72d3ca9ad16d36977e2e64d975460", + "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": { + "hyperf": { + "config": "Hyperf\\Server\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/service-governance", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/service-governance.git", + "reference": "e4e606f86d40fd3630e688d23870944d1b7b7db1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/service-governance/zipball/e4e606f86d40fd3630e688d23870944d1b7b7db1", + "reference": "e4e606f86d40fd3630e688d23870944d1b7b7db1", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/support": "~3.1.0", + "jetbrains/phpstorm-attributes": "^1.0", + "php": ">=8.1" + }, + "suggest": { + "hyperf/event": "Required to use RegisterServiceListener.", + "hyperf/framework": "Required to use RegisterServiceListener.", + "hyperf/service-governance-consul": "Required to use consul adapter.", + "hyperf/service-governance-nacos": "Required to use nacos adapter." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\ServiceGovernance\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ServiceGovernance\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A service governance component for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "php", + "service-governance", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/service-governance-nacos", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/service-governance-nacos.git", + "reference": "9f85b659c0c6608e902364cfe0d897844447df25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/service-governance-nacos/zipball/9f85b659c0c6608e902364cfe0d897844447df25", + "reference": "9f85b659c0c6608e902364cfe0d897844447df25", + "shasum": "" + }, + "require": { + "hyperf/codec": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/nacos": "~3.1.0", + "hyperf/service-governance": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\ServiceGovernanceNacos\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\ServiceGovernanceNacos\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A nacos adapter for service governance.", + "homepage": "https://hyperf.io", + "keywords": [ + "hyperf", + "nacos-adapter", + "php", + "service-governance", + "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-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/stdlib", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/stdlib.git", + "reference": "13393734a4cc6c9878390b1f6b0fc7e5202c6b59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/stdlib/zipball/13393734a4cc6c9878390b1f6b0fc7e5202c6b59", + "reference": "13393734a4cc6c9878390b1f6b0fc7e5202c6b59", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/stringable", + "version": "v3.1.55", + "source": { + "type": "git", + "url": "https://github.com/hyperf/stringable.git", + "reference": "1ce51e8c73609898da6b0b9ab80a14508fa671d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/stringable/zipball/1ce51e8c73609898da6b0b9ab80a14508fa671d7", + "reference": "1ce51e8c73609898da6b0b9ab80a14508fa671d7", + "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": "2025-05-02T14:13:24+00:00" + }, + { + "name": "hyperf/support", + "version": "v3.1.51", + "source": { + "type": "git", + "url": "https://github.com/hyperf/support.git", + "reference": "8d630b496945f3ac791a570fe6c1bf481c3f28ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/support/zipball/8d630b496945f3ac791a570fe6c1bf481c3f28ed", + "reference": "8d630b496945f3ac791a570fe6c1bf481c3f28ed", + "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": "2025-02-06T07:02:37+00:00" + }, + { + "name": "hyperf/tappable", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/tappable.git", + "reference": "f5c5d343c95238dcb3fe500876ceadc175e221f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/tappable/zipball/f5c5d343c95238dcb3fe500876ceadc175e221f8", + "reference": "f5c5d343c95238dcb3fe500876ceadc175e221f8", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/token-bucket", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/hyperf/token-bucket.git", + "reference": "7ebb9e7d01d3daecf23b80502b2adffd2fcb2283" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/token-bucket/zipball/7ebb9e7d01d3daecf23b80502b2adffd2fcb2283", + "reference": "7ebb9e7d01d3daecf23b80502b2adffd2fcb2283", + "shasum": "" + }, + "require": { + "ext-bcmath": "*", + "malkusch/lock": "^2.0", + "php": "^8.0" + }, + "replace": { + "bandwidth-throttle/token-bucket": "2.0.0" + }, + "require-dev": { + "mikey179/vfsstream": "^1.5.0", + "mockery/mockery": "^1.5", + "php-mock/php-mock-phpunit": "^2.6", + "phpunit/phpunit": "^9.0", + "predis/predis": "^1" + }, + "type": "library", + "autoload": { + "psr-4": { + "bandwidthThrottle\\tokenBucket\\": "classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "WTFPL" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de", + "role": "Developer" + }, + { + "name": "Hyperf Developers", + "email": "group@hyperf.io" + } + ], + "description": "Implementation of the Token Bucket algorithm.", + "homepage": "https://github.com/bandwidth-throttle/token-bucket", + "keywords": [ + "bandwidth", + "rate limit", + "rate limiting", + "throttle", + "throttling", + "token bucket" + ], + "support": { + "source": "https://github.com/hyperf/token-bucket/tree/v2.0.0" + }, + "time": "2023-01-07T12:45:03+00:00" + }, + { + "name": "hyperf/translation", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/translation.git", + "reference": "0bca5490a99b0ea5200d5753fd096338ec24c25f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/translation/zipball/0bca5490a99b0ea5200d5753fd096338ec24c25f", + "reference": "0bca5490a99b0ea5200d5753fd096338ec24c25f", + "shasum": "" + }, + "require": { + "hyperf/contract": "~3.1.0", + "hyperf/macroable": "~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": { + "hyperf": { + "config": "Hyperf\\Translation\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Hyperf\\Translation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An independent translation component, forked by illuminate/translation.", + "keywords": [ + "hyperf", + "translation" + ], + "support": { + "issues": "https://github.com/hyperf/translation/issues", + "source": "https://github.com/hyperf/translation/tree/v3.1.42" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/utils", + "version": "v3.1.42", + "source": { + "type": "git", + "url": "https://github.com/hyperf/utils.git", + "reference": "4b13a567a61d08a3c4d058499e28a5b26fc18f1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/utils/zipball/4b13a567a61d08a3c4d058499e28a5b26fc18f1c", + "reference": "4b13a567a61d08a3c4d058499e28a5b26fc18f1c", + "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": "2024-09-25T02:54:12+00:00" + }, + { + "name": "hyperf/validation", + "version": "v3.1.53", + "source": { + "type": "git", + "url": "https://github.com/hyperf/validation.git", + "reference": "476ccad33326073cd07ca66b7c6d5c1f4f3c7f53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/validation/zipball/476ccad33326073cd07ca66b7c6d5c1f4f3c7f53", + "reference": "476ccad33326073cd07ca66b7c6d5c1f4f3c7f53", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^3.0", + "hyperf/collection": "~3.1.0", + "hyperf/conditionable": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/di": "~3.1.0", + "hyperf/framework": "~3.1.0", + "hyperf/macroable": "~3.1.0", + "hyperf/stringable": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/tappable": "~3.1.0", + "hyperf/translation": "~3.1.0", + "hyperf/utils": "~3.1.0", + "nesbot/carbon": "^2.21", + "php": ">=8.1", + "psr/container": "^1.0 || ^2.0", + "psr/event-dispatcher": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "suggest": { + "hyperf/database": "Required if you want to use the database validation rule (~3.1.0).", + "hyperf/http-server": "Required if you want to use the request validation rule (~3.1.0)." + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Validation\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Validation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "hyperf validation", + "keywords": [ + "hyperf", + "validation" + ], + "support": { + "issues": "https://github.com/hyperf/validation/issues", + "source": "https://github.com/hyperf/validation/tree/v3.1.53" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-04-03T07:47:47+00:00" + }, + { + "name": "jetbrains/phpstorm-attributes", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/JetBrains/phpstorm-attributes.git", + "reference": "64de815a4509c29e00d5e3474087fd24c171afc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JetBrains/phpstorm-attributes/zipball/64de815a4509c29e00d5e3474087fd24c171afc2", + "reference": "64de815a4509c29e00d5e3474087fd24c171afc2", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "JetBrains\\PhpStorm\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "JetBrains", + "homepage": "https://www.jetbrains.com" + } + ], + "description": "PhpStorm specific attributes", + "keywords": [ + "attributes", + "jetbrains", + "phpstorm" + ], + "support": { + "issues": "https://youtrack.jetbrains.com/newIssue?project=WI", + "source": "https://github.com/JetBrains/phpstorm-attributes/tree/1.2" + }, + "time": "2024-10-11T10:46:19+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" + } + ], + "abandoned": "symfony/mime", + "time": "2023-11-02T16:47:19+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.20.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "conflict": { + "zendframework/zend-stdlib": "*" + }, + "require-dev": { + "laminas/laminas-coding-standard": "^3.0", + "phpbench/phpbench": "^1.3.1", + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.26.1" + }, + "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-10-29T13:46:07+00:00" + }, + { + "name": "malkusch/lock", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-lock/lock.git", + "reference": "66ccdccbb3b9a2cabdeba077f6aa1759dd3fbcd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-lock/lock/zipball/66ccdccbb3b9a2cabdeba077f6aa1759dd3fbcd2", + "reference": "66ccdccbb3b9a2cabdeba077f6aa1759dd3fbcd2", + "shasum": "" + }, + "require": { + "php": ">=7.4 <8.4", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "require-dev": { + "eloquent/liberator": "^2.0 || ^3.0", + "ergebnis/composer-normalize": "^2.13", + "ergebnis/phpunit-slow-test-detector": "^2.9", + "ext-memcached": "*", + "ext-pcntl": "*", + "ext-pdo": "*", + "ext-pdo_mysql": "*", + "ext-pdo_sqlite": "*", + "ext-sysvsem": "*", + "friendsofphp/php-cs-fixer": "^3.0", + "mikey179/vfsstream": "^1.6.11", + "php-mock/php-mock-phpunit": "^2.1", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.5.25 || ^10.0 || ^11.0", + "predis/predis": "^1.1.8", + "spatie/async": "^1.5" + }, + "suggest": { + "ext-igbinary": "To use this library with PHP Redis igbinary serializer enabled.", + "ext-lzf": "To use this library with PHP Redis lzf compression enabled.", + "ext-pnctl": "Enables locking with flock without busy waiting in CLI scripts.", + "ext-redis": "To use this library with the PHP Redis extension.", + "ext-sysvsem": "Enables locking using semaphores.", + "predis/predis": "To use this library with predis." + }, + "type": "library", + "autoload": { + "psr-4": { + "malkusch\\lock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Malkusch", + "email": "markus@malkusch.de", + "homepage": "http://markus.malkusch.de" + }, + { + "name": "Willem Stuursma-Ruwen", + "email": "willem@stuursma.name" + }, + { + "name": "Michael Voříšek", + "homepage": "https://mvorisek.cz/" + } + ], + "description": "Mutex library for exclusive code execution.", + "homepage": "https://github.com/malkusch/lock", + "keywords": [ + "advisory-locks", + "cas", + "flock", + "lock", + "locking", + "memcache", + "mutex", + "mysql", + "postgresql", + "redis", + "redlock", + "semaphore" + ], + "support": { + "issues": "https://github.com/php-lock/lock/issues", + "source": "https://github.com/php-lock/lock/tree/2.3.0" + }, + "time": "2024-12-05T22:54:07+00:00" + }, + { + "name": "markrogoyski/math-php", + "version": "v2.11.0", + "source": { + "type": "git", + "url": "https://github.com/markrogoyski/math-php.git", + "reference": "ae499f31513821a62f3d2fb8c6f0d3a333e8b591" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/markrogoyski/math-php/zipball/ae499f31513821a62f3d2fb8c6f0d3a333e8b591", + "reference": "ae499f31513821a62f3d2fb8c6f0d3a333e8b591", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phploc/phploc": "*", + "phpmd/phpmd": "^2.6", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MathPHP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Rogoyski", + "email": "mark@rogoyski.com", + "homepage": "https://github.com/markrogoyski", + "role": "Lead developer" + }, + { + "name": "Kevin Nowaczyk", + "homepage": "https://github.com/Beakerboy", + "role": "Developer" + }, + { + "name": "MathPHP Community of Contributors", + "homepage": "https://github.com/markrogoyski/math-php/graphs/contributors" + } + ], + "description": "Math Library for PHP. Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra", + "homepage": "https://github.com/markrogoyski/math-php/", + "keywords": [ + "algebra", + "combinatorics", + "distributions", + "linear algebra", + "math", + "mathematics", + "matrix", + "numerical analysis", + "probability", + "regressions", + "statistics" + ], + "support": { + "issues": "https://github.com/markrogoyski/math-php/issues", + "source": "https://github.com/markrogoyski/math-php/tree/v2.11.0" + }, + "time": "2025-01-26T20:16:06+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2025-03-24T10:02:05+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.73.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/9228ce90e1035ff2f0db84b40ec2e023ed802075", + "reference": "9228ce90e1035ff2f0db84b40ec2e023ed802075", + "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": "<6", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.99 || ^1.7.14", + "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", + "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2025-01-08T20:10:23+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.19.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.1" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^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.19.4" + }, + "time": "2024-09-29T15:01:53+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4|^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2024-05-08T12:36:18+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "php-amqplib/php-amqplib", + "version": "v3.7.3", + "source": { + "type": "git", + "url": "https://github.com/php-amqplib/php-amqplib.git", + "reference": "9f50fe69a9f1a19e2cb25596a354d705de36fe59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/9f50fe69a9f1a19e2cb25596a354d705de36fe59", + "reference": "9f50fe69a9f1a19e2cb25596a354d705de36fe59", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-sockets": "*", + "php": "^7.2||^8.0", + "phpseclib/phpseclib": "^2.0|^3.0" + }, + "conflict": { + "php": "7.4.0 - 7.4.1" + }, + "replace": { + "videlalvaro/php-amqplib": "self.version" + }, + "require-dev": { + "ext-curl": "*", + "nategood/httpful": "^0.2.20", + "phpunit/phpunit": "^7.5|^9.5", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpAmqpLib\\": "PhpAmqpLib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Alvaro Videla", + "role": "Original Maintainer" + }, + { + "name": "Raúl Araya", + "email": "nubeiro@gmail.com", + "role": "Maintainer" + }, + { + "name": "Luke Bakken", + "email": "luke@bakken.io", + "role": "Maintainer" + }, + { + "name": "Ramūnas Dronga", + "email": "github@ramuno.lt", + "role": "Maintainer" + } + ], + "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", + "homepage": "https://github.com/php-amqplib/php-amqplib/", + "keywords": [ + "message", + "queue", + "rabbitmq" + ], + "support": { + "issues": "https://github.com/php-amqplib/php-amqplib/issues", + "source": "https://github.com/php-amqplib/php-amqplib/tree/v3.7.3" + }, + "time": "2025-02-18T20:11:13+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.3", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:41:07+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.43", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "709ec107af3cb2f385b9617be72af8cf62441d02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/709ec107af3cb2f385b9617be72af8cf62441d02", + "reference": "709ec107af3cb2f385b9617be72af8cf62441d02", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.43" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2024-12-14T21:12:59+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/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.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "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.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44", + "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" + }, + "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.3.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": "2025-05-24T10:34:04+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d", + "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d", + "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.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-30T19:00:26+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.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": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.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": "2025-04-25T09:37:31+00:00" + }, + { + "name": "symfony/string", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125", + "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.3.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": "2025-04-20T20:19:01+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.4.22", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "7e3b3b7146c6fab36ddff304a8041174bf6e17ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/7e3b3b7146c6fab36ddff304a8041174bf6e17ad", + "reference": "7e3b3b7146c6fab36ddff304a8041174bf6e17ad", + "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.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/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.22" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-05-29T07:06:44+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\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.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-27T08:32:26+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.2", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.3", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2025-04-30T23:37:27+00:00" + } + ], + "packages-dev": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "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.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.75.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c", + "reference": "399a128ff2fdaf4281e4e79b755693286cdf325c", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.6", + "infection/infection": "^0.29.14", + "justinrainbow/json-schema": "^5.3 || ^6.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12", + "symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3", + "symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2025-03-31T18:40:42+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "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.1.1" + }, + "time": "2025-04-30T06:54:44+00:00" + }, + { + "name": "hyperf/devtool", + "version": "v3.1.51", + "source": { + "type": "git", + "url": "https://github.com/hyperf/devtool.git", + "reference": "b032916fa51293f894046754f596f7d6d71352df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/devtool/zipball/b032916fa51293f894046754f596f7d6d71352df", + "reference": "b032916fa51293f894046754f596f7d6d71352df", + "shasum": "" + }, + "require": { + "hyperf/code-parser": "~3.1.0", + "hyperf/command": "~3.1.0", + "hyperf/contract": "~3.1.0", + "hyperf/di": "~3.1.0", + "hyperf/support": "~3.1.0", + "hyperf/utils": "~3.1.0", + "php": ">=8.1" + }, + "type": "library", + "extra": { + "hyperf": { + "config": "Hyperf\\Devtool\\ConfigProvider" + }, + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Hyperf\\Devtool\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A Devtool for Hyperf.", + "homepage": "https://hyperf.io", + "keywords": [ + "dev", + "devtool", + "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": "2025-02-06T06:42:00+00:00" + }, + { + "name": "hyperf/testing", + "version": "v3.1.55", + "source": { + "type": "git", + "url": "https://github.com/hyperf/testing.git", + "reference": "f7daebdcc7aa4520acf61689f7e2e4049e9247db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hyperf/testing/zipball/f7daebdcc7aa4520acf61689f7e2e4049e9247db", + "reference": "f7daebdcc7aa4520acf61689f7e2e4049e9247db", + "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.55" + }, + "funding": [ + { + "url": "https://hyperf.wiki/#/zh-cn/donate", + "type": "custom" + }, + { + "url": "https://opencollective.com/hyperf", + "type": "open_collective" + } + ], + "time": "2025-05-02T14:13:24+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-05-16T03:13:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-04-29T12:36:36+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.12.27", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "3a6e423c076ab39dfedc307e2ac627ef579db162" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3a6e423c076ab39dfedc307e2ac627ef579db162", + "reference": "3a6e423c076ab39dfedc307e2ac627ef579db162", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-05-21T20:51:45+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.46", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "8080be387a5be380dda48c6f41cee4a13aadab3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8080be387a5be380dda48c6f41cee4a13aadab3d", + "reference": "8080be387a5be380dda48c6f41cee4a13aadab3d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.46" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-05-02T06:46:24+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-18T14:56:07+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:17:12+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "5.1.7", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "c6f9cd0aa1a1e3691ed736253f0cdce381d96cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/c6f9cd0aa1a1e3691ed736253f0cdce381d96cae", + "reference": "c6f9cd0aa1a1e3691ed736253f0cdce381d96cae", + "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.7" + }, + "time": "2025-03-22T23:53:02+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", + "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.3.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": "2025-04-22T09:11:45+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.4.22", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "6b7c97fe1ddac8df3cc9ba6410c8abc683e148ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6b7c97fe1ddac8df3cc9ba6410c8abc683e148ae", + "reference": "6b7c97fe1ddac8df3cc9ba6410c8abc683e148ae", + "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.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" + }, + "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.22" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-05-11T15:36:20+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca", + "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca", + "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.3.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": "2025-04-04T13:12:05+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "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.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "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.3.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": "2025-04-17T09:11:12+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "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.3.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": "2025-02-24T10:49:57+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.3" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/autoload/alibaba.php b/config/autoload/alibaba.php new file mode 100644 index 0000000..61b2f5f --- /dev/null +++ b/config/autoload/alibaba.php @@ -0,0 +1,38 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +use function Hyperf\Support\env; + +return [ + /* + |-------------------------------------------------------------------------- + | Aliases + |-------------------------------------------------------------------------- + | + | + */ + + 'accessKeyId' => env('ALI_ACCESS_KEY_ID', ''), + 'accessKeySecret' => env('ALI_ACCESS_KEY_SECRET', ''), + + 'oss' => [ + 'oss_endpoint' => env('OSS_ENDPOINT', ''), + ], + 'logs' => [ + 'log_endpoint' => env('LOG_ENDPOINT', ''), + 'log_project' => env('LOG_PROJECT', ''), + 'log_store' => env('LOG_STORE', ''), + ], +]; \ No newline at end of file diff --git a/config/autoload/amqp.php b/config/autoload/amqp.php new file mode 100644 index 0000000..4c881df --- /dev/null +++ b/config/autoload/amqp.php @@ -0,0 +1,42 @@ + [ + 'host' => env('AMQP_HOST', 'localhost'), + 'port' => (int) env('AMQP_PORT', 5672), + 'user' => env('AMQP_USER', 'guest'), + 'password' => env('AMQP_PASSWORD', 'guest'), + 'vhost' => env('AMQP_VHOST', '/'), + 'concurrent' => [ + 'limit' => 1, + ], + 'pool' => [ + 'connections' => 2, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3, + 'read_write_timeout' => 6, + 'context' => null, + 'keepalive' => true, + 'heartbeat' => 3, + 'channel_rpc_timeout' => 0.0, + 'close_on_destruct' => false, + 'max_idle_channels' => 10, + ], + ], +]; diff --git a/config/autoload/annotations.php b/config/autoload/annotations.php new file mode 100644 index 0000000..1423a25 --- /dev/null +++ b/config/autoload/annotations.php @@ -0,0 +1,21 @@ + [ + 'paths' => [ + BASE_PATH . '/app', + ], + 'ignore_annotations' => [ + 'mixin', + ], + ], +]; diff --git a/config/autoload/aspects.php b/config/autoload/aspects.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/aspects.php @@ -0,0 +1,13 @@ + [ + 'driver' => RedisDriver::class, + 'redis' => [ + 'pool' => 'default', + ], + 'channel' => '{queue}', + 'timeout' => 2, + 'retry_seconds' => 5, + 'handle_timeout' => 10, + 'processes' => 1, + 'concurrent' => [ + 'limit' => 10, + ], + 'max_messages' => 0, + ], + 'whf' => [ + 'driver' => RedisDriver::class, + 'redis' => [ + 'pool' => 'default', + ], + 'channel' => '{drp.custom}', + 'timeout' => 2, + 'retry_seconds' => 5, + 'handle_timeout' => 10, + 'processes' => 1, + 'concurrent' => [ + 'limit' => 10, + ], + 'max_messages' => 0, + ], +]; diff --git a/config/autoload/cache.php b/config/autoload/cache.php new file mode 100644 index 0000000..24d0e5b --- /dev/null +++ b/config/autoload/cache.php @@ -0,0 +1,19 @@ + [ + 'driver' => Hyperf\Cache\Driver\RedisDriver::class, + 'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class, + 'prefix' => 'c:', + 'skip_cache_results' => [], + ], +]; diff --git a/config/autoload/commands.php b/config/autoload/commands.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/commands.php @@ -0,0 +1,13 @@ + [ + 'driver' => env('DB_DRIVER', 'mysql'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', 3306), + 'database' => env('DB_DATABASE', 'hyperf'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => env('DB_PREFIX', ''), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60), + ], + 'cache' => [ + 'handler' => Hyperf\ModelCache\Handler\RedisHandler::class, + 'cache_key' => '{mc:%s:m:%s}:%s:%s', + 'prefix' => 'default', + 'ttl' => 3600 * 24, + 'empty_model_ttl' => 600, + 'load_script' => true, + ], + 'commands' => [ + 'gen:model' => [ + 'path' => 'app/Model', + 'force_casts' => true, + 'inheritance' => 'Model', + 'uses' => '', + 'table_mapping' => [], + ], + ], + ], +]; diff --git a/config/autoload/dependencies.php b/config/autoload/dependencies.php new file mode 100644 index 0000000..06fc625 --- /dev/null +++ b/config/autoload/dependencies.php @@ -0,0 +1,27 @@ + StdoutLoggerFactory::class, + UserAuthServiceInterface::class => UserAuthServiceConsumer::class, + EasyAppServiceInterface::class => EasyAppServiceConsumer::class, + InventoryServiceInterface::class => InventoryServiceConsumer::class, +]; diff --git a/config/autoload/devtool.php b/config/autoload/devtool.php new file mode 100644 index 0000000..3c2f607 --- /dev/null +++ b/config/autoload/devtool.php @@ -0,0 +1,44 @@ + [ + 'amqp' => [ + 'consumer' => [ + 'namespace' => 'App\\Amqp\\Consumer', + ], + 'producer' => [ + 'namespace' => 'App\\Amqp\\Producer', + ], + ], + 'aspect' => [ + 'namespace' => 'App\\Aspect', + ], + 'command' => [ + 'namespace' => 'App\\Command', + ], + 'controller' => [ + 'namespace' => 'App\\Controller', + ], + 'job' => [ + 'namespace' => 'App\\Job', + ], + 'listener' => [ + 'namespace' => 'App\\Listener', + ], + 'middleware' => [ + 'namespace' => 'App\\Middleware', + ], + 'Process' => [ + 'namespace' => 'App\\Processes', + ], + ], +]; diff --git a/config/autoload/exceptions.php b/config/autoload/exceptions.php new file mode 100644 index 0000000..63f4b26 --- /dev/null +++ b/config/autoload/exceptions.php @@ -0,0 +1,25 @@ + [ + 'http' => [ + HttpExceptionHandler::class, + AppExceptionHandler::class, + ApiExceptionHandler::class, + ], + ], +]; diff --git a/config/autoload/listeners.php b/config/autoload/listeners.php new file mode 100644 index 0000000..8a2c7a2 --- /dev/null +++ b/config/autoload/listeners.php @@ -0,0 +1,15 @@ + JsonFormatter::class, + 'constructor' => [ + 'format' => null, + 'dateFormat' => 'Y-m-d H:i:s', + 'allowInlineLineBreaks' => true, + ], + ] + : [ + 'class' => LineFormatter::class, + 'constructor' => [ + 'format' => "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", + 'dateFormat' => 'Y-m-d H:i:s', + 'allowInlineLineBreaks' => true, + ], + ]; + +$loggers = [ + 'default', 'sql', 'request', 'crontab', 'queue', 'timer', 'job', 'some', 'amqp' +]; + +$logLevel = $isProduction ? $productionLogLevel : LogLevel::INFO; + +$config = []; + +foreach ($loggers as $loggerName) { + $handler = $isProduction + ? [ + 'class' => AliSlsHandler::class, + 'constructor' => [ + 'filename' => BASE_PATH . sprintf('/runtime/logs/%s/%s.log', $loggerName, $loggerName), + 'level' => $logLevel, + 'maxFiles' => 30, + ], + ] + : [ + 'class' => RotatingFileHandler::class, + 'constructor' => [ + 'filename' => BASE_PATH . sprintf('/runtime/logs/%s/%s.log', $loggerName, $loggerName), + 'level' => $logLevel, + 'maxFiles' => 30, + ], + ]; + + $config[$loggerName] = [ + 'handler' => $handler, + 'formatter' => $formatter, + 'processors' => [ + [ + 'class' => AppendRequestIdProcessor::class, + ], + ], + ]; +} + +return $config; diff --git a/config/autoload/menu.php b/config/autoload/menu.php new file mode 100644 index 0000000..aa28c5d --- /dev/null +++ b/config/autoload/menu.php @@ -0,0 +1,1099 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +######################################################################################################### +### 'cancels_recursion' => true, 递归取消,当有下级隐藏域存在时,取消递归,前端标识 +### 'affix' => true, 字体选中标识,默认为false,选中时请设置为true +######################################################################################################### + +return [ + 'menu' => [ + [ + 'name' => 'home', + 'path' => '/home', + 'meta' => [ + 'title' => '首页', + 'code' => 'permission_home', + 'icon' => 'sc-icon-home', + 'type' => 'menu', + ], + 'actions' => ['sysHome'], + 'children' => [ + [ + 'name' => 'dashboard', + 'path' => '/dashboard', + 'meta' => [ + 'title' => '数据统计', + 'code' => 'permission_controller', + 'icon' => 'sc-icon-controller', + 'affix' => true, + ], + 'actions' => ['sysMenu'], + 'component' => 'home', + ], [ + 'name' => 'userCenter', + 'path' => '/user/center', + 'meta' => [ + 'title' => '个人中心', + 'code' => 'permission_account_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => ['updateMe', 'bindMobile'], + 'component' => 'userCenter', + ], + ], + ], + [ + 'name' => 'purchase', + 'path' => '/purchase', + 'meta' => [ + 'title' => '提货', + 'code' => 'permission_purchase', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'purchaseOrder', + 'path' => '/purchase/order', + 'meta' => [ + 'title' => '提货单据', + 'code' => 'permission_purchase_order', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'purchaseIn', + 'path' => '/purchase/order/purchase_in', + 'meta' => [ + 'title' => '自建提货单', + 'code' => 'permission_purchase_order_purchase_in', + 'icon' => 'sc-icon-data-confirm', + ], + 'actions' => ['flowLineForPurchaseInbound', 'purchaseOrderContractDetail', 'listOrderByOrderType'], + 'component' => 'purchase/order/purchase_in', + 'cancels_recursion' => true, + 'children' => [ + [ + 'name' => 'purchaseContractUrl', + 'path' => '/purchase/order/purchase_in/contract_url', + 'meta' => [ + 'title' => '提货明细', + 'code' => 'permission_purchase_order_purchase_in_contract_url', + 'icon' => 'sc-icon-data-confirm', + 'hidden' => true, + ], + 'actions' => ['mark_contract_url'], + 'component' => 'purchase/order/purchase_in/contract_url', + 'children' => [], + ] + ], + ], + ], + ], + [ + 'name' => 'orderQuery', + 'path' => '/purchase/purchase/order_query', + 'meta' => [ + 'title' => '单据列表', + 'code' => 'permission_purchase_order_query', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => ['permission_purchase_order_query_purchase_in' + , 'detailDeliveryOrder', 'deliveryOrderSearchBar', 'listPurchaseOrderContract'], + 'children' => [ + [ + 'name' => 'purchaseOrderQuery', + 'path' => '/purchase/order_query/purchase', + 'meta' => [ + 'title' => '待审核提货单', + 'code' => 'permission_purchase_order_query_purchase', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['getLaseReviewRecord', 'listContractSearchBar'], + 'component' => 'purchase/order_query/purchaseForm', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseListForm', + 'path' => '/purchase/order_query/list', + 'meta' => [ + 'title' => '司机端车辆状态', + 'code' => 'permission_purchase_order_query_list', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['orderStatisticsSearchBar'], + 'component' => 'purchase/order_query/list', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseStatisticsForm', + 'path' => '/purchase/order_query/statistics', + 'meta' => [ + 'title' => '现场装车', + 'code' => 'permission_purchase_order_query_statistics', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['purchaseOrderGoodsStatisticsListSearchBar'], + 'component' => 'purchase/order_query/statistics', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseStatisticsForm', + 'path' => '/purchase/order_query/statistics', + 'meta' => [ + 'title' => '放行状态', + 'code' => 'permission_purchase_order_query_statistics', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['purchaseOrderGoodsStatisticsListSearchBar'], + 'component' => 'purchase/order_query/statistics', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseStatisticsForm', + 'path' => '/purchase/order_query/statistics', + 'meta' => [ + 'title' => '货权状态', + 'code' => 'permission_purchase_order_query_statistics', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['purchaseOrderGoodsStatisticsListSearchBar'], + 'component' => 'purchase/order_query/statistics', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseStatisticsForm', + 'path' => '/purchase/order_query/statistics', + 'meta' => [ + 'title' => '提货单出库确认', + 'code' => 'permission_purchase_order_query_statistics', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['purchaseOrderGoodsStatisticsListSearchBar'], + 'component' => 'purchase/order_query/statistics', + 'children' => [ + ], + ], + [ + 'name' => 'purchaseStatisticsForm', + 'path' => '/purchase/order_query/statistics', + 'meta' => [ + 'title' => '提货单核销', + 'code' => 'permission_purchase_order_query_statistics', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['purchaseOrderGoodsStatisticsListSearchBar'], + 'component' => 'purchase/order_query/statistics', + 'children' => [ + ], + ], + ], + ], + ], + ], + [ + 'name' => 'stock', + 'path' => '/stock', + 'meta' => [ + 'title' => '库存', + 'code' => 'permission_stock', + 'icon' => 'sc-icon-stock', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'stockOrder', + 'path' => '/stock/order', + 'meta' => [ + 'title' => '库存单据', + 'code' => 'permission_stock_order', + 'icon' => 'sc-icon-stock', + 'type' => 'menu', + ], + 'actions' => ['stockOrderList', 'detailOrder', 'stockOrderSearchBar', 'stockGoodsSummaryList', 'stockSummarySearchBar', + 'stockGoodsList', 'listStockGoods', 'stockGoodsListSearchBar', 'getCategory'], + 'children' => [ + [ + 'name' => 'inbound', + 'path' => '/stock/order/inbound', + 'meta' => [ + 'title' => '新增入库单', + 'code' => 'permission_stock_order_inbound', + 'icon' => 'sc-icon-stock', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'stock/order/inbound', + 'children' => [], + ], + ], + ], + [ + 'name' => 'stockQuery', + 'path' => '/stock/query', + 'meta' => [ + 'title' => '仓库库存查询', + 'code' => 'permission_stock_query', + 'icon' => 'sc-icon-stock', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'stockOtherForm', + 'path' => '/stock/query/other', + 'meta' => [ + 'title' => '仓库入库单查询', + 'code' => 'permission_stock_query_other', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'stock/query/other', + 'children' => [ + ], + ], + [ + 'name' => 'stockListForm', + 'path' => '/stock/query/details', + 'meta' => [ + 'title' => '入库明细列表', + 'code' => 'permission_stock_query_detail', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['listGoodsInOutRecord', 'goodsInOutRecordSearchBar', 'scanGoodsCodeShowDetail', 'stockGoodsInOutCategory'], + 'component' => 'stock/query', + 'children' => [ + ], + ], + [ + 'name' => 'stockListForm', + 'path' => '/stock/query/details', + 'meta' => [ + 'title' => '明细库存', + 'code' => 'permission_stock_query_detail', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['listGoodsInOutRecord', 'goodsInOutRecordSearchBar', 'scanGoodsCodeShowDetail', 'stockGoodsInOutCategory'], + 'component' => 'stock/query', + 'children' => [ + ], + ], + [ + 'name' => 'stockListForm', + 'path' => '/stock/query/details', + 'meta' => [ + 'title' => '汇总库存', + 'code' => 'permission_stock_query_detail', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['listGoodsInOutRecord', 'goodsInOutRecordSearchBar', 'scanGoodsCodeShowDetail', 'stockGoodsInOutCategory'], + 'component' => 'stock/query', + 'children' => [ + ], + ], + ], + ], + [ + 'name' => 'stockQuery', + 'path' => '/stock/query', + 'meta' => [ + 'title' => '质押库存查询', + 'code' => 'permission_stock_query', + 'icon' => 'sc-icon-stock', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'stockOtherForm', + 'path' => '/stock/query/other', + 'meta' => [ + 'title' => '质押库存明细', + 'code' => 'permission_stock_query_other', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'stock/query/other', + 'children' => [ + ], + ], + [ + 'name' => 'stockListForm', + 'path' => '/stock/query/details', + 'meta' => [ + 'title' => '质押库存汇总', + 'code' => 'permission_stock_query_detail', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => ['listGoodsInOutRecord', 'goodsInOutRecordSearchBar', 'scanGoodsCodeShowDetail', 'stockGoodsInOutCategory'], + 'component' => 'stock/query', + 'children' => [ + ], + ], + ], + ], + ], + ], + [ + 'name' => 'finance', + 'path' => '/finance', + 'meta' => [ + 'title' => '金融', + 'code' => 'permission_finance_mag', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance', + 'children' => [ + [ + 'name' => 'query', + 'path' => '/finance/query', + 'meta' => [ + 'title' => '单据查询', + 'code' => 'permission_finance_query', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance', + 'children' => [ + [ + 'name' => 'costQuery', + 'path' => '/finance/query/cost_query', + 'meta' => [ + 'title' => '融资管理', + 'code' => 'permission_finance_query_cost_query', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/cost_query', + 'children' => [ + ], + ], + [ + 'name' => 'financeInOutQueryForm', + 'path' => '/finance/query/in_out_cost_query', + 'meta' => [ + 'title' => '赎货管理', + 'code' => 'permission_finance_query_inOutCost', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/inOutCost', + 'children' => [ + ], + ], + [ + 'name' => 'financeSettlementPaymentRecord', + 'path' => '/finance/query/payment/record', + 'meta' => [ + 'title' => '收/付款', + 'code' => 'permission_finance_settlement_record', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/query/payment/record', + 'children' => [ + ], + ], + [ + 'name' => 'financePartnerCostListForm', + 'path' => '/finance/query/partner_cost_list', + 'meta' => [ + 'title' => '往来单位应收应付', + 'code' => 'permission_finance_query_partner_cost_list', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [ + 'financePartnerSettlementSearchBar', 'partnerSettlementList', + ], + 'component' => 'finance/partnerCostList', + 'children' => [], + ], + [ + 'name' => 'financeReconciliationRecordForm', + 'path' => '/finance/query/reconciliation/record', + 'meta' => [ + 'title' => '财务对账', + 'code' => 'permission_finance_query_reconciliation', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/reconciliationRecord', + 'children' => [], + ], + ], + ], + [ + 'name' => 'invoiceManage', + 'path' => '/finance/invoice/manage', + 'meta' => [ + 'title' => '发票管理', + 'code' => 'permission_finance_invoice_manage', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => ['generateDocumentNumber', 'invoiceInList', 'mbReadInvoiceOCR', 'mbInvoiceDetail'], + 'component' => '/finance/manage', + 'children' => [ + [ + 'name' => 'invoiceBill', + 'path' => '/finance/invoice/manage/bill', + 'meta' => [ + 'title' => '发票单据', + 'code' => 'permission_finance_invoice_manage_bill', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance/manage/invoice/bill', + 'children' => [], + ], + [ + 'name' => 'invoiceIncomeList', + 'path' => '/finance/invoice/manage/income', + 'meta' => [ + 'title' => '发票进项列表', + 'code' => 'permission_finance_invoice_income_list', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => ['invoiceList', 'invoiceSearchBar'], + 'component' => 'finance/manage/invoice/income', + 'children' => [], + ], + ], + ], + ], + ], + [ + 'name' => 'finance', + 'path' => '/finance', + 'meta' => [ + 'title' => '货权', + 'code' => 'permission_finance_mag', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance', + 'children' => [ + [ + 'name' => 'order', + 'path' => '/finance/order', + 'meta' => [ + 'title' => '货权单据', + 'code' => 'permission_finance_order', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance', + 'children' => [ + [ + 'name' => 'receive', + 'path' => '/finance/order/receive', + 'meta' => [ + 'title' => '创建货权规则', + 'code' => 'permission_finance_order_receive', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/receive', + 'children' => [ + ], + ], + [ + 'name' => 'receive', + 'path' => '/finance/order/receive', + 'meta' => [ + 'title' => '创建监管变更单', + 'code' => 'permission_finance_order_receive', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/receive', + 'children' => [ + ], + ], + [ + 'name' => 'receive', + 'path' => '/finance/order/receive', + 'meta' => [ + 'title' => '创建货权变更单', + 'code' => 'permission_finance_order_receive', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/receive', + 'children' => [ + ], + ] + ], + ], + [ + 'name' => 'query', + 'path' => '/finance/query', + 'meta' => [ + 'title' => '单据查询', + 'code' => 'permission_finance_query', + 'icon' => 'sc-icon-finance-mag', + 'type' => 'menu', + ], + 'actions' => [], + 'component' => 'finance', + 'children' => [ + [ + 'name' => 'costQuery', + 'path' => '/finance/query/cost_query', + 'meta' => [ + 'title' => '控货规则列表', + 'code' => 'permission_finance_query_cost_query', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/cost_query', + 'children' => [ + ], + ], + [ + 'name' => 'financeInOutQueryForm', + 'path' => '/finance/query/in_out_cost_query', + 'meta' => [ + 'title' => '监管变更', + 'code' => 'permission_finance_query_inOutCost', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/inOutCost', + 'children' => [ + ], + ], + [ + 'name' => 'financeSettlementPaymentRecord', + 'path' => '/finance/query/payment/record', + 'meta' => [ + 'title' => '货权变更', + 'code' => 'permission_finance_settlement_record', + 'icon' => 'sc-icon-order-list', + ], + 'actions' => [], + 'component' => 'finance/query/payment/record', + 'children' => [ + ], + ], + ], + ], + ], + ], + [ + 'name' => 'information', + 'path' => '/information', + 'meta' => [ + 'title' => '资料', + 'code' => 'permission_information', + 'icon' => 'sc-icon-information', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'partners', + 'path' => '/information/partners', + 'meta' => [ + 'title' => '三维立体库', + 'code' => 'permission_partners', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'partners', + 'path' => '/information/partners', + 'meta' => [ + 'title' => '管理仓库', + 'code' => 'permission_partners_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/partners', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/information/partners/add-partners', + 'name' => 'add-partners', + 'meta' => [ + 'title' => '添加仓库', + 'code' => 'permission_partners_add', + 'icon' => 'sc-icon-function-add', + 'hidden' => true, + ], + 'actions' => ['mark_partners_add'], + 'component' => 'information/partners/add-partners', + ], + ], + ], + ], + ], + [ + 'name' => 'stockManage', + 'path' => '/information/stock', + 'meta' => [ + 'title' => '商品管理', + 'code' => 'permission_information_stock', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'warehouse', + 'path' => '/information/warehouse', + 'meta' => [ + 'title' => '新增商品', + 'code' => 'permission_warehouse_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/warehouse', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/information/warehouse/add-warehouse', + 'name' => 'add-warehouse', + 'meta' => [ + 'title' => '添加品名', + 'code' => 'permission_warehouse_add', + 'icon' => 'sc-icon-function-add', + 'hidden' => true, + ], + 'actions' => ['mark_warehouse_add'], + 'component' => 'information/warehouse/add-warehouse', + ], + ], + ], + [ + 'name' => 'warehouse', + 'path' => '/information/warehouse', + 'meta' => [ + 'title' => '入库公式', + 'code' => 'permission_warehouse_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/warehouse', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/information/warehouse/add-warehouse', + 'name' => 'add-warehouse', + 'meta' => [ + 'title' => '新增公式', + 'code' => 'permission_warehouse_add', + 'icon' => 'sc-icon-function-add', + 'hidden' => true, + ], + 'actions' => ['mark_warehouse_add'], + 'component' => 'information/warehouse/add-warehouse', + ], + ], + ], + ], + ], + [ + 'name' => 'financeManage', + 'path' => '/information/finance', + 'meta' => [ + 'title' => '单据配置', + 'code' => 'permission_finance', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'costItem', + 'path' => '/information/cost_item', + 'meta' => [ + 'title' => '提货单属性配置', + 'code' => 'permission_costItem_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/costItem', + ], + [ + 'name' => 'bankInfo', + 'path' => '/information/bank_info', + 'meta' => [ + 'title' => '附加服务费配置', + 'code' => 'permission_bank_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/bankInfo', + ], + [ + 'name' => 'bankInfo', + 'path' => '/information/bank_info', + 'meta' => [ + 'title' => '提货单打印配置', + 'code' => 'permission_bank_info', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/bankInfo', + ] + ], + ], + [ + 'name' => 'contract', + 'path' => '/information/contract', + 'meta' => [ + 'title' => '金融配置', + 'code' => 'permission_contract', + 'icon' => 'sc-icon-order', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'templateItem', + 'path' => '/information/template/item', + 'meta' => [ + 'title' => '新增模板', + 'code' => 'permission_template_item', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/template/item', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/information/template/item/add', + 'name' => 'add-template', + 'meta' => [ + 'title' => '创建合同模版', + 'code' => 'permission_template_item_add', + 'icon' => 'sc-icon-function-add', + 'hidden' => true, + ], + 'actions' => [], + 'component' => 'information/template/item/add', + ], + ], + ], + [ + 'name' => 'templateManage', + 'path' => '/information/template/manage', + 'meta' => [ + 'title' => '模板管理', + 'code' => 'permission_template_manage', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'information/template/manage', + 'children' => [ + ], + ], + ], + ], + ], + ], + [ + 'name' => 'AI-Report', + 'path' => '/ai/report', + 'meta' => [ + 'title' => '报表', + 'code' => 'permission_report', + 'icon' => 'sc-icon-product', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'platform', + 'path' => '/setting/platform', + 'meta' => [ + 'title' => '采购/库存报表', + 'code' => 'permission_setting_inv_report', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'aiPurchaseOrderAnalysis', + 'path' => '/ai/purchase', + 'meta' => [ + 'title' => '入库单分析', + 'code' => 'permission_report_purchase_order_analysis', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'ai/purchase', + ], + [ + 'name' => 'aiStockAnalysis', + 'path' => '/ai/stock', + 'meta' => [ + 'title' => '库存分析', + 'code' => 'permission_report_inventory_analysis', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'ai/stock', + ], + ] + ], [ + 'name' => 'platform', + 'path' => '/setting/platform', + 'meta' => [ + 'title' => '财务报表', + 'code' => 'permission_setting_fin_report', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'aiReconciliation', + 'path' => '/ai/reconciliation', + 'meta' => [ + 'title' => '财务对账', + 'code' => 'permission_report_finance_reconciliation', + 'icon' => 'sc-icon-account-info', + ], + 'actions' => [], + 'component' => 'ai/reconciliation', + ], + ] + ] + ] + ], + [ + 'name' => 'setting', + 'path' => '/setting', + 'meta' => [ + 'title' => '系统', + 'code' => 'permission_setting_info', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'name' => 'platform', + 'path' => '/setting/platform', + 'meta' => [ + 'title' => '平台管理', + 'code' => 'permission_setting_platform', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'path' => '/setting/company', + 'name' => 'company', + 'meta' => [ + 'title' => '公司管理', + 'code' => 'permission_company', + 'icon' => 'sc-icon-company', + ], + 'actions' => [], + 'component' => 'setting/company', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/setting/company/add-permission', + 'name' => 'add-permission', + 'meta' => [ + 'title' => '功能授权', + 'code' => 'permission_system_company_permission', + 'icon' => 'sc-icon-function-add', + 'hidden' => true, + ], + 'actions' => ['mark_company_permission'], + 'component' => 'setting/company/add-permission', + ], + [ + 'path' => '/setting/company/add-data-permission', + 'name' => 'add-data-permission', + 'meta' => [ + 'title' => '数据授权', + 'code' => 'permission_system_data_permission', + 'icon' => 'sc-icon-function-data-add', + 'hidden' => true, + ], + 'actions' => ['mark_data_permission'], + 'component' => 'setting/company/add-data-permission', + ], + [ + 'path' => '/setting/user/company-user-list', + 'name' => 'company-user-permission', + 'meta' => [ + 'title' => '用户列表', + 'code' => 'permission_system_user_list', + 'icon' => 'sc-icon-user-company-user-permission', + 'hidden' => true, + ], + 'actions' => ['mark_user_as_list'], + 'component' => 'setting/user/company-user-list', + ], + [ + 'path' => '/setting/log/company-logs', + 'name' => 'company-logs-permission', + 'meta' => [ + 'title' => '操作日志', + 'code' => 'permission_system_company_logs_permission', + 'icon' => 'sc-icon-company-logs-permission', + 'hidden' => true, + ], + 'actions' => ['mark_logs_permission'], + 'component' => 'setting/log/company-logs', + ], + ], + ], + ], + ], + [ + 'name' => 'permission_role', + 'path' => '/setting/permission_role', + 'meta' => [ + 'title' => '权限角色管理', + 'code' => 'permission_setting_permission_role', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'path' => '/setting/user', + 'name' => 'userMag', + 'meta' => [ + 'title' => '用户管理', + 'code' => 'permission_system_user', + 'icon' => 'sc-icon-user-mag', + ], + 'actions' => [ + 'userList', 'userListActive', 'userTypeList', 'userAuditStatusList', 'companyFieldList', + 'deptListActive', 'updateDeptStatus', 'getDeptInfo', 'userInformation', 'listCompanyName', + 'getUserRoles', 'getUserAssignRoles' + ], + 'component' => 'setting/user', + 'cancels_recursion' => true, + 'children' => [ + [ + 'path' => '/setting/user/view-permission', + 'name' => 'repairInfo', + 'meta' => [ + 'title' => '查看权限', + 'code' => 'permission_view_permission', + 'icon' => 'sc-icon-view-permission', + 'hidden' => true, + ], + 'actions' => ['mark_view_permission'], + 'component' => 'setting/user/view-permission', + ], + ], + ], + [ + 'path' => '/setting/role', + 'name' => 'role', + 'meta' => [ + 'title' => '角色管理', + 'code' => 'permission_system_role', + 'icon' => 'sc-icon-role-mag', + ], + 'actions' => ['rolesList', 'roleChecked', 'dataChecked', 'memberSelectList'], + 'component' => 'setting/role', + ], + [ + 'path' => '/setting/dept', + 'name' => 'dept', + 'meta' => [ + 'title' => '部门管理', + 'code' => 'permission_system_dept', + 'icon' => 'sc-icon-role-mag', + ], + 'actions' => ['deptList'], + 'component' => 'setting/dept', + ], + ], + ], + [ + 'name' => 'system', + 'path' => '/setting/system', + 'meta' => [ + 'title' => '系统日志', + 'code' => 'permission_setting_system_logger', + 'icon' => 'sc-icon-system', + 'type' => 'menu', + ], + 'actions' => [], + 'children' => [ + [ + 'path' => '/setting/log', + 'name' => 'log', + 'meta' => [ + 'title' => '操作日志', + 'code' => 'permission_system_log', + 'icon' => 'sc-icon-system-log', + ], + 'actions' => ['sysLogList', 'sysLogOperationList', 'sysLogOperationFieldList'], + 'component' => 'setting/log', + ], + ], + ], + ], + ], + ], + // 数据权限 + 'data_permissions' => [ + 'permission_goods_info' => [ + ['title' => '新增|修改商品', 'actions' => 'addGoods'], + ['title' => '启用|禁用商品', 'actions' => 'goodsStatusChange'], + ['title' => '新增品牌', 'actions' => 'addBrand'], + ['title' => '更新品牌状态', 'actions' => 'updateBrandStatus'], + ['title' => '删除品牌', 'actions' => 'deleteBrand'], + ['title' => '导出商品', 'actions' => 'exportGoods'], + ['title' => '批量打印', 'actions' => 'printBatchGoods'], + ['title' => '删除商品', 'actions' => 'deleteGoods'], + ['title' => '增加商品单位', 'actions' => 'addUnit'], + ['title' => '增加商品单位组', 'actions' => 'addUnitGroup'], + ], + ], + +// 跳过验证的权限路由(默认不受权限控制) + 'ignore_menu' => [ + 'permission_home', + 'permission_controller', + 'permission_account_info', + ], +]; \ No newline at end of file diff --git a/config/autoload/middlewares.php b/config/autoload/middlewares.php new file mode 100644 index 0000000..3521615 --- /dev/null +++ b/config/autoload/middlewares.php @@ -0,0 +1,21 @@ + [ + ValidationMiddleware::class, + RequestLogsMiddleware::class, + ], +]; diff --git a/config/autoload/op_logs.php b/config/autoload/op_logs.php new file mode 100644 index 0000000..8762678 --- /dev/null +++ b/config/autoload/op_logs.php @@ -0,0 +1,22 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +return [ + [ + 'id' => 1, + 'action' => 'UserController@userLogin', + 'name' => '用户登录', + ] +]; \ No newline at end of file diff --git a/config/autoload/processes.php b/config/autoload/processes.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/config/autoload/processes.php @@ -0,0 +1,13 @@ + [ + 'host' => env('REDIS_HOST', 'localhost'), + 'auth' => env('REDIS_AUTH', null), + 'port' => (int) env('REDIS_PORT', 6379), + 'db' => (int) env('REDIS_DB', 0), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60), + ], + ], +]; diff --git a/config/autoload/server.php b/config/autoload/server.php new file mode 100644 index 0000000..7a4de17 --- /dev/null +++ b/config/autoload/server.php @@ -0,0 +1,56 @@ + SWOOLE_PROCESS, + 'servers' => [ + [ + 'name' => 'http', + 'type' => ServerInterface::SERVER_HTTP, + 'host' => '0.0.0.0', + 'port' => 9501, + 'sock_type' => SWOOLE_SOCK_TCP, + 'callbacks' => [ + Event::ON_REQUEST => [Server::class, 'onRequest'], + ], + 'options' => [ + // Whether to enable request lifecycle event + 'enable_request_lifecycle' => false, + ], + ], + ], + 'settings' => [ + Constant::OPTION_ENABLE_COROUTINE => true, + Constant::OPTION_WORKER_NUM => min(swoole_cpu_num() * 4, 32), + Constant::OPTION_PID_FILE => BASE_PATH . '/runtime/hyperf.pid', + Constant::OPTION_OPEN_TCP_NODELAY => true, + Constant::OPTION_MAX_COROUTINE => 100000, + Constant::OPTION_OPEN_HTTP2_PROTOCOL => true, + Constant::OPTION_MAX_REQUEST => 100000, + Constant::OPTION_SOCKET_BUFFER_SIZE => 2 * 1024 * 1024, + Constant::OPTION_BUFFER_OUTPUT_SIZE => 2 * 1024 * 1024, + Constant::OPTION_ENABLE_DEADLOCK_CHECK => true, + + // 连接池配置 + Constant::OPTION_REACTOR_NUM => swoole_cpu_num(), + ], + 'callbacks' => [ + Event::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], + Event::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], + Event::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'], + ], +]; diff --git a/config/autoload/services.php b/config/autoload/services.php new file mode 100644 index 0000000..44c8f12 --- /dev/null +++ b/config/autoload/services.php @@ -0,0 +1,63 @@ + value(function () { + $consumers = []; + $services = [ + 'UserAuthService' => UserAuthServiceInterface::class, + 'EasyAppService' => EasyAppServiceInterface::class, + 'InventoryService' => InventoryServiceInterface::class, + ]; + foreach ($services as $name => $interface) { + $consumers[] = [ + 'name' => $name, + 'service' => $interface, + 'protocol' => 'jsonrpc-http', + 'load_balancer' => 'random', + 'registry' => [ + 'protocol' => 'nacos', + 'address' => 'http://127.0.0.1:8848', + ], + 'options' => [ + 'connect_timeout' => 5.0, + 'recv_timeout' => 5.0, + 'settings' => [ + // 开启连接池 + 'open_connection_pool' => true, + ], + // 重试次数,默认值为 2,收包超时不进行重试。暂只支持 JsonRpcPoolTransporter + 'retry_count' => 2, + // 重试间隔,毫秒 + 'retry_interval' => 100, + // 使用多路复用 RPC 时的心跳间隔,null 为不触发心跳 + 'heartbeat' => 30, + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 100, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => 30, + 'max_idle_time' => 60.0, + ], + ] + ]; + } + return $consumers; + }), +]; diff --git a/config/autoload/set_rpc_config.php b/config/autoload/set_rpc_config.php new file mode 100644 index 0000000..709a67d --- /dev/null +++ b/config/autoload/set_rpc_config.php @@ -0,0 +1,21 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +// 配置RPC公司信息 +return [ + 'companyInfo' => [ + 'full_name' => '苏州德木智造科技有限公司', + ], +]; \ No newline at end of file diff --git a/config/autoload/translation.php b/config/autoload/translation.php new file mode 100644 index 0000000..35b9f06 --- /dev/null +++ b/config/autoload/translation.php @@ -0,0 +1,16 @@ + 'zh_CN', + 'fallback_locale' => 'en', + 'path' => BASE_PATH . '/storage/languages', +]; diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..418135e --- /dev/null +++ b/config/config.php @@ -0,0 +1,33 @@ + env('APP_NAME', 'skeleton'), + 'app_env' => env('APP_ENV', 'dev'), + 'scan_cacheable' => env('SCAN_CACHEABLE', false), + StdoutLoggerInterface::class => [ + 'log_level' => [ + LogLevel::ALERT, + LogLevel::CRITICAL, + LogLevel::DEBUG, + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::INFO, + LogLevel::NOTICE, + LogLevel::WARNING, + ], + ], +]; diff --git a/config/container.php b/config/container.php new file mode 100644 index 0000000..c82a0e8 --- /dev/null +++ b/config/container.php @@ -0,0 +1,21 @@ + [CheckTokenMiddleware::class]]); \ No newline at end of file diff --git a/deploy.test.yml b/deploy.test.yml new file mode 100644 index 0000000..b5b692b --- /dev/null +++ b/deploy.test.yml @@ -0,0 +1,30 @@ +version: '3.7' +services: + hyperf: + image: $REGISTRY_URL/$PROJECT_NAME:test + environment: + - "APP_PROJECT=hyperf" + - "APP_ENV=testing" + ports: + - "9501:9501" + deploy: + replicas: 1 + restart_policy: + condition: on-failure + delay: 5s + max_attempts: 5 + update_config: + parallelism: 2 + delay: 5s + order: start-first + networks: + - hyperf_net + configs: + - source: hyperf_v1.0 + target: /opt/www/.env +configs: + hyperf_v1.0: + external: true +networks: + hyperf_net: + external: true diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1828ece --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3' +services: + hyperf-skeleton: + container_name: hyperf-skeleton + image: hyperf-skeleton + build: + context: . + volumes: + - ./:/opt/www + ports: + - 9501:9501 + environment: + - APP_ENV=dev + - SCAN_CACHEABLE=false + +networks: + default: + name: hyperf-skeleton diff --git a/migrations/2024_12_24_150857_create_column_config_table.php b/migrations/2024_12_24_150857_create_column_config_table.php new file mode 100755 index 0000000..13bf9a6 --- /dev/null +++ b/migrations/2024_12_24_150857_create_column_config_table.php @@ -0,0 +1,47 @@ +unsignedInteger('id', true); + $table->integer('company_id')->unsigned()->default(0)->comment('公司ID'); + $table->string('method', 50)->default('')->comment('场景'); + $table->string('prop', 50)->default('')->comment('字段'); + $table->string('label', 50)->default('')->comment('名称'); + $table->boolean('sortable')->default(true)->comment('是否开启排序'); + $table->integer('sort')->default(0)->comment('排序值'); + $table->integer('width')->default(0)->comment('宽度'); + $table->boolean('hide')->default(true)->comment('是否显示'); + $table->boolean('fix')->default(true)->comment('是否固定'); + $table->boolean('filter')->default(true)->comment('是否筛选'); + $table->boolean('is_search')->default(true)->comment('是否搜索'); + $table->string('search_type', 50)->default('')->comment('搜索类型'); + $table->string('condition', 50)->default('')->comment('搜索条件'); + MigrateService::migrateCreateInfo($table); + + $table->comment('列配置'); + + $table->index(['company_id', 'deleted_at'], 'company_id_deleted_at_index'); + $table->index(['creator_id', 'method'], 'creator_id_method_index'); + $table->unique(['prop', 'method', 'creator_id'], 'prop_method_creator_id_index'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('column_config'); + } +}; diff --git a/migrations/2024_12_24_153319_create_table_config_table.php b/migrations/2024_12_24_153319_create_table_config_table.php new file mode 100755 index 0000000..2d06d03 --- /dev/null +++ b/migrations/2024_12_24_153319_create_table_config_table.php @@ -0,0 +1,39 @@ +unsignedInteger('id', true); + + $table->integer('company_id')->unsigned()->default(0)->comment('公司ID'); + $table->string('method', 50)->default('')->comment('场景'); + $table->string('size', 50)->default('')->comment('表格大小'); + // 配置项 + $table->json('config')->comment('配置项'); + + MigrateService::migrateCreateInfo($table); + $table->comment('表格配置'); + + $table->index(['company_id', 'deleted_at'], 'company_id_deleted_at_index'); + $table->index(['method', 'creator_id'], 'method_creator_id_index'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('table_config'); + } +}; diff --git a/migrations/2025_05_25_090319_create_operator_logs_table.php b/migrations/2025_05_25_090319_create_operator_logs_table.php new file mode 100755 index 0000000..7dedfd8 --- /dev/null +++ b/migrations/2025_05_25_090319_create_operator_logs_table.php @@ -0,0 +1,44 @@ +unsignedInteger('id', true); + $table->integer('company_id')->unsigned()->default(0)->comment('公司ID'); + $table->smallInteger('type')->default(0)->comment('日志类型'); + $table->string('log_title', 120)->default('')->comment('日志主题'); + $table->string('route', 255)->default('')->comment('路由名称'); + $table->json('params')->comment('参数'); + $table->integer('ip')->default(0)->comment('IP地址')->unsigned(); + $table->string('location', 255)->default('')->comment('IP定位地址'); + $table->tinyInteger('source')->default(0)->comment('客户端操作来源:1PC端 2手机端 3对外服务SDK接口 4后台执行日志'); + $table->float('timer', 8, 3)->default(0)->comment('接口请求时间'); + $table->string('agent', 255)->default('')->comment('客户端浏览器内核'); + $table->text('remark')->comment('日志备注'); + $table->integer('creator_id')->default(0)->unsigned()->comment('创建人ID'); + $table->string('creator_name', 45)->default('')->comment('创建人姓名'); + $table->integer('created_at')->default(0)->unsigned()->comment('创建时间'); + $table->integer('updated_at')->default(0)->unsigned()->comment('更新时间'); + + $table->index(['source', 'type', 'company_id', 'created_at', 'id'], 'idx_mes_logs_full'); + $table->comment('日志管理表'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('operator_logs'); + } +}; diff --git a/migrations/2025_06_05_160600_create_purchase_table.php b/migrations/2025_06_05_160600_create_purchase_table.php new file mode 100644 index 0000000..e85cbfb --- /dev/null +++ b/migrations/2025_06_05_160600_create_purchase_table.php @@ -0,0 +1,55 @@ +bigIncrements('id'); + + $table->integer('company_id')->unsigned()->default(0)->comment('公司ID'); + + $table->string('purchase_sn', 45)->default('')->comment('采购单号'); + $table->json('warehouse_ids')->comment('所属的仓库ID列表'); + $table->string('contract_sn', 45)->default('')->comment('采购合同号'); + $table->integer('purchase_time')->default(0)->unsigned()->comment('提单日期'); + $table->tinyInteger('customer_type')->default(1)->comment('代理类型:1-代理 2-非代理'); + $table->tinyInteger('container_type')->default(1)->comment('装卸类型:1拆箱费(整箱) 2上下车费(散货)'); + $table->smallInteger('container_count')->default(0)->unsigned()->comment('箱量/车次'); + $table->smallInteger('original_count')->default(0)->unsigned()->comment('码单件数'); + $table->decimal('original_cube', 12, 4)->default(0)->unsigned()->comment('码单方数'); + $table->smallInteger('receiving_container')->default(0)->unsigned()->comment('收到的货柜数或车次'); + $table->smallInteger('receiving_count')->default(0)->unsigned()->comment('收货件数'); + $table->decimal('receiving_cube', 12, 4)->default(0)->unsigned()->comment('收货方数'); + $table->integer('kz_company_id')->default(0)->unsigned()->comment('开证公司id'); + $table->string('kz_company_name', 45)->default('')->comment('开证公司'); + $table->integer('sh_company_id')->default(0)->unsigned()->comment('收货公司id'); + $table->string('sh_company_name', 45)->default('')->comment('收货公司'); + $table->string('remark', 255)->default('')->comment('备注'); + $table->tinyInteger('is_from_erp')->default(0)->comment('是否erp提交的数据:0否,1是'); + $table->integer('erp_return_id')->default(0)->unsigned()->comment('对应的erp退货单id,默认0不是退货单'); + + $table->tinyInteger('status')->default(1)->comment('状态: 0结束 1正在执行'); + + MigrateService::migrateCreateInfo($table); + + $table->comment('采购单表'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('purchase'); + } +}; diff --git a/migrations/2025_06_05_161808_create_first_company_table.php b/migrations/2025_06_05_161808_create_first_company_table.php new file mode 100755 index 0000000..475653f --- /dev/null +++ b/migrations/2025_06_05_161808_create_first_company_table.php @@ -0,0 +1,42 @@ +bigIncrements('id'); + $table->string('domain', 100)->comment('公司域名'); + $table->string('name', 60)->comment('公司简称'); + $table->string('full_name', 255)->default('')->comment('公司全称'); + $table->string('address', 255)->default('')->comment('公司地址'); + $table->string('company_type', 20)->default('')->comment('公司类型'); + $table->string('logo', 255)->default('')->comment('公司LOGO'); + $table->string('org_code', 64)->default('')->comment('公司营业执照编号'); + $table->string('owner', 45)->default('')->comment('公司法人'); + $table->string('id_card', 18)->default('')->comment('公司法人身份证'); + $table->char('mobile', 11)->default('')->comment('负责人手机'); + $table->integer('activation_date')->default(0)->unsigned()->comment('启用时间'); + $table->tinyInteger('active_status')->default(1)->comment('状态: 0禁用 1正常'); + $table->string('remark', 255)->default('')->comment('备注信息'); + MigrateService::migrateCreateInfo($table); + $table->comment('平台公司信息'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('first_company'); + } +}; diff --git a/migrations/2025_06_05_175228_create_company_table.php b/migrations/2025_06_05_175228_create_company_table.php new file mode 100644 index 0000000..d168385 --- /dev/null +++ b/migrations/2025_06_05_175228_create_company_table.php @@ -0,0 +1,37 @@ +bigIncrements('id'); + + $table->tinyInteger('company_type')->default(1)->comment('公司类型 1:开证公司 2:收货公司'); + $table->string('name', 128)->default('')->comment('公司全称'); + $table->tinyInteger('status')->default(1)->comment('状态: 0禁用 1正常'); + + $table->unique(['name', 'company_type'], 'name'); + + MigrateService::migrateCreateInfo($table); + + $table->comment('公司表'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('company'); + } +}; diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..8bc5f33 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,14 @@ +# Magic behaviour with __get, __set, __call and __callStatic is not exactly static analyser-friendly :) +# Fortunately, You can ignore it by the following config. +# +# vendor/bin/phpstan analyse app --memory-limit 200M -l 0 +# +parameters: + level: 0 + paths: + - ./app + - ./config + reportUnmatchedIgnoredErrors: false + ignoreErrors: + - '#Static call to instance method Hyperf\\HttpServer\\Router\\Router::[a-zA-Z0-9\\_]+\(\)#' + - '#Static call to instance method Hyperf\\DbConnection\\Db::[a-zA-Z0-9\\_]+\(\)#' diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..caaa1d2 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,16 @@ + + + + + ./test + + + + + + + + ./app + + + diff --git a/storage/languages/en/validation.php b/storage/languages/en/validation.php new file mode 100644 index 0000000..cc57d60 --- /dev/null +++ b/storage/languages/en/validation.php @@ -0,0 +1,209 @@ + 'The :attribute must be accepted.', + 'accepted_if' => 'The :attribute must be accepted when :other is :value.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', + 'alpha' => 'The :attribute may only contain letters.', + 'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.', + 'alpha_num' => 'The :attribute may only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'ascii' => 'The :attribute must only contain single-byte alphanumeric characters and symbols.', + 'before' => 'The :attribute must be a date before :date.', + 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', + 'between' => [ + 'numeric' => 'The :attribute must be between :min and :max.', + 'file' => 'The :attribute must be between :min and :max kilobytes.', + 'string' => 'The :attribute must be between :min and :max characters.', + 'array' => 'The :attribute must have between :min and :max items.', + ], + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'contains' => 'The :attribute is missing a required value.', + 'date' => 'The :attribute is not a valid date.', + 'date_equals' => 'The :attribute must be a date equal to :date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'decimal' => 'The :attribute must have :decimal decimal places.', + 'declined' => 'The :attribute must be declined.', + 'declined_if' => 'The :attribute must be declined when :other is :value.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', + 'doesnt_end_with' => 'The :attribute must not end with one of the following: :values.', + 'doesnt_start_with' => 'The :attribute must not start with one of the following: :values.', + 'email' => 'The :attribute must be a valid email address.', + 'ends_with' => 'The :attribute must end with one of the following: :values.', + 'enum' => 'The selected :attribute is invalid.', + 'exists' => 'The selected :attribute is invalid.', + 'extensions' => 'The :attribute must have one of the following extensions: :values.', + 'file' => 'The :attribute must be a file.', + 'filled' => 'The :attribute field is required.', + 'gt' => [ + 'numeric' => 'The :attribute must be greater than :value', + 'file' => 'The :attribute must be greater than :value kb', + 'string' => 'The :attribute must be greater than :value characters', + 'array' => 'The :attribute must be greater than :value items', + ], + 'gte' => [ + 'numeric' => 'The :attribute must be great than or equal to :value', + 'file' => 'The :attribute must be great than or equal to :value kb', + 'string' => 'The :attribute must be great than or equal to :value characters', + 'array' => 'The :attribute must be great than or equal to :value items', + ], + 'hex_color' => 'The :attribute must be a valid hexadecimal color.', + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'in_array' => 'The :attribute field does not exist in :other.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'ipv4' => 'The :attribute must be a valid IPv4 address.', + 'ipv6' => 'The :attribute must be a valid IPv6 address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'list' => 'The :attribute must be a list.', + 'lowercase' => 'The :attribute must be lowercase.', + 'lt' => [ + 'numeric' => 'The :attribute must be less than :value', + 'file' => 'The :attribute must be less than :value kb', + 'string' => 'The :attribute must be less than :value characters', + 'array' => 'The :attribute must be less than :value items', + ], + 'lte' => [ + 'numeric' => 'The :attribute must be less than or equal to :value', + 'file' => 'The :attribute must be less than or equal to :value kb', + 'string' => 'The :attribute must be less than or equal to :value characters', + 'array' => 'The :attribute must be less than or equal to :value items', + ], + 'mac_address' => 'The :attribute must be a valid MAC address.', + 'max' => [ + 'numeric' => 'The :attribute may not be greater than :max.', + 'file' => 'The :attribute may not be greater than :max kilobytes.', + 'string' => 'The :attribute may not be greater than :max characters.', + 'array' => 'The :attribute may not have more than :max items.', + ], + 'max_digits' => 'The :attribute must not have more than :max digits.', + 'mimes' => 'The :attribute must be a file of type: :values.', + 'mimetypes' => 'The :attribute must be a file of type: :values.', + 'min' => [ + 'numeric' => 'The :attribute must be at least :min.', + 'file' => 'The :attribute must be at least :min kilobytes.', + 'string' => 'The :attribute must be at least :min characters.', + 'array' => 'The :attribute must have at least :min items.', + ], + 'min_digits' => 'The :attribute must have at least :min digits.', + 'missing' => 'The :attribute must be missing.', + 'missing_if' => 'The :attribute must be missing when :other is :value.', + 'missing_unless' => 'The :attribute must be missing unless :other is :value.', + 'missing_with' => 'The :attribute must be missing when :values is present.', + 'missing_with_all' => 'The :attribute must be missing when :values are present.', + 'multiple_of' => 'The :attribute must be a multiple of :value.', + 'not_in' => 'The selected :attribute is invalid.', + 'not_regex' => 'The :attribute cannot match a given regular rule.', + 'numeric' => 'The :attribute must be a number.', + 'present' => 'The :attribute field must be present.', + 'prohibits' => 'The :attribute field must be present.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values is present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'exclude' => 'The :attribute field is excluded.', + 'exclude_if' => 'The :attribute field is excluded when :other is :value.', + 'exclude_unless' => 'The :attribute field is excluded unless :other is in :values.', + 'exclude_with' => 'The :attribute field is excluded when :values is present.', + 'exclude_without' => 'The :attribute field is excluded when :values is not present.', + 'same' => 'The :attribute and :other must match.', + 'size' => [ + 'numeric' => 'The :attribute must be :size.', + 'file' => 'The :attribute must be :size kilobytes.', + 'string' => 'The :attribute must be :size characters.', + 'array' => 'The :attribute must contain :size items.', + ], + 'starts_with' => 'The :attribute must be start with :values ', + 'string' => 'The :attribute must be a string.', + 'timezone' => 'The :attribute must be a valid zone.', + 'unique' => 'The :attribute has already been taken.', + 'uploaded' => 'The :attribute failed to upload.', + 'uppercase' => 'The :attribute must be uppercase.', + 'url' => 'The :attribute format is invalid.', + 'ulid' => 'The :attribute must be a valid ULID.', + 'uuid' => 'The :attribute is invalid UUID.', + 'max_if' => [ + 'numeric' => 'The :attribute may not be greater than :max when :other is :value.', + 'file' => 'The :attribute may not be greater than :max kilobytes when :other is :value.', + 'string' => 'The :attribute may not be greater than :max characters when :other is :value.', + 'array' => 'The :attribute may not have more than :max items when :other is :value.', + ], + 'min_if' => [ + 'numeric' => 'The :attribute must be at least :min when :other is :value.', + 'file' => 'The :attribute must be at least :min kilobytes when :other is :value.', + 'string' => 'The :attribute must be at least :min characters when :other is :value.', + 'array' => 'The :attribute must have at least :min items when :other is :value.', + ], + 'between_if' => [ + 'numeric' => 'The :attribute must be between :min and :max when :other is :value.', + 'file' => 'The :attribute must be between :min and :max kilobytes when :other is :value.', + 'string' => 'The :attribute must be between :min and :max characters when :other is :value.', + 'array' => 'The :attribute must have between :min and :max items when :other is :value.', + ], + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'custom-message', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [], + 'phone_number' => 'The :attribute must be a valid phone number', + 'telephone_number' => 'The :attribute must be a valid telephone number', + + 'chinese_word' => 'The :attribute must contain valid characters(chinese/english character, number, underscore)', + 'sequential_array' => 'The :attribute must be sequential array', +]; diff --git a/storage/languages/zh_CN/validation.php b/storage/languages/zh_CN/validation.php new file mode 100644 index 0000000..3e5160d --- /dev/null +++ b/storage/languages/zh_CN/validation.php @@ -0,0 +1,185 @@ + ':attribute 必须接受', + 'active_url' => ':attribute 必须是一个合法的 URL', + 'after' => ':attribute 必须是 :date 之后的一个日期', + 'after_or_equal' => ':attribute 必须是 :date 之后或相同的一个日期', + 'alpha' => ':attribute 只能包含字母', + 'alpha_dash' => ':attribute 只能包含字母、数字、中划线或下划线', + 'alpha_num' => ':attribute 只能包含字母和数字', + 'array' => ':attribute 必须是一个数组', + 'before' => ':attribute 必须是 :date 之前的一个日期', + 'before_or_equal' => ':attribute 必须是 :date 之前或相同的一个日期', + 'between' => [ + 'numeric' => ':attribute 必须在 :min 到 :max 之间', + 'file' => ':attribute 必须在 :min 到 :max kb 之间', + 'string' => ':attribute 必须在 :min 到 :max 个字符之间', + 'array' => ':attribute 必须在 :min 到 :max 项之间', + ], + 'boolean' => ':attribute 字符必须是 true 或 false, 1 或 0', + 'confirmed' => ':attribute 二次确认不匹配', + 'date' => ':attribute 必须是一个合法的日期', + 'date_format' => ':attribute 与给定的格式 :format 不符合', + 'decimal' => ':attribute 必须有 :decimal 位小数', + 'different' => ':attribute 必须不同于 :other', + 'digits' => ':attribute 必须是 :digits 位', + 'digits_between' => ':attribute 必须在 :min 和 :max 位之间', + 'dimensions' => ':attribute 具有无效的图片尺寸', + 'distinct' => ':attribute 字段具有重复值', + 'email' => ':attribute 必须是一个合法的电子邮件地址', + 'exists' => '选定的 :attribute 是无效的', + 'file' => ':attribute 必须是一个文件', + 'filled' => ':attribute 的字段是必填的', + 'gt' => [ + 'numeric' => ':attribute 必须大于 :value', + 'file' => ':attribute 必须大于 :value kb', + 'string' => ':attribute 必须大于 :value 个字符', + 'array' => ':attribute 必须大于 :value 项', + ], + 'gte' => [ + 'numeric' => ':attribute 必须大于等于 :value', + 'file' => ':attribute 必须大于等于 :value kb', + 'string' => ':attribute 必须大于等于 :value 个字符', + 'array' => ':attribute 必须大于等于 :value 项', + ], + 'image' => ':attribute 必须是 jpg, jpeg, png, bmp 或者 gif 格式的图片', + 'in' => '选定的 :attribute 是无效的', + 'in_array' => ':attribute 字段不存在于 :other', + 'integer' => ':attribute 必须是个整数', + 'ip' => ':attribute 必须是一个合法的 IP 地址', + 'ipv4' => ':attribute 必须是一个合法的 IPv4 地址', + 'ipv6' => ':attribute 必须是一个合法的 IPv6 地址', + 'json' => ':attribute 必须是一个合法的 JSON 字符串', + 'list' => ':attribute 必须是一个数组列表', + 'lt' => [ + 'numeric' => ':attribute 必须小于 :value', + 'file' => ':attribute 必须小于 :value kb', + 'string' => ':attribute 必须小于 :value 个字符', + 'array' => ':attribute 必须小于 :value 项', + ], + 'lte' => [ + 'numeric' => ':attribute 必须小于等于 :value', + 'file' => ':attribute 必须小于等于 :value kb', + 'string' => ':attribute 必须小于等于 :value 个字符', + 'array' => ':attribute 必须小于等于 :value 项', + ], + 'max' => [ + 'numeric' => ':attribute 的最大值为 :max', + 'file' => ':attribute 的最大为 :max kb', + 'string' => ':attribute 的最大长度为 :max 字符', + 'array' => ':attribute 至多有 :max 项', + ], + 'mimes' => ':attribute 的文件类型必须是 :values', + 'mimetypes' => ':attribute 的文件MIME必须是 :values', + 'min' => [ + 'numeric' => ':attribute 的最小值为 :min', + 'file' => ':attribute 大小至少为 :min kb', + 'string' => ':attribute 的最小长度为 :min 字符', + 'array' => ':attribute 至少有 :min 项', + ], + 'not_in' => '选定的 :attribute 是无效的', + 'not_regex' => ':attribute 不能匹配给定的正则', + 'numeric' => ':attribute 必须是数字', + 'present' => ':attribute 字段必须存在', + 'prohibits' => '必须提供 :attribute 字段', + 'regex' => ':attribute 格式是无效的', + 'required' => ':attribute 字段是必须的', + 'required_if' => ':attribute 字段是必须的当 :other 是 :value', + 'required_unless' => ':attribute 字段是必须的,除非 :other 是在 :values 中', + 'required_with' => ':attribute 字段是必须的当 :values 是存在的', + 'required_with_all' => ':attribute 字段是必须的当 :values 是存在的', + 'required_without' => ':attribute 字段是必须的当 :values 是不存在的', + 'required_without_all' => ':attribute 字段是必须的当 没有一个 :values 是存在的', + 'exclude' => ':attribute 字段是被排除的', + 'exclude_if' => '当 :other 为 :value 时,排除 :attribute 字段', + 'exclude_unless' => '除非 :other 是在 :values 中,否则排除 :attribute 字段', + 'exclude_with' => '当 :values 存在时,排除 :attribute 字段', + 'exclude_without' => '当 :values 不存在时,排除 :attribute 字段', + 'same' => ':attribute 和 :other 必须匹配', + 'size' => [ + 'numeric' => ':attribute 必须是 :size', + 'file' => ':attribute 必须是 :size kb', + 'string' => ':attribute 必须是 :size 个字符', + 'array' => ':attribute 必须包括 :size 项', + ], + 'starts_with' => ':attribute 必须以 :values 为开头', + 'string' => ':attribute 必须是一个字符串', + 'timezone' => ':attribute 必须是个有效的时区', + 'unique' => ':attribute 已存在', + 'uploaded' => ':attribute 上传失败', + 'url' => ':attribute 无效的格式', + 'uuid' => ':attribute 无效的UUID格式', + 'max_if' => [ + 'numeric' => '当 :other 为 :value 时 :attribute 不能大于 :max', + 'file' => '当 :other 为 :value 时 :attribute 不能大于 :max kb', + 'string' => '当 :other 为 :value 时 :attribute 不能大于 :max 个字符', + 'array' => '当 :other 为 :value 时 :attribute 最多只有 :max 个单元', + ], + 'min_if' => [ + 'numeric' => '当 :other 为 :value 时 :attribute 必须大于等于 :min', + 'file' => '当 :other 为 :value 时 :attribute 大小不能小于 :min kb', + 'string' => '当 :other 为 :value 时 :attribute 至少为 :min 个字符', + 'array' => '当 :other 为 :value 时 :attribute 至少有 :min 个单元', + ], + 'between_if' => [ + 'numeric' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max 之间', + 'file' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max kb 之间', + 'string' => '当 :other 为 :value 时 :attribute 必须介于 :min - :max 个字符之间', + 'array' => '当 :other 为 :value 时 :attribute 必须只有 :min - :max 个单元', + ], + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'custom-message', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => [], + 'phone_number' => ':attribute 必须为一个有效的电话号码', + 'telephone_number' => ':attribute 必须为一个有效的手机号码', + + 'chinese_word' => ':attribute 必须包含以下有效字符 (中文/英文,数字, 下划线)', + 'sequential_array' => ':attribute 必须是一个有序数组', +]; diff --git a/test/Cases/ExampleTest.php b/test/Cases/ExampleTest.php new file mode 100644 index 0000000..789ff67 --- /dev/null +++ b/test/Cases/ExampleTest.php @@ -0,0 +1,27 @@ +get('/')->assertOk()->assertSee('Hyperf'); + } +} diff --git a/test/HttpTestCase.php b/test/HttpTestCase.php new file mode 100644 index 0000000..da07e66 --- /dev/null +++ b/test/HttpTestCase.php @@ -0,0 +1,45 @@ +client = make(Client::class); + } + + public function __call($name, $arguments) + { + return $this->client->{$name}(...$arguments); + } +} diff --git a/test/bootstrap.php b/test/bootstrap.php new file mode 100644 index 0000000..818d1d8 --- /dev/null +++ b/test/bootstrap.php @@ -0,0 +1,30 @@ +get(Hyperf\Contract\ApplicationInterface::class);