From 4a8befd110e09dcb9595c43a82fe067b6f6508dd Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 2 Oct 2022 18:40:18 +0300 Subject: [PATCH 01/87] redis-syncs --- Dockerfile | 5 +- app/init.php | 23 +- app/workers/syncsIn.php | 31 + app/workers/syncsOut.php | 34 + bin/worker-syncs-in | 10 + bin/worker-syncs-out | 10 + composer.lock | 5388 -------------------------------- docker-compose.yml | 43 + src/Appwrite/Event/Event.php | 6 + src/Appwrite/Event/SyncIn.php | 51 + src/Appwrite/Event/SyncOut.php | 51 + 11 files changed, 261 insertions(+), 5391 deletions(-) create mode 100644 app/workers/syncsIn.php create mode 100644 app/workers/syncsOut.php create mode 100644 bin/worker-syncs-in create mode 100644 bin/worker-syncs-out delete mode 100644 composer.lock create mode 100644 src/Appwrite/Event/SyncIn.php create mode 100644 src/Appwrite/Event/SyncOut.php diff --git a/Dockerfile b/Dockerfile index a7cae38502..b2345f984e 100755 --- a/Dockerfile +++ b/Dockerfile @@ -351,7 +351,10 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/worker-builds && \ chmod +x /usr/local/bin/worker-mails && \ chmod +x /usr/local/bin/worker-messaging && \ - chmod +x /usr/local/bin/worker-webhooks + chmod +x /usr/local/bin/worker-webhooks && \ + chmod +x /usr/local/bin/worker-syncs-out && \ + chmod +x /usr/local/bin/worker-syncs-in + # Letsencrypt Permissions RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/ diff --git a/app/init.php b/app/init.php index df7763707d..e4c7663133 100644 --- a/app/init.php +++ b/app/init.php @@ -18,6 +18,7 @@ ini_set('default_socket_timeout', -1); error_reporting(E_ALL); +use Appwrite\Event\SyncOut; use Appwrite\Extend\PDO; use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; @@ -36,6 +37,7 @@ use Appwrite\Event\Event; use Appwrite\Event\Mail; use Appwrite\Event\Phone; +use Appwrite\Event\SyncIn; use Appwrite\Network\Validator\Email; use Appwrite\Network\Validator\IP; use Appwrite\Network\Validator\URL; @@ -749,8 +751,7 @@ function (mixed $value) { App::setResource('usage', function ($register) { return new Stats($register->get('statsd')); }, ['register']); - -App::setResource('clients', function ($request, $console, $project) { +App::setResource('clients', function ($request, $console, $project) use ($register) { $console->setAttribute('platforms', [ // Always allow current host '$collection' => ID::custom('platforms'), 'name' => 'Current Host', @@ -758,6 +759,24 @@ function (mixed $value) { 'hostname' => $request->getHostname(), ], Document::SET_TYPE_APPEND); + $register->set('syncOut', function () { + return new SyncOut(); + }); + + cache::on(cache::EVENT_PURGE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + cache::on(cache::EVENT_SAVE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + /** * Get All verified client URLs for both console and current projects * + Filter for duplicated entries diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php new file mode 100644 index 0000000000..8fef867c14 --- /dev/null +++ b/app/workers/syncsIn.php @@ -0,0 +1,31 @@ +args['key']); + } + + + public function shutdown(): void + { + } +} diff --git a/bin/worker-syncs-in b/bin/worker-syncs-in new file mode 100644 index 0000000000..f82d859e1f --- /dev/null +++ b/bin/worker-syncs-in @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] +then + REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" +else + REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" +fi + +INTERVAL=0.1 QUEUE='v1-syncs-in' APP_INCLUDE='/usr/src/code/app/workers/syncsIn.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file diff --git a/bin/worker-syncs-out b/bin/worker-syncs-out new file mode 100644 index 0000000000..523ecd5270 --- /dev/null +++ b/bin/worker-syncs-out @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] +then + REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" +else + REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" +fi + +INTERVAL=0.1 QUEUE='v1-syncs-out' APP_INCLUDE='/usr/src/code/app/workers/syncsOut.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 9ec0ea3197..0000000000 --- a/composer.lock +++ /dev/null @@ -1,5388 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "568151395a8877f87d9bdce048adc2dc", - "packages": [ - { - "name": "adhocore/jwt", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/adhocore/php-jwt.git", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ahc\\Jwt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jitendra Adhikari", - "email": "jiten.adhikary@gmail.com" - } - ], - "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", - "keywords": [ - "auth", - "json-web-token", - "jwt", - "jwt-auth", - "jwt-php", - "token" - ], - "support": { - "issues": "https://github.com/adhocore/php-jwt/issues", - "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" - }, - "funding": [ - { - "url": "https://paypal.me/ji10", - "type": "custom" - } - ], - "time": "2021-02-20T09:56:44+00:00" - }, - { - "name": "appwrite/php-clamav", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/php-clamav.git", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", - "shasum": "" - }, - "require": { - "ext-sockets": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\ClamAV\\": "src/ClamAV" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "ClamAV network and pipe client for PHP", - "keywords": [ - "anti virus", - "appwrite", - "clamav", - "php" - ], - "support": { - "issues": "https://github.com/appwrite/php-clamav/issues", - "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" - }, - "time": "2020-10-02T05:23:46+00:00" - }, - { - "name": "appwrite/php-runtimes", - "version": "0.11.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/runtimes.git", - "reference": "547fc026e11c0946846a8ac690898f5bf53be101" - }, - "require": { - "php": ">=8.0", - "utopia-php/system": "0.4.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\Runtimes\\": "src/Runtimes" - } - }, - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", - "keywords": [ - "appwrite", - "php", - "runtimes" - ], - "time": "2022-08-15T14:03:36+00:00" - }, - { - "name": "chillerlan/php-qrcode", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", - "shasum": "" - }, - "require": { - "chillerlan/php-settings-container": "^2.1", - "ext-mbstring": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5", - "setasign/fpdf": "^1.8.2" - }, - "suggest": { - "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", - "setasign/fpdf": "Required to use the QR FPDF output." - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\QRCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" - }, - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - }, - { - "name": "Contributors", - "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" - } - ], - "description": "A QR code generator. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-qrcode", - "keywords": [ - "phpqrcode", - "qr", - "qr code", - "qrcode", - "qrcode-generator" - ], - "support": { - "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2021-11-25T22:38:09+00:00" - }, - { - "name": "chillerlan/php-settings-container", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\Settings\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - } - ], - "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-settings-container", - "keywords": [ - "PHP7", - "Settings", - "configuration", - "container", - "helper" - ], - "support": { - "issues": "https://github.com/chillerlan/php-settings-container/issues", - "source": "https://github.com/chillerlan/php-settings-container" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2022-07-05T22:32:14+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "v1.13.1", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/85df015088e00daf8ce395189de22c8eb45c8d49", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "suggest": { - "ext-redis": "Improved performance for communicating with redis" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php", - "Module.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "support": { - "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.13.1" - }, - "time": "2022-06-20T22:56:59+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.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": "2022-01-17T14:14:24+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2022-01-18T15:43:28+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", - "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.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "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 - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "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.5.0" - }, - "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": "2022-08-28T15:39:27+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "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/1.5.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2022-08-28T14:55:35+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.4.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.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.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "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.4.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": "2022-08-28T14:45:39+00:00" - }, - { - "name": "influxdb/influxdb-php", - "version": "1.15.2", - "source": { - "type": "git", - "url": "https://github.com/influxdata/influxdb-php.git", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0|^7.0", - "php": "^5.5 || ^7.0 || ^8.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.2.1", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "Curl extension, needed for Curl driver", - "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." - }, - "type": "library", - "autoload": { - "psr-4": { - "InfluxDB\\": "src/InfluxDB" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Hoogendijk", - "email": "stephen@tca0.nl" - }, - { - "name": "Daniel Martinez", - "email": "danimartcas@hotmail.com" - }, - { - "name": "Gianluca Arbezzano", - "email": "gianarb92@gmail.com" - } - ], - "description": "InfluxDB client library for PHP", - "keywords": [ - "client", - "influxdata", - "influxdb", - "influxdb class", - "influxdb client", - "influxdb library", - "time series" - ], - "support": { - "issues": "https://github.com/influxdata/influxdb-php/issues", - "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" - }, - "time": "2020-12-26T17:45:17+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.8.0", - "php": "^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0|^8.5|^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" - }, - "time": "2021-02-04T16:20:16+00:00" - }, - { - "name": "matomo/device-detector", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/matomo-org/device-detector.git", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", - "shasum": "" - }, - "require": { - "mustangostang/spyc": "*", - "php": "^7.2|^8.0" - }, - "replace": { - "piwik/device-detector": "self.version" - }, - "require-dev": { - "matthiasmullie/scrapbook": "^1.4.7", - "mayflower/mo4-coding-standard": "^v8.0.0", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5.8", - "psr/cache": "^1.0.1", - "psr/simple-cache": "^1.0.1", - "symfony/yaml": "^5.1.7" - }, - "suggest": { - "doctrine/cache": "Can directly be used for caching purpose", - "ext-yaml": "Necessary for using the Pecl YAML parser" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeviceDetector\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "The Matomo Team", - "email": "hello@matomo.org", - "homepage": "https://matomo.org/team/" - } - ], - "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", - "homepage": "https://matomo.org", - "keywords": [ - "devicedetection", - "parser", - "useragent" - ], - "support": { - "forum": "https://forum.matomo.org/", - "issues": "https://github.com/matomo-org/device-detector/issues", - "source": "https://github.com/matomo-org/matomo", - "wiki": "https://dev.matomo.org/" - }, - "time": "2022-04-11T09:58:17+00:00" - }, - { - "name": "mongodb/mongodb", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/mongodb/mongo-php-library.git", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d", - "shasum": "" - }, - "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mongodb": "^1.8.1", - "jean85/pretty-package-versions": "^1.2", - "php": "^7.0 || ^8.0", - "symfony/polyfill-php80": "^1.19" - }, - "require-dev": { - "squizlabs/php_codesniffer": "^3.5, <3.5.5", - "symfony/phpunit-bridge": "5.x-dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "MongoDB\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andreas Braun", - "email": "andreas.braun@mongodb.com" - }, - { - "name": "Jeremy Mikola", - "email": "jmikola@gmail.com" - } - ], - "description": "MongoDB driver library", - "homepage": "https://jira.mongodb.org/browse/PHPLIB", - "keywords": [ - "database", - "driver", - "mongodb", - "persistence" - ], - "support": { - "issues": "https://github.com/mongodb/mongo-php-library/issues", - "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0" - }, - "time": "2020-11-25T12:26:02+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "git@github.com:mustangostang/spyc.git", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2019-09-10T13:16:29+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.2", - "yoast/phpunit-polyfills": "^1.0.0" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2022-02-28T15:31:21+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20: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": "resque/php-resque", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/resque/php-resque.git", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "~1.7", - "php": ">=5.6.0", - "psr/log": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "suggest": { - "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", - "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", - "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." - }, - "bin": [ - "bin/resque", - "bin/resque-scheduler" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Resque": "lib", - "ResqueScheduler": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dan Hunsaker", - "email": "danhunsaker+resque@gmail.com", - "role": "Maintainer" - }, - { - "name": "Rajib Ahmed", - "homepage": "https://github.com/rajibahmed", - "role": "Maintainer" - }, - { - "name": "Steve Klabnik", - "email": "steve@steveklabnik.com", - "role": "Maintainer" - }, - { - "name": "Chris Boulton", - "email": "chris@bigcommerce.com", - "role": "Creator" - } - ], - "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", - "homepage": "http://www.github.com/resque/php-resque/", - "keywords": [ - "background", - "job", - "redis", - "resque" - ], - "support": { - "issues": "https://github.com/resque/php-resque/issues", - "source": "https://github.com/resque/php-resque/tree/v1.3.6" - }, - "time": "2020-04-16T16:39:50+00:00" - }, - { - "name": "slickdeals/statsd", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/Slickdeals/statsd-php.git", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", - "shasum": "" - }, - "require": { - "php": ">= 7.3 || ^8" - }, - "replace": { - "domnikl/statsd": "self.version" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Domnikl\\Statsd\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dominik Liebler", - "email": "liebler.dominik@gmail.com" - } - ], - "description": "a PHP client for statsd", - "homepage": "https://github.com/Slickdeals/statsd-php", - "keywords": [ - "Metrics", - "monitoring", - "statistics", - "statsd", - "udp" - ], - "support": { - "issues": "https://github.com/Slickdeals/statsd-php/issues", - "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" - }, - "time": "2021-06-04T20:33:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-02-25T11:15:52+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.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": "2022-05-10T07:21:04+00:00" - }, - { - "name": "utopia-php/abuse", - "version": "0.13.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4c1b8fe742f17158c59550cdfd9074a94bf474ac", - "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Abuse\\": "src/Abuse" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple abuse library to manage application usage limits", - "keywords": [ - "Abuse", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.13.1" - }, - "time": "2022-09-07T16:02:58+00:00" - }, - { - "name": "utopia-php/analytics", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/analytics.git", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Analytics\\": "src/Analytics" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library to track events & users.", - "keywords": [ - "analytics", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.2.0" - }, - "time": "2021-03-23T21:33:07+00:00" - }, - { - "name": "utopia-php/audit", - "version": "0.14.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/audit.git", - "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/b011224ed9bfef7e5c849938e65619af28f7cf41", - "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Audit\\": "src/Audit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple audit library to manage application users logs", - "keywords": [ - "Audit", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.14.1" - }, - "time": "2022-09-07T16:03:16+00:00" - }, - { - "name": "utopia-php/cache", - "version": "0.6.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cache.git", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/9889235a6d3da6cbb1f435201529da4d27c30e79", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-redis": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Cache\\": "src/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple cache library to manage application cache storing, loading and purging", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.6.1" - }, - "time": "2022-08-10T08:12:46+00:00" - }, - { - "name": "utopia-php/cli", - "version": "0.13.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cli.git", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/69e68f8ed525fe162fae950a0507ed28a0f179bc", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc", - "shasum": "" - }, - "require": { - "php": ">=7.4", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\CLI\\": "src/CLI" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple CLI library to manage command line applications", - "keywords": [ - "cli", - "command line", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.13.0" - }, - "time": "2022-04-26T08:41:22+00:00" - }, - { - "name": "utopia-php/config", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/config.git", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Config\\": "src/Config" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Config library to managing application config variables", - "keywords": [ - "config", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/config/issues", - "source": "https://github.com/utopia-php/config/tree/0.2.2" - }, - "time": "2020-10-24T09:49:09+00:00" - }, - { - "name": "utopia-php/database", - "version": "0.25.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "2883de82eee99e5744bf6e4123095a530c48a194" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/2883de82eee99e5744bf6e4123095a530c48a194", - "reference": "2883de82eee99e5744bf6e4123095a530c48a194", - "shasum": "" - }, - "require": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "mongodb/mongodb": "1.8.0", - "php": ">=8.0", - "utopia-php/cache": "0.6.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "fakerphp/faker": "^1.14", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.11.0", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Database\\": "src/Database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Brandon Leckemby", - "email": "brandon@appwrite.io" - } - ], - "description": "A simple library to manage application persistency using multiple database adapters", - "keywords": [ - "database", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.25.4" - }, - "time": "2022-09-14T06:22:33+00:00" - }, - { - "name": "utopia-php/domains", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Domains\\": "src/Domains" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "domains", - "framework", - "icann", - "php", - "public suffix", - "tld", - "tld extract", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/master" - }, - "time": "2020-02-23T07:40:02+00:00" - }, - { - "name": "utopia-php/framework", - "version": "0.21.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/c81789b87a917da2daf336738170ebe01f50ea18", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.10", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.21.1" - }, - "time": "2022-09-07T09:56:28+00:00" - }, - { - "name": "utopia-php/image", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/image.git", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", - "shasum": "" - }, - "require": { - "ext-imagick": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Image\\": "src/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Image manipulation library", - "keywords": [ - "framework", - "image", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.4" - }, - "time": "2022-05-11T12:30:41+00:00" - }, - { - "name": "utopia-php/locale", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/locale.git", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Locale\\": "src/Locale" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple locale library to manage application translations", - "keywords": [ - "framework", - "locale", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/locale/issues", - "source": "https://github.com/utopia-php/locale/tree/0.4.0" - }, - "time": "2021-07-24T11:35:55+00:00" - }, - { - "name": "utopia-php/logger", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Logger\\": "src/Logger" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], - "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "appsignal", - "errors", - "framework", - "logger", - "logging", - "logs", - "php", - "raygun", - "sentry", - "upf", - "utopia", - "warnings" - ], - "support": { - "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" - }, - "time": "2022-03-18T10:56:57+00:00" - }, - { - "name": "utopia-php/orchestration", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/orchestration.git", - "reference": "94263976413871efb6b16157a7101a81df3b6d78" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/94263976413871efb6b16157a7101a81df3b6d78", - "reference": "94263976413871efb6b16157a7101a81df3b6d78", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.13.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Orchestration\\": "src/Orchestration" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Lite & fast micro PHP abstraction library for container orchestration", - "keywords": [ - "docker", - "framework", - "kubernetes", - "orchestration", - "php", - "swarm", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.6.0" - }, - "time": "2022-07-13T16:47:18+00:00" - }, - { - "name": "utopia-php/preloader", - "version": "0.2.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/preloader.git", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Preloader\\": "src/Preloader" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", - "keywords": [ - "framework", - "php", - "preload", - "preloader", - "preloading", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/preloader/issues", - "source": "https://github.com/utopia-php/preloader/tree/0.2.4" - }, - "time": "2020-10-24T07:04:59+00:00" - }, - { - "name": "utopia-php/registry", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/registry.git", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Registry\\": "src/Registry" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple dependency management library for PHP", - "keywords": [ - "dependency management", - "di", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/registry/issues", - "source": "https://github.com/utopia-php/registry/tree/0.5.0" - }, - "time": "2021-03-10T10:45:22+00:00" - }, - { - "name": "utopia-php/storage", - "version": "0.11.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/storage.git", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-zlib": "*", - "ext-zstd": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Storage\\": "src/Storage" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Storage library to manage application storage", - "keywords": [ - "framework", - "php", - "storage", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.11.0" - }, - "time": "2022-08-31T09:17:31+00:00" - }, - { - "name": "utopia-php/swoole", - "version": "0.3.3", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/swoole.git", - "reference": "8312df69233b5dcd3992de88f131f238002749de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/8312df69233b5dcd3992de88f131f238002749de", - "reference": "8312df69233b5dcd3992de88f131f238002749de", - "shasum": "" - }, - "require": { - "ext-swoole": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "swoole/ide-helper": "4.8.3", - "vimeo/psalm": "4.15.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Swoole\\": "src/Swoole" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", - "keywords": [ - "framework", - "http", - "php", - "server", - "swoole", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.3.3" - }, - "time": "2022-01-20T09:58:43+00:00" - }, - { - "name": "utopia-php/system", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/system.git", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/67c92c66ce8f0cc925a00bca89f7a188bf9183c0", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\System\\": "src/System" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library for obtaining information about the host's system.", - "keywords": [ - "framework", - "php", - "system", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.4.0" - }, - "time": "2021-02-04T14:14:49+00:00" - }, - { - "name": "utopia-php/websocket", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/websocket.git", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.6.6", - "textalk/websocket": "1.5.2", - "vimeo/psalm": "^4.8.1", - "workerman/workerman": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\WebSocket\\": "src/WebSocket" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple abstraction for WebSocket servers.", - "keywords": [ - "framework", - "php", - "upf", - "utopia", - "websocket" - ], - "support": { - "issues": "https://github.com/utopia-php/websocket/issues", - "source": "https://github.com/utopia-php/websocket/tree/0.1.0" - }, - "time": "2021-12-20T10:50:09+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "appwrite/sdk-generator", - "version": "0.28.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "matthiasmullie/minify": "^1.3.68", - "php": ">=7.0.0", - "twig/twig": "^3.4.1" - }, - "require-dev": { - "brianium/paratest": "^6.4", - "phpunit/phpunit": "^9.5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\SDK\\": "src/SDK", - "Appwrite\\Spec\\": "src/Spec" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "support": { - "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" - }, - "time": "2022-09-22T09:15:54+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "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.22" - }, - "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.4.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%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.69", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" - }, - "funding": [ - { - "url": "https://github.com/matthiasmullie", - "type": "github" - } - ], - "time": "2022-08-01T09:00:18+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.17", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-08-30T12:24:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library 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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "swoole/ide-helper", - "version": "4.8.9", - "source": { - "type": "git", - "url": "https://github.com/swoole/ide-helper.git", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "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/4.8.9" - }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-04-18T20:38:04+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.7", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" - }, - "time": "2022-03-29T09:46:59+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "twig/twig", - "version": "v3.4.2", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.2" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "time": "2022-08-12T06:47:24+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0.0", - "ext-curl": "*", - "ext-imagick": "*", - "ext-mbstring": "*", - "ext-json": "*", - "ext-yaml": "*", - "ext-dom": "*", - "ext-redis": "*", - "ext-swoole": "*", - "ext-pdo": "*", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-sockets": "*" - }, - "platform-dev": { - "ext-fileinfo": "*" - }, - "platform-overrides": { - "php": "8.0" - }, - "plugin-api-version": "2.3.0" -} diff --git a/docker-compose.yml b/docker-compose.yml index 79a8d218fa..1d52fc1c0f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,6 +107,7 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb - redis @@ -254,6 +255,48 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + appwrite-worker-syncs-out: + entrypoint: worker-syncs-out + <<: *x-logging + container_name: appwrite-worker-syncs-out + build: + context: . + networks: + - appwrite + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + + appwrite-worker-syncs-in: + entrypoint: worker-syncs-in + <<: *x-logging + container_name: appwrite-worker-syncs-in + build: + context: . + networks: + - appwrite + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + appwrite-worker-webhooks: entrypoint: worker-webhooks <<: *x-logging diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index 222cf59444..4315de44b5 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -35,6 +35,12 @@ class Event public const MESSAGING_QUEUE_NAME = 'v1-messaging'; public const MESSAGING_CLASS_NAME = 'MessagingV1'; + public const SYNCS_IN_QUEUE_NAME = 'v1-syncs-in'; + public const SYNCS_IN_CLASS_NAME = 'SyncsInV1'; + + public const SYNCS_OUT_QUEUE_NAME = 'v1-syncs-out'; + public const SYNCS_OUT_CLASS_NAME = 'SyncsOutV1'; + protected string $queue = ''; protected string $class = ''; protected string $event = ''; diff --git a/src/Appwrite/Event/SyncIn.php b/src/Appwrite/Event/SyncIn.php new file mode 100644 index 0000000000..8413bbc5a8 --- /dev/null +++ b/src/Appwrite/Event/SyncIn.php @@ -0,0 +1,51 @@ +key = $key; + + return $this; + } + + /** + * Returns cache key. + * + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * Executes the event and sends it to the messaging worker. + * + * @return string|bool + * @throws \InvalidArgumentException + */ + public function trigger(): string|bool + { + return Resque::enqueue($this->queue, $this->class, [ + 'key' => $this->key, + ]); + } +} diff --git a/src/Appwrite/Event/SyncOut.php b/src/Appwrite/Event/SyncOut.php new file mode 100644 index 0000000000..73946e7e01 --- /dev/null +++ b/src/Appwrite/Event/SyncOut.php @@ -0,0 +1,51 @@ +key = $key; + + return $this; + } + + /** + * Returns cache key. + * + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * Executes the event and sends it to the messaging worker. + * + * @return string|bool + * @throws \InvalidArgumentException + */ + public function trigger(): string|bool + { + return Resque::enqueue($this->queue, $this->class, [ + 'key' => $this->key, + ]); + } +} From c6a054f88de2ab6c40c29659ef2d9847c29c5cdf Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 6 Oct 2022 15:33:57 +0300 Subject: [PATCH 02/87] redis-syncs --- app/config/services.php | 13 +++++++++++ app/controllers/api/syncs.php | 44 +++++++++++++++++++++++++++++++++++ app/workers/syncsIn.php | 20 ++++++++++++++++ app/workers/syncsOut.php | 42 +++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/syncs.php diff --git a/app/config/services.php b/app/config/services.php index 7369574a80..a1af27aa6e 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -186,4 +186,17 @@ 'optional' => false, 'icon' => '', ], + 'syncs' => [ + 'key' => 'syncs', + 'name' => 'syncs', + 'subtitle' => 'Appwrite\'s cloud regions syncs Endpoint', + 'description' => 'Syncs Endpoint', + 'controller' => 'api/syncs.php', + 'sdk' => false, + 'docs' => false, + 'docsUrl' => '', + 'tests' => true, + 'optional' => false, + 'icon' => '', + ], ]; diff --git a/app/controllers/api/syncs.php b/app/controllers/api/syncs.php new file mode 100644 index 0000000000..850f07600f --- /dev/null +++ b/app/controllers/api/syncs.php @@ -0,0 +1,44 @@ +desc('Purge cache keys') + ->label('scope', 'public') + ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') + ->inject('request') + ->inject('response') + ->action(function (array $keys, Request $request, Response $response) { + + if (empty($keys)) { + throw new Exception(Exception::KEY_NOT_FOUND); + } + + $token = $request->getHeader('authorization'); + $token = str_replace(["Bearer"," "], "", $token); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); +// try { +// $payload = $jwt->decode($token); +// } catch (JWTException $error) { +// throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); +// } + + $syncIn = new SyncIn(); + foreach ($keys as $key) { + $syncIn + ->addKey($key) + ->trigger(); + } + + $response + ->setStatusCode(Response::STATUS_CODE_OK) + ->send(); + }); diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php index 8fef867c14..d70e9cafca 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/syncsIn.php @@ -1,6 +1,8 @@ args['key'])) { + //var_dump('Purging -> ' . $this->args['key'] . ' from Redis cache'); + $this->getCache()->purge($this->args['key']); + } } + /** + * Get cache + * @return RedisCache + * @throws Exception + */ + private function getCache(): RedisCache + { + global $register; + + return new RedisCache($register->get('cache')); + } + + + public function shutdown(): void { } diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index d9e9260af2..af596e46d4 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -1,6 +1,8 @@ '172.17.0.1', + 'nyc1' => '172.17.0.1', + 'blr1' => '172.17.0.1', + ]; + public function getName(): string { return "syncs-out"; @@ -23,8 +31,38 @@ public function init(): void public function run(): void { - var_dump('run'); - var_dump($this->args['key']); + //TODO current region env implementation + $currentRegion = 'nyc1'; + + $data['keys'][] = $this->args['key']; + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); + $token = $jwt->encode($data); + + foreach ($this->regions as $region => $host) { + if ($currentRegion === $region) { + continue; + } + $ch = curl_init($host . '/v1/syncs'); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $token, + 'Content-Type: application/json' + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); + + for ($attempts = 0; $attempts < 6; $attempts++) { + curl_exec($ch); + $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($responseStatus === 200) { + break; + } + + sleep(2); + } + curl_close($ch); + } } From e25dd110498e634e4c0a1ad75311aea0beff326c Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 13 Oct 2022 09:27:55 +0300 Subject: [PATCH 03/87] static scope to instance --- app/controllers/api/syncs.php | 10 +++--- app/init.php | 60 ++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/controllers/api/syncs.php b/app/controllers/api/syncs.php index 850f07600f..e6181de62e 100644 --- a/app/controllers/api/syncs.php +++ b/app/controllers/api/syncs.php @@ -25,11 +25,11 @@ $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); -// try { -// $payload = $jwt->decode($token); -// } catch (JWTException $error) { -// throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); -// } + try { + $payload = $jwt->decode($token); + } catch (JWTException $error) { + throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); + } $syncIn = new SyncIn(); foreach ($keys as $key) { diff --git a/app/init.php b/app/init.php index e4c7663133..cd87dd6cc2 100644 --- a/app/init.php +++ b/app/init.php @@ -759,24 +759,6 @@ function (mixed $value) { 'hostname' => $request->getHostname(), ], Document::SET_TYPE_APPEND); - $register->set('syncOut', function () { - return new SyncOut(); - }); - - cache::on(cache::EVENT_PURGE, function ($key) use ($register) { - $register - ->get('syncOut') - ->addKey($key) - ->trigger(); - }); - - cache::on(cache::EVENT_SAVE, function ($key) use ($register) { - $register - ->get('syncOut') - ->addKey($key) - ->trigger(); - }); - /** * Get All verified client URLs for both console and current projects * + Filter for duplicated entries @@ -945,25 +927,59 @@ function (mixed $value) { ]); }, []); -App::setResource('dbForProject', function ($db, $cache, Document $project) { +$register->set('syncOut', function () { + return new SyncOut(); +}); + +App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { + $cache = new Cache(new RedisCache($cache)); + $cache->attach(cache::EVENT_SAVE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + $cache->attach(cache::EVENT_PURGE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace("_{$project->getInternalId()}"); return $database; -}, ['db', 'cache', 'project']); +}, ['db', 'cache', 'project', 'register']); + +App::setResource('dbForConsole', function ($db, $cache, $register) { -App::setResource('dbForConsole', function ($db, $cache) { $cache = new Cache(new RedisCache($cache)); + $cache->attach(cache::EVENT_SAVE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + $cache->attach(cache::EVENT_PURGE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_console'); return $database; -}, ['db', 'cache']); +}, ['db', 'cache', 'register']); App::setResource('deviceLocal', function () { From 9ccb26d09035064aaf4893d06a9d2847f3ba53bd Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 13 Oct 2022 09:28:47 +0300 Subject: [PATCH 04/87] composer.lock --- composer.lock | 5388 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5388 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..c1ba117837 --- /dev/null +++ b/composer.lock @@ -0,0 +1,5388 @@ +{ + "_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": "568151395a8877f87d9bdce048adc2dc", + "packages": [ + { + "name": "adhocore/jwt", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-jwt.git", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ahc\\Jwt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", + "keywords": [ + "auth", + "json-web-token", + "jwt", + "jwt-auth", + "jwt-php", + "token" + ], + "support": { + "issues": "https://github.com/adhocore/php-jwt/issues", + "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + } + ], + "time": "2021-02-20T09:56:44+00:00" + }, + { + "name": "appwrite/php-clamav", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/appwrite/php-clamav.git", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", + "shasum": "" + }, + "require": { + "ext-sockets": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\ClamAV\\": "src/ClamAV" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "ClamAV network and pipe client for PHP", + "keywords": [ + "anti virus", + "appwrite", + "clamav", + "php" + ], + "support": { + "issues": "https://github.com/appwrite/php-clamav/issues", + "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" + }, + "time": "2020-10-02T05:23:46+00:00" + }, + { + "name": "appwrite/php-runtimes", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/appwrite/runtimes.git", + "reference": "547fc026e11c0946846a8ac690898f5bf53be101" + }, + "require": { + "php": ">=8.0", + "utopia-php/system": "0.4.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\Runtimes\\": "src/Runtimes" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", + "keywords": [ + "appwrite", + "php", + "runtimes" + ], + "time": "2022-08-15T14:03:36+00:00" + }, + { + "name": "chillerlan/php-qrcode", + "version": "4.3.3", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-qrcode.git", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", + "shasum": "" + }, + "require": { + "chillerlan/php-settings-container": "^2.1", + "ext-mbstring": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", + "setasign/fpdf": "Required to use the QR FPDF output." + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\QRCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kazuhiko Arase", + "homepage": "https://github.com/kazuhikoarase" + }, + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + }, + { + "name": "Contributors", + "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" + } + ], + "description": "A QR code generator. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-qrcode", + "keywords": [ + "phpqrcode", + "qr", + "qr code", + "qrcode", + "qrcode-generator" + ], + "support": { + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2021-11-25T22:38:09+00:00" + }, + { + "name": "chillerlan/php-settings-container", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-settings-container.git", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\Settings\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + } + ], + "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-settings-container", + "keywords": [ + "PHP7", + "Settings", + "configuration", + "container", + "helper" + ], + "support": { + "issues": "https://github.com/chillerlan/php-settings-container/issues", + "source": "https://github.com/chillerlan/php-settings-container" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2022-07-05T22:32:14+00:00" + }, + { + "name": "colinmollenhour/credis", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "85df015088e00daf8ce395189de22c8eb45c8d49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/85df015088e00daf8ce395189de22c8eb45c8d49", + "reference": "85df015088e00daf8ce395189de22c8eb45c8d49", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "suggest": { + "ext-redis": "Improved performance for communicating with redis" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php", + "Module.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "support": { + "issues": "https://github.com/colinmollenhour/credis/issues", + "source": "https://github.com/colinmollenhour/credis/tree/v1.13.1" + }, + "time": "2022-06-20T22:56:59+00:00" + }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.5", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", + "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.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": "2022-01-17T14:14:24+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "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.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "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 + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "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.5.0" + }, + "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": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "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/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.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.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "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.4.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": "2022-08-28T14:45:39+00:00" + }, + { + "name": "influxdb/influxdb-php", + "version": "1.15.2", + "source": { + "type": "git", + "url": "https://github.com/influxdata/influxdb-php.git", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "Curl extension, needed for Curl driver", + "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." + }, + "type": "library", + "autoload": { + "psr-4": { + "InfluxDB\\": "src/InfluxDB" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Hoogendijk", + "email": "stephen@tca0.nl" + }, + { + "name": "Daniel Martinez", + "email": "danimartcas@hotmail.com" + }, + { + "name": "Gianluca Arbezzano", + "email": "gianarb92@gmail.com" + } + ], + "description": "InfluxDB client library for PHP", + "keywords": [ + "client", + "influxdata", + "influxdb", + "influxdb class", + "influxdb client", + "influxdb library", + "time series" + ], + "support": { + "issues": "https://github.com/influxdata/influxdb-php/issues", + "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" + }, + "time": "2020-12-26T17:45:17+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "1e0104b46f045868f11942aea058cd7186d6c303" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", + "reference": "1e0104b46f045868f11942aea058cd7186d6c303", + "shasum": "" + }, + "require": { + "composer/package-versions-deprecated": "^1.8.0", + "php": "^7.0|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0|^8.5|^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" + }, + "time": "2021-02-04T16:20:16+00:00" + }, + { + "name": "matomo/device-detector", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/matomo-org/device-detector.git", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", + "shasum": "" + }, + "require": { + "mustangostang/spyc": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "piwik/device-detector": "self.version" + }, + "require-dev": { + "matthiasmullie/scrapbook": "^1.4.7", + "mayflower/mo4-coding-standard": "^v8.0.0", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8.5.8", + "psr/cache": "^1.0.1", + "psr/simple-cache": "^1.0.1", + "symfony/yaml": "^5.1.7" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeviceDetector\\": "" + }, + "exclude-from-classmap": [ + "Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "homepage": "https://matomo.org", + "keywords": [ + "devicedetection", + "parser", + "useragent" + ], + "support": { + "forum": "https://forum.matomo.org/", + "issues": "https://github.com/matomo-org/device-detector/issues", + "source": "https://github.com/matomo-org/matomo", + "wiki": "https://dev.matomo.org/" + }, + "time": "2022-04-11T09:58:17+00:00" + }, + { + "name": "mongodb/mongodb", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/mongodb/mongo-php-library.git", + "reference": "953dbc19443aa9314c44b7217a16873347e6840d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d", + "reference": "953dbc19443aa9314c44b7217a16873347e6840d", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mongodb": "^1.8.1", + "jean85/pretty-package-versions": "^1.2", + "php": "^7.0 || ^8.0", + "symfony/polyfill-php80": "^1.19" + }, + "require-dev": { + "squizlabs/php_codesniffer": "^3.5, <3.5.5", + "symfony/phpunit-bridge": "5.x-dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "MongoDB\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Andreas Braun", + "email": "andreas.braun@mongodb.com" + }, + { + "name": "Jeremy Mikola", + "email": "jmikola@gmail.com" + } + ], + "description": "MongoDB driver library", + "homepage": "https://jira.mongodb.org/browse/PHPLIB", + "keywords": [ + "database", + "driver", + "mongodb", + "persistence" + ], + "support": { + "issues": "https://github.com/mongodb/mongo-php-library/issues", + "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0" + }, + "time": "2020-11-25T12:26:02+00:00" + }, + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2019-09-10T13:16:29+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.6.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.2", + "yoast/phpunit-polyfills": "^1.0.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2022-02-28T15:31:21+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.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": "http://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/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.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": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.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": "http://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/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "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/1.1.4" + }, + "time": "2021-05-03T11:20: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": "resque/php-resque", + "version": "v1.3.6", + "source": { + "type": "git", + "url": "https://github.com/resque/php-resque.git", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "~1.7", + "php": ">=5.6.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", + "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", + "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." + }, + "bin": [ + "bin/resque", + "bin/resque-scheduler" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Resque": "lib", + "ResqueScheduler": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Hunsaker", + "email": "danhunsaker+resque@gmail.com", + "role": "Maintainer" + }, + { + "name": "Rajib Ahmed", + "homepage": "https://github.com/rajibahmed", + "role": "Maintainer" + }, + { + "name": "Steve Klabnik", + "email": "steve@steveklabnik.com", + "role": "Maintainer" + }, + { + "name": "Chris Boulton", + "email": "chris@bigcommerce.com", + "role": "Creator" + } + ], + "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", + "homepage": "http://www.github.com/resque/php-resque/", + "keywords": [ + "background", + "job", + "redis", + "resque" + ], + "support": { + "issues": "https://github.com/resque/php-resque/issues", + "source": "https://github.com/resque/php-resque/tree/v1.3.6" + }, + "time": "2020-04-16T16:39:50+00:00" + }, + { + "name": "slickdeals/statsd", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/Slickdeals/statsd-php.git", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", + "shasum": "" + }, + "require": { + "php": ">= 7.3 || ^8" + }, + "replace": { + "domnikl/statsd": "self.version" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Domnikl\\Statsd\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dominik Liebler", + "email": "liebler.dominik@gmail.com" + } + ], + "description": "a PHP client for statsd", + "homepage": "https://github.com/Slickdeals/statsd-php", + "keywords": [ + "Metrics", + "monitoring", + "statistics", + "statsd", + "udp" + ], + "support": { + "issues": "https://github.com/Slickdeals/statsd-php/issues", + "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" + }, + "time": "2021-06-04T20:33:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.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": "2022-05-10T07:21:04+00:00" + }, + { + "name": "utopia-php/abuse", + "version": "0.13.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/abuse.git", + "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4c1b8fe742f17158c59550cdfd9074a94bf474ac", + "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.25.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Abuse\\": "src/Abuse" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple abuse library to manage application usage limits", + "keywords": [ + "Abuse", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/abuse/issues", + "source": "https://github.com/utopia-php/abuse/tree/0.13.1" + }, + "time": "2022-09-07T16:02:58+00:00" + }, + { + "name": "utopia-php/analytics", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/analytics.git", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Analytics\\": "src/Analytics" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library to track events & users.", + "keywords": [ + "analytics", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/analytics/issues", + "source": "https://github.com/utopia-php/analytics/tree/0.2.0" + }, + "time": "2021-03-23T21:33:07+00:00" + }, + { + "name": "utopia-php/audit", + "version": "0.14.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/audit.git", + "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/b011224ed9bfef7e5c849938e65619af28f7cf41", + "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.25.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Audit\\": "src/Audit" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple audit library to manage application users logs", + "keywords": [ + "Audit", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/audit/issues", + "source": "https://github.com/utopia-php/audit/tree/0.14.1" + }, + "time": "2022-09-07T16:03:16+00:00" + }, + { + "name": "utopia-php/cache", + "version": "0.6.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cache.git", + "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/9889235a6d3da6cbb1f435201529da4d27c30e79", + "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Cache\\": "src/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple cache library to manage application cache storing, loading and purging", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cache/issues", + "source": "https://github.com/utopia-php/cache/tree/0.6.1" + }, + "time": "2022-08-10T08:12:46+00:00" + }, + { + "name": "utopia-php/cli", + "version": "0.13.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cli.git", + "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/69e68f8ed525fe162fae950a0507ed28a0f179bc", + "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\CLI\\": "src/CLI" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple CLI library to manage command line applications", + "keywords": [ + "cli", + "command line", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cli/issues", + "source": "https://github.com/utopia-php/cli/tree/0.13.0" + }, + "time": "2022-04-26T08:41:22+00:00" + }, + { + "name": "utopia-php/config", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/config.git", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Config\\": "src/Config" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Config library to managing application config variables", + "keywords": [ + "config", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/config/issues", + "source": "https://github.com/utopia-php/config/tree/0.2.2" + }, + "time": "2020-10-24T09:49:09+00:00" + }, + { + "name": "utopia-php/database", + "version": "0.25.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "2883de82eee99e5744bf6e4123095a530c48a194" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/2883de82eee99e5744bf6e4123095a530c48a194", + "reference": "2883de82eee99e5744bf6e4123095a530c48a194", + "shasum": "" + }, + "require": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "mongodb/mongodb": "1.8.0", + "php": ">=8.0", + "utopia-php/cache": "0.6.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "fakerphp/faker": "^1.14", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "4.8.0", + "utopia-php/cli": "^0.11.0", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Database\\": "src/Database" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Brandon Leckemby", + "email": "brandon@appwrite.io" + } + ], + "description": "A simple library to manage application persistency using multiple database adapters", + "keywords": [ + "database", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/database/issues", + "source": "https://github.com/utopia-php/database/tree/0.25.4" + }, + "time": "2022-09-14T06:22:33+00:00" + }, + { + "name": "utopia-php/domains", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/domains.git", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Domains\\": "src/Domains" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "domains", + "framework", + "icann", + "php", + "public suffix", + "tld", + "tld extract", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/domains/issues", + "source": "https://github.com/utopia-php/domains/tree/master" + }, + "time": "2020-02-23T07:40:02+00:00" + }, + { + "name": "utopia-php/framework", + "version": "0.21.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/framework.git", + "reference": "c81789b87a917da2daf336738170ebe01f50ea18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/c81789b87a917da2daf336738170ebe01f50ea18", + "reference": "c81789b87a917da2daf336738170ebe01f50ea18", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.10", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple, light and advanced PHP framework", + "keywords": [ + "framework", + "php", + "upf" + ], + "support": { + "issues": "https://github.com/utopia-php/framework/issues", + "source": "https://github.com/utopia-php/framework/tree/0.21.1" + }, + "time": "2022-09-07T09:56:28+00:00" + }, + { + "name": "utopia-php/image", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/image.git", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", + "shasum": "" + }, + "require": { + "ext-imagick": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Image\\": "src/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Image manipulation library", + "keywords": [ + "framework", + "image", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/image/issues", + "source": "https://github.com/utopia-php/image/tree/0.5.4" + }, + "time": "2022-05-11T12:30:41+00:00" + }, + { + "name": "utopia-php/locale", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/locale.git", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Locale\\": "src/Locale" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple locale library to manage application translations", + "keywords": [ + "framework", + "locale", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/locale/issues", + "source": "https://github.com/utopia-php/locale/tree/0.4.0" + }, + "time": "2021-07-24T11:35:55+00:00" + }, + { + "name": "utopia-php/logger", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/logger.git", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Logger\\": "src/Logger" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Matej Bačo", + "email": "matej@appwrite.io" + }, + { + "name": "Christy Jacob", + "email": "christy@appwrite.io" + } + ], + "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "appsignal", + "errors", + "framework", + "logger", + "logging", + "logs", + "php", + "raygun", + "sentry", + "upf", + "utopia", + "warnings" + ], + "support": { + "issues": "https://github.com/utopia-php/logger/issues", + "source": "https://github.com/utopia-php/logger/tree/0.3.0" + }, + "time": "2022-03-18T10:56:57+00:00" + }, + { + "name": "utopia-php/orchestration", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/orchestration.git", + "reference": "94263976413871efb6b16157a7101a81df3b6d78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/94263976413871efb6b16157a7101a81df3b6d78", + "reference": "94263976413871efb6b16157a7101a81df3b6d78", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.13.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Orchestration\\": "src/Orchestration" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Lite & fast micro PHP abstraction library for container orchestration", + "keywords": [ + "docker", + "framework", + "kubernetes", + "orchestration", + "php", + "swarm", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/orchestration/issues", + "source": "https://github.com/utopia-php/orchestration/tree/0.6.0" + }, + "time": "2022-07-13T16:47:18+00:00" + }, + { + "name": "utopia-php/preloader", + "version": "0.2.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/preloader.git", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Preloader\\": "src/Preloader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "team@appwrite.io" + } + ], + "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", + "keywords": [ + "framework", + "php", + "preload", + "preloader", + "preloading", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/preloader/issues", + "source": "https://github.com/utopia-php/preloader/tree/0.2.4" + }, + "time": "2020-10-24T07:04:59+00:00" + }, + { + "name": "utopia-php/registry", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/registry.git", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Registry\\": "src/Registry" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple dependency management library for PHP", + "keywords": [ + "dependency management", + "di", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/registry/issues", + "source": "https://github.com/utopia-php/registry/tree/0.5.0" + }, + "time": "2021-03-10T10:45:22+00:00" + }, + { + "name": "utopia-php/storage", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/storage.git", + "reference": "59802cf281d1976560cf6e353f250a9b870efddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", + "reference": "59802cf281d1976560cf6e353f250a9b870efddc", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-zlib": "*", + "ext-zstd": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Storage\\": "src/Storage" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Storage library to manage application storage", + "keywords": [ + "framework", + "php", + "storage", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/storage/issues", + "source": "https://github.com/utopia-php/storage/tree/0.11.0" + }, + "time": "2022-08-31T09:17:31+00:00" + }, + { + "name": "utopia-php/swoole", + "version": "0.3.3", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/swoole.git", + "reference": "8312df69233b5dcd3992de88f131f238002749de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/8312df69233b5dcd3992de88f131f238002749de", + "reference": "8312df69233b5dcd3992de88f131f238002749de", + "shasum": "" + }, + "require": { + "ext-swoole": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "swoole/ide-helper": "4.8.3", + "vimeo/psalm": "4.15.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Swoole\\": "src/Swoole" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "team@appwrite.io" + } + ], + "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", + "keywords": [ + "framework", + "http", + "php", + "server", + "swoole", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/swoole/issues", + "source": "https://github.com/utopia-php/swoole/tree/0.3.3" + }, + "time": "2022-01-20T09:58:43+00:00" + }, + { + "name": "utopia-php/system", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/system.git", + "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/system/zipball/67c92c66ce8f0cc925a00bca89f7a188bf9183c0", + "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\System\\": "src/System" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library for obtaining information about the host's system.", + "keywords": [ + "framework", + "php", + "system", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/system/issues", + "source": "https://github.com/utopia-php/system/tree/0.4.0" + }, + "time": "2021-02-04T14:14:49+00:00" + }, + { + "name": "utopia-php/websocket", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/websocket.git", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.6.6", + "textalk/websocket": "1.5.2", + "vimeo/psalm": "^4.8.1", + "workerman/workerman": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\WebSocket\\": "src/WebSocket" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple abstraction for WebSocket servers.", + "keywords": [ + "framework", + "php", + "upf", + "utopia", + "websocket" + ], + "support": { + "issues": "https://github.com/utopia-php/websocket/issues", + "source": "https://github.com/utopia-php/websocket/tree/0.1.0" + }, + "time": "2021-12-20T10:50:09+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "appwrite/sdk-generator", + "version": "0.28.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/sdk-generator.git", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "matthiasmullie/minify": "^1.3.68", + "php": ">=7.0.0", + "twig/twig": "^3.4.1" + }, + "require-dev": { + "brianium/paratest": "^6.4", + "phpunit/phpunit": "^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\SDK\\": "src/SDK", + "Appwrite\\Spec\\": "src/Spec" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", + "support": { + "issues": "https://github.com/appwrite/sdk-generator/issues", + "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" + }, + "time": "2022-09-22T09:15:54+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "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.22" + }, + "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.4.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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.69", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", + "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.0", + "matthiasmullie/scrapbook": "dev-master", + "phpunit/phpunit": ">=4.8" + }, + "suggest": { + "psr/cache-implementation": "Cache implementation to use with Minify::cache" + }, + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", + "homepage": "http://www.minifier.org", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2022-08-01T09:00:18+00:00" + }, + { + "name": "matthiasmullie/path-converter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/path-converter.git", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\PathConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "pathconverter@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Relative path converter", + "homepage": "http://github.com/matthiasmullie/path-converter", + "keywords": [ + "converter", + "path", + "paths", + "relative" + ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, + "time": "2019-02-05T23:41:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + }, + "time": "2022-09-04T07:30:47+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.17", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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 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", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-08-30T12:24:04+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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 calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "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", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "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/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library 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/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "4.8.9", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "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/4.8.9" + }, + "funding": [ + { + "url": "https://gitee.com/swoole/swoole?donate=true", + "type": "custom" + }, + { + "url": "https://github.com/swoole", + "type": "github" + } + ], + "time": "2022-04-18T20:38:04+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.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": "2022-05-24T11:49:31+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.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": "2022-05-24T11:49:31+00:00" + }, + { + "name": "textalk/websocket", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/Textalk/websocket-php.git", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "shasum": "" + }, + "require": { + "php": "^7.2 | ^8.0", + "psr/log": "^1 | ^2 | ^3" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "soren@abicart.se" + } + ], + "description": "WebSocket client and server", + "support": { + "issues": "https://github.com/Textalk/websocket-php/issues", + "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" + }, + "time": "2022-03-29T09:46:59+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "twig/twig", + "version": "v3.4.3", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2022-09-28T08:42:51+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0.0", + "ext-curl": "*", + "ext-imagick": "*", + "ext-mbstring": "*", + "ext-json": "*", + "ext-yaml": "*", + "ext-dom": "*", + "ext-redis": "*", + "ext-swoole": "*", + "ext-pdo": "*", + "ext-openssl": "*", + "ext-zlib": "*", + "ext-sockets": "*" + }, + "platform-dev": { + "ext-fileinfo": "*" + }, + "platform-overrides": { + "php": "8.0" + }, + "plugin-api-version": "2.2.0" +} From ae57ac67819ae6e8619c12f974e4dcb86f4df55a Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 18 Oct 2022 10:06:46 +0300 Subject: [PATCH 05/87] composer.lock --- app/init.php | 41 +- app/workers/syncsIn.php | 1 + composer.lock | 5388 --------------------------------------- docker-compose.yml | 1 + 4 files changed, 22 insertions(+), 5409 deletions(-) delete mode 100644 composer.lock diff --git a/app/init.php b/app/init.php index f91c81db1d..3e7dfd3874 100644 --- a/app/init.php +++ b/app/init.php @@ -933,20 +933,19 @@ function (mixed $value) { App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { $cache = new Cache(new RedisCache($cache)); - - $cache->attach(cache::EVENT_SAVE, function ($key) use ($register) { + $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { $register ->get('syncOut') ->addKey($key) ->trigger(); }); - $cache->attach(cache::EVENT_PURGE, function ($key) use ($register) { - $register - ->get('syncOut') - ->addKey($key) - ->trigger(); - }); +// $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { +// $register +// ->get('syncOut') +// ->addKey($key) +// ->trigger(); +// }); $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); @@ -959,19 +958,19 @@ function (mixed $value) { $cache = new Cache(new RedisCache($cache)); - $cache->attach(cache::EVENT_SAVE, function ($key) use ($register) { - $register - ->get('syncOut') - ->addKey($key) - ->trigger(); - }); - - $cache->attach(cache::EVENT_PURGE, function ($key) use ($register) { - $register - ->get('syncOut') - ->addKey($key) - ->trigger(); - }); +// $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { +// $register +// ->get('syncOut') +// ->addKey($key) +// ->trigger(); +// }); +// +// $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { +// $register +// ->get('syncOut') +// ->addKey($key) +// ->trigger(); +// }); $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php index d70e9cafca..77841f6eb5 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/syncsIn.php @@ -27,6 +27,7 @@ public function run(): void { if (!empty($this->args['key'])) { //var_dump('Purging -> ' . $this->args['key'] . ' from Redis cache'); + //$this->getCache()->purge($this->args['key']); $this->getCache()->purge($this->args['key']); } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 0c984066b8..0000000000 --- a/composer.lock +++ /dev/null @@ -1,5388 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "568151395a8877f87d9bdce048adc2dc", - "packages": [ - { - "name": "adhocore/jwt", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/adhocore/php-jwt.git", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ahc\\Jwt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jitendra Adhikari", - "email": "jiten.adhikary@gmail.com" - } - ], - "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", - "keywords": [ - "auth", - "json-web-token", - "jwt", - "jwt-auth", - "jwt-php", - "token" - ], - "support": { - "issues": "https://github.com/adhocore/php-jwt/issues", - "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" - }, - "funding": [ - { - "url": "https://paypal.me/ji10", - "type": "custom" - } - ], - "time": "2021-02-20T09:56:44+00:00" - }, - { - "name": "appwrite/php-clamav", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/php-clamav.git", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", - "shasum": "" - }, - "require": { - "ext-sockets": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\ClamAV\\": "src/ClamAV" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "ClamAV network and pipe client for PHP", - "keywords": [ - "anti virus", - "appwrite", - "clamav", - "php" - ], - "support": { - "issues": "https://github.com/appwrite/php-clamav/issues", - "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" - }, - "time": "2020-10-02T05:23:46+00:00" - }, - { - "name": "appwrite/php-runtimes", - "version": "0.11.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/runtimes.git", - "reference": "547fc026e11c0946846a8ac690898f5bf53be101" - }, - "require": { - "php": ">=8.0", - "utopia-php/system": "0.4.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\Runtimes\\": "src/Runtimes" - } - }, - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", - "keywords": [ - "appwrite", - "php", - "runtimes" - ], - "time": "2022-08-15T14:03:36+00:00" - }, - { - "name": "chillerlan/php-qrcode", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", - "shasum": "" - }, - "require": { - "chillerlan/php-settings-container": "^2.1", - "ext-mbstring": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5", - "setasign/fpdf": "^1.8.2" - }, - "suggest": { - "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", - "setasign/fpdf": "Required to use the QR FPDF output." - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\QRCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" - }, - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - }, - { - "name": "Contributors", - "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" - } - ], - "description": "A QR code generator. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-qrcode", - "keywords": [ - "phpqrcode", - "qr", - "qr code", - "qrcode", - "qrcode-generator" - ], - "support": { - "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2021-11-25T22:38:09+00:00" - }, - { - "name": "chillerlan/php-settings-container", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\Settings\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - } - ], - "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-settings-container", - "keywords": [ - "PHP7", - "Settings", - "configuration", - "container", - "helper" - ], - "support": { - "issues": "https://github.com/chillerlan/php-settings-container/issues", - "source": "https://github.com/chillerlan/php-settings-container" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2022-07-05T22:32:14+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "v1.13.1", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/85df015088e00daf8ce395189de22c8eb45c8d49", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "suggest": { - "ext-redis": "Improved performance for communicating with redis" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php", - "Module.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "support": { - "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.13.1" - }, - "time": "2022-06-20T22:56:59+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.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": "2022-01-17T14:14:24+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2022-01-18T15:43:28+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", - "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.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "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 - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "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.5.0" - }, - "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": "2022-08-28T15:39:27+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "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/1.5.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2022-08-28T14:55:35+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.4.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.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.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "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.4.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": "2022-08-28T14:45:39+00:00" - }, - { - "name": "influxdb/influxdb-php", - "version": "1.15.2", - "source": { - "type": "git", - "url": "https://github.com/influxdata/influxdb-php.git", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0|^7.0", - "php": "^5.5 || ^7.0 || ^8.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.2.1", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "Curl extension, needed for Curl driver", - "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." - }, - "type": "library", - "autoload": { - "psr-4": { - "InfluxDB\\": "src/InfluxDB" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Hoogendijk", - "email": "stephen@tca0.nl" - }, - { - "name": "Daniel Martinez", - "email": "danimartcas@hotmail.com" - }, - { - "name": "Gianluca Arbezzano", - "email": "gianarb92@gmail.com" - } - ], - "description": "InfluxDB client library for PHP", - "keywords": [ - "client", - "influxdata", - "influxdb", - "influxdb class", - "influxdb client", - "influxdb library", - "time series" - ], - "support": { - "issues": "https://github.com/influxdata/influxdb-php/issues", - "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" - }, - "time": "2020-12-26T17:45:17+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.8.0", - "php": "^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0|^8.5|^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" - }, - "time": "2021-02-04T16:20:16+00:00" - }, - { - "name": "matomo/device-detector", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/matomo-org/device-detector.git", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", - "shasum": "" - }, - "require": { - "mustangostang/spyc": "*", - "php": "^7.2|^8.0" - }, - "replace": { - "piwik/device-detector": "self.version" - }, - "require-dev": { - "matthiasmullie/scrapbook": "^1.4.7", - "mayflower/mo4-coding-standard": "^v8.0.0", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5.8", - "psr/cache": "^1.0.1", - "psr/simple-cache": "^1.0.1", - "symfony/yaml": "^5.1.7" - }, - "suggest": { - "doctrine/cache": "Can directly be used for caching purpose", - "ext-yaml": "Necessary for using the Pecl YAML parser" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeviceDetector\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "The Matomo Team", - "email": "hello@matomo.org", - "homepage": "https://matomo.org/team/" - } - ], - "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", - "homepage": "https://matomo.org", - "keywords": [ - "devicedetection", - "parser", - "useragent" - ], - "support": { - "forum": "https://forum.matomo.org/", - "issues": "https://github.com/matomo-org/device-detector/issues", - "source": "https://github.com/matomo-org/matomo", - "wiki": "https://dev.matomo.org/" - }, - "time": "2022-04-11T09:58:17+00:00" - }, - { - "name": "mongodb/mongodb", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/mongodb/mongo-php-library.git", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d", - "shasum": "" - }, - "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mongodb": "^1.8.1", - "jean85/pretty-package-versions": "^1.2", - "php": "^7.0 || ^8.0", - "symfony/polyfill-php80": "^1.19" - }, - "require-dev": { - "squizlabs/php_codesniffer": "^3.5, <3.5.5", - "symfony/phpunit-bridge": "5.x-dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "MongoDB\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andreas Braun", - "email": "andreas.braun@mongodb.com" - }, - { - "name": "Jeremy Mikola", - "email": "jmikola@gmail.com" - } - ], - "description": "MongoDB driver library", - "homepage": "https://jira.mongodb.org/browse/PHPLIB", - "keywords": [ - "database", - "driver", - "mongodb", - "persistence" - ], - "support": { - "issues": "https://github.com/mongodb/mongo-php-library/issues", - "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0" - }, - "time": "2020-11-25T12:26:02+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "git@github.com:mustangostang/spyc.git", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2019-09-10T13:16:29+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.2", - "yoast/phpunit-polyfills": "^1.0.0" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2022-02-28T15:31:21+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20: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": "resque/php-resque", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/resque/php-resque.git", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "~1.7", - "php": ">=5.6.0", - "psr/log": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "suggest": { - "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", - "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", - "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." - }, - "bin": [ - "bin/resque", - "bin/resque-scheduler" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Resque": "lib", - "ResqueScheduler": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dan Hunsaker", - "email": "danhunsaker+resque@gmail.com", - "role": "Maintainer" - }, - { - "name": "Rajib Ahmed", - "homepage": "https://github.com/rajibahmed", - "role": "Maintainer" - }, - { - "name": "Steve Klabnik", - "email": "steve@steveklabnik.com", - "role": "Maintainer" - }, - { - "name": "Chris Boulton", - "email": "chris@bigcommerce.com", - "role": "Creator" - } - ], - "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", - "homepage": "http://www.github.com/resque/php-resque/", - "keywords": [ - "background", - "job", - "redis", - "resque" - ], - "support": { - "issues": "https://github.com/resque/php-resque/issues", - "source": "https://github.com/resque/php-resque/tree/v1.3.6" - }, - "time": "2020-04-16T16:39:50+00:00" - }, - { - "name": "slickdeals/statsd", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/Slickdeals/statsd-php.git", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", - "shasum": "" - }, - "require": { - "php": ">= 7.3 || ^8" - }, - "replace": { - "domnikl/statsd": "self.version" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Domnikl\\Statsd\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dominik Liebler", - "email": "liebler.dominik@gmail.com" - } - ], - "description": "a PHP client for statsd", - "homepage": "https://github.com/Slickdeals/statsd-php", - "keywords": [ - "Metrics", - "monitoring", - "statistics", - "statsd", - "udp" - ], - "support": { - "issues": "https://github.com/Slickdeals/statsd-php/issues", - "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" - }, - "time": "2021-06-04T20:33:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-02-25T11:15:52+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.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": "2022-05-10T07:21:04+00:00" - }, - { - "name": "utopia-php/abuse", - "version": "0.13.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4c1b8fe742f17158c59550cdfd9074a94bf474ac", - "reference": "4c1b8fe742f17158c59550cdfd9074a94bf474ac", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Abuse\\": "src/Abuse" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple abuse library to manage application usage limits", - "keywords": [ - "Abuse", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.13.1" - }, - "time": "2022-09-07T16:02:58+00:00" - }, - { - "name": "utopia-php/analytics", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/analytics.git", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Analytics\\": "src/Analytics" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library to track events & users.", - "keywords": [ - "analytics", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.2.0" - }, - "time": "2021-03-23T21:33:07+00:00" - }, - { - "name": "utopia-php/audit", - "version": "0.14.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/audit.git", - "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/b011224ed9bfef7e5c849938e65619af28f7cf41", - "reference": "b011224ed9bfef7e5c849938e65619af28f7cf41", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Audit\\": "src/Audit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple audit library to manage application users logs", - "keywords": [ - "Audit", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.14.1" - }, - "time": "2022-09-07T16:03:16+00:00" - }, - { - "name": "utopia-php/cache", - "version": "0.6.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cache.git", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/9889235a6d3da6cbb1f435201529da4d27c30e79", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-redis": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Cache\\": "src/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple cache library to manage application cache storing, loading and purging", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.6.1" - }, - "time": "2022-08-10T08:12:46+00:00" - }, - { - "name": "utopia-php/cli", - "version": "0.13.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cli.git", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/69e68f8ed525fe162fae950a0507ed28a0f179bc", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc", - "shasum": "" - }, - "require": { - "php": ">=7.4", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\CLI\\": "src/CLI" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple CLI library to manage command line applications", - "keywords": [ - "cli", - "command line", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.13.0" - }, - "time": "2022-04-26T08:41:22+00:00" - }, - { - "name": "utopia-php/config", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/config.git", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Config\\": "src/Config" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Config library to managing application config variables", - "keywords": [ - "config", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/config/issues", - "source": "https://github.com/utopia-php/config/tree/0.2.2" - }, - "time": "2020-10-24T09:49:09+00:00" - }, - { - "name": "utopia-php/database", - "version": "0.25.5", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "6d1c1d46d66553154975a3e8e72d30b5bd2413d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/6d1c1d46d66553154975a3e8e72d30b5bd2413d9", - "reference": "6d1c1d46d66553154975a3e8e72d30b5bd2413d9", - "shasum": "" - }, - "require": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "mongodb/mongodb": "1.8.0", - "php": ">=8.0", - "utopia-php/cache": "0.6.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "fakerphp/faker": "^1.14", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.11.0", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Database\\": "src/Database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Brandon Leckemby", - "email": "brandon@appwrite.io" - } - ], - "description": "A simple library to manage application persistency using multiple database adapters", - "keywords": [ - "database", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.25.5" - }, - "time": "2022-09-30T15:01:32+00:00" - }, - { - "name": "utopia-php/domains", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Domains\\": "src/Domains" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "domains", - "framework", - "icann", - "php", - "public suffix", - "tld", - "tld extract", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/master" - }, - "time": "2020-02-23T07:40:02+00:00" - }, - { - "name": "utopia-php/framework", - "version": "0.21.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/c81789b87a917da2daf336738170ebe01f50ea18", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.10", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.21.1" - }, - "time": "2022-09-07T09:56:28+00:00" - }, - { - "name": "utopia-php/image", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/image.git", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", - "shasum": "" - }, - "require": { - "ext-imagick": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Image\\": "src/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Image manipulation library", - "keywords": [ - "framework", - "image", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.4" - }, - "time": "2022-05-11T12:30:41+00:00" - }, - { - "name": "utopia-php/locale", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/locale.git", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Locale\\": "src/Locale" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple locale library to manage application translations", - "keywords": [ - "framework", - "locale", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/locale/issues", - "source": "https://github.com/utopia-php/locale/tree/0.4.0" - }, - "time": "2021-07-24T11:35:55+00:00" - }, - { - "name": "utopia-php/logger", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Logger\\": "src/Logger" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], - "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "appsignal", - "errors", - "framework", - "logger", - "logging", - "logs", - "php", - "raygun", - "sentry", - "upf", - "utopia", - "warnings" - ], - "support": { - "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" - }, - "time": "2022-03-18T10:56:57+00:00" - }, - { - "name": "utopia-php/orchestration", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/orchestration.git", - "reference": "94263976413871efb6b16157a7101a81df3b6d78" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/94263976413871efb6b16157a7101a81df3b6d78", - "reference": "94263976413871efb6b16157a7101a81df3b6d78", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.13.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Orchestration\\": "src/Orchestration" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Lite & fast micro PHP abstraction library for container orchestration", - "keywords": [ - "docker", - "framework", - "kubernetes", - "orchestration", - "php", - "swarm", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.6.0" - }, - "time": "2022-07-13T16:47:18+00:00" - }, - { - "name": "utopia-php/preloader", - "version": "0.2.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/preloader.git", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Preloader\\": "src/Preloader" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", - "keywords": [ - "framework", - "php", - "preload", - "preloader", - "preloading", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/preloader/issues", - "source": "https://github.com/utopia-php/preloader/tree/0.2.4" - }, - "time": "2020-10-24T07:04:59+00:00" - }, - { - "name": "utopia-php/registry", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/registry.git", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Registry\\": "src/Registry" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple dependency management library for PHP", - "keywords": [ - "dependency management", - "di", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/registry/issues", - "source": "https://github.com/utopia-php/registry/tree/0.5.0" - }, - "time": "2021-03-10T10:45:22+00:00" - }, - { - "name": "utopia-php/storage", - "version": "0.11.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/storage.git", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-zlib": "*", - "ext-zstd": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Storage\\": "src/Storage" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Storage library to manage application storage", - "keywords": [ - "framework", - "php", - "storage", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.11.0" - }, - "time": "2022-08-31T09:17:31+00:00" - }, - { - "name": "utopia-php/swoole", - "version": "0.3.3", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/swoole.git", - "reference": "8312df69233b5dcd3992de88f131f238002749de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/8312df69233b5dcd3992de88f131f238002749de", - "reference": "8312df69233b5dcd3992de88f131f238002749de", - "shasum": "" - }, - "require": { - "ext-swoole": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "swoole/ide-helper": "4.8.3", - "vimeo/psalm": "4.15.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Swoole\\": "src/Swoole" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", - "keywords": [ - "framework", - "http", - "php", - "server", - "swoole", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.3.3" - }, - "time": "2022-01-20T09:58:43+00:00" - }, - { - "name": "utopia-php/system", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/system.git", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/67c92c66ce8f0cc925a00bca89f7a188bf9183c0", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\System\\": "src/System" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library for obtaining information about the host's system.", - "keywords": [ - "framework", - "php", - "system", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.4.0" - }, - "time": "2021-02-04T14:14:49+00:00" - }, - { - "name": "utopia-php/websocket", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/websocket.git", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.6.6", - "textalk/websocket": "1.5.2", - "vimeo/psalm": "^4.8.1", - "workerman/workerman": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\WebSocket\\": "src/WebSocket" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple abstraction for WebSocket servers.", - "keywords": [ - "framework", - "php", - "upf", - "utopia", - "websocket" - ], - "support": { - "issues": "https://github.com/utopia-php/websocket/issues", - "source": "https://github.com/utopia-php/websocket/tree/0.1.0" - }, - "time": "2021-12-20T10:50:09+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "appwrite/sdk-generator", - "version": "0.28.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "matthiasmullie/minify": "^1.3.68", - "php": ">=7.0.0", - "twig/twig": "^3.4.1" - }, - "require-dev": { - "brianium/paratest": "^6.4", - "phpunit/phpunit": "^9.5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\SDK\\": "src/SDK", - "Appwrite\\Spec\\": "src/Spec" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "support": { - "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" - }, - "time": "2022-09-22T09:15:54+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "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.22" - }, - "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.4.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%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.69", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" - }, - "funding": [ - { - "url": "https://github.com/matthiasmullie", - "type": "github" - } - ], - "time": "2022-08-01T09:00:18+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.17", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-08-30T12:24:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library 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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "swoole/ide-helper", - "version": "4.8.9", - "source": { - "type": "git", - "url": "https://github.com/swoole/ide-helper.git", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "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/4.8.9" - }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-04-18T20:38:04+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.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": "2022-05-24T11:49:31+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.7", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" - }, - "time": "2022-03-29T09:46:59+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "twig/twig", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "time": "2022-09-28T08:42:51+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0.0", - "ext-curl": "*", - "ext-imagick": "*", - "ext-mbstring": "*", - "ext-json": "*", - "ext-yaml": "*", - "ext-dom": "*", - "ext-redis": "*", - "ext-swoole": "*", - "ext-pdo": "*", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-sockets": "*" - }, - "platform-dev": { - "ext-fileinfo": "*" - }, - "platform-overrides": { - "php": "8.0" - }, - "plugin-api-version": "2.2.0" -} diff --git a/docker-compose.yml b/docker-compose.yml index 7b4803c78a..f41bddfcb7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -207,6 +207,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb - redis From 462b30b721ab32addc6276eb274e6262d417bc9d Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 18 Oct 2022 18:42:41 +0300 Subject: [PATCH 06/87] failed request log --- app/config/collections.php | 56 +++++++++++++++++++++++++++++ app/controllers/api/syncs.php | 6 ++-- app/init.php | 57 +++++++++++++++++++---------- app/preload.php | 1 + app/realtime.php | 2 ++ app/tasks/maintenance.php | 42 +++++++++++++++++----- app/workers/deletes.php | 10 ++++++ app/workers/syncsOut.php | 65 ++++++++++++++++++++++------------ composer.json | 2 +- composer.lock | 56 +++++++++++++++++------------ docker-compose.yml | 10 ++++-- src/Appwrite/Event/Delete.php | 11 ++++++ src/Appwrite/Event/SyncOut.php | 24 +++++++++++++ 13 files changed, 264 insertions(+), 78 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index d8f65da788..58d00c85aa 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -18,6 +18,62 @@ */ $collections = [ + 'syncs' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('syncs'), + 'name' => 'Syncs', + 'attributes' => [ + [ + '$id' => ID::custom('region'), + 'type' => Database::VAR_STRING, + 'size' => 256, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('keys'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => true, + 'default' => [], + 'array' => false, + 'filters' => ['json'], + ], + [ + '$id' => ID::custom('requestedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('status'), + 'type' => Database::VAR_INTEGER, + 'size' => 256, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + ], + 'indexes' => [ + [ + '$id' => ID::custom('_key_requestedAt_status'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['requestedAt', 'status'], + 'lengths' => [], + 'orders' => [], + ], + ], + ], 'databases' => [ '$collection' => ID::custom(Database::METADATA), '$id' => ID::custom('databases'), diff --git a/app/controllers/api/syncs.php b/app/controllers/api/syncs.php index e6181de62e..ccd6f82c8f 100644 --- a/app/controllers/api/syncs.php +++ b/app/controllers/api/syncs.php @@ -18,13 +18,13 @@ ->inject('response') ->action(function (array $keys, Request $request, Response $response) { - if (empty($keys)) { + //if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - } + //} $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); try { $payload = $jwt->decode($token); } catch (JWTException $error) { diff --git a/app/init.php b/app/init.php index e621956c15..efb6554c54 100644 --- a/app/init.php +++ b/app/init.php @@ -154,6 +154,7 @@ const DELETE_TYPE_SESSIONS = 'sessions'; const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp'; const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource'; +const DELETE_TYPE_SYNCS = 'syncs'; // Compression type const COMPRESSION_TYPE_NONE = 'none'; const COMPRESSION_TYPE_GZIP = 'gzip'; @@ -930,6 +931,10 @@ function (mixed $value) { return new SyncOut(); }); +$register->set('deletes', function () { + return new Delete(); +}); + App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { $cache = new Cache(new RedisCache($cache)); @@ -940,12 +945,19 @@ function (mixed $value) { ->trigger(); }); -// $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { -// $register -// ->get('syncOut') -// ->addKey($key) -// ->trigger(); -// }); + $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + $cache->on(cache::EVENT_FLUSH, function ($region) use ($register) { + $register + ->get('deletes') + ->setRegion($region) + ->trigger(); + }); $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); @@ -958,19 +970,26 @@ function (mixed $value) { $cache = new Cache(new RedisCache($cache)); -// $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { -// $register -// ->get('syncOut') -// ->addKey($key) -// ->trigger(); -// }); -// -// $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { -// $register -// ->get('syncOut') -// ->addKey($key) -// ->trigger(); -// }); + $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { + $register + ->get('syncOut') + ->addKey($key) + ->trigger(); + }); + + $cache->on(cache::EVENT_FLUSH, function ($region) use ($register) { + $register + ->get('deletes') + ->setRegion($region) + ->trigger(); + }); $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); diff --git a/app/preload.php b/app/preload.php index bf8b0bfd1d..fb63a381b6 100644 --- a/app/preload.php +++ b/app/preload.php @@ -35,6 +35,7 @@ realpath(__DIR__ . '/../vendor/symfony'), realpath(__DIR__ . '/../vendor/mongodb'), realpath(__DIR__ . '/../vendor/utopia-php/websocket'), // TODO: remove workerman autoload + realpath(__DIR__ . '/../vendor/utopia-php/cache'), // TODO: Remove when memcached ext issue get fixed ] as $key => $value ) { if ($value !== false) { diff --git a/app/realtime.php b/app/realtime.php index be87c3d6e6..2263f3c396 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -171,6 +171,7 @@ function () use ($register, $db, $redis) { */ Timer::tick(5000, function () use ($register, $stats, &$statsDocument, $logError) { $payload = []; + foreach ($stats as $projectId => $value) { $payload[$projectId] = $stats->get($projectId, 'connectionsTotal'); } @@ -187,6 +188,7 @@ function () use ($register, $db, $redis) { Authorization::skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument)); } catch (\Throwable $th) { + call_user_func($logError, $th, "updateWorkerDocument"); } finally { call_user_func($returnDatabase); diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index 42b5ed00dc..c60a7f24dd 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -6,6 +6,7 @@ use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; use Appwrite\Event\Delete; +use Appwrite\Event\SyncOut; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -54,7 +55,7 @@ function getConsoleDB(): Database Console::title('Maintenance V1'); Console::success(APP_NAME . ' maintenance process v1 has started'); - function notifyDeleteExecutionLogs(int $interval) + function notifyDeleteExecutionLogs(int $interval): void { (new Delete()) ->setType(DELETE_TYPE_EXECUTIONS) @@ -62,7 +63,7 @@ function notifyDeleteExecutionLogs(int $interval) ->trigger(); } - function notifyDeleteAbuseLogs(int $interval) + function notifyDeleteAbuseLogs(int $interval): void { (new Delete()) ->setType(DELETE_TYPE_ABUSE) @@ -70,7 +71,7 @@ function notifyDeleteAbuseLogs(int $interval) ->trigger(); } - function notifyDeleteAuditLogs(int $interval) + function notifyDeleteAuditLogs(int $interval): void { (new Delete()) ->setType(DELETE_TYPE_AUDIT) @@ -78,7 +79,7 @@ function notifyDeleteAuditLogs(int $interval) ->trigger(); } - function notifyDeleteUsageStats(int $interval30m, int $interval1d) + function notifyDeleteUsageStats(int $interval30m, int $interval1d): void { (new Delete()) ->setType(DELETE_TYPE_USAGE) @@ -87,7 +88,7 @@ function notifyDeleteUsageStats(int $interval30m, int $interval1d) ->trigger(); } - function notifyDeleteConnections() + function notifyDeleteConnections(): void { (new Delete()) ->setType(DELETE_TYPE_REALTIME) @@ -95,7 +96,7 @@ function notifyDeleteConnections() ->trigger(); } - function notifyDeleteExpiredSessions() + function notifyDeleteExpiredSessions(): void { (new Delete()) ->setType(DELETE_TYPE_SESSIONS) @@ -103,7 +104,7 @@ function notifyDeleteExpiredSessions() ->trigger(); } - function renewCertificates($dbForConsole) + function renewCertificates($dbForConsole): void { $time = DateTime::now(); @@ -139,6 +140,29 @@ function notifyDeleteCache($interval) ->trigger(); } + function syncRegionalCache($dbForConsole): void + { + $time = DateTime::now(); + + $chunks = $dbForConsole->find('syncs', [ + Query::notEqual('status', 200), + Query::limit(300) + ]); + + if (\count($chunks) > 0) { + Console::info("[{$time}] Found " . \count($chunks) . " cache chunks to purge."); + foreach ($chunks as $chunk) { + $keys = $chunk->getAttribute('keys'); +// (new SyncOut()) + // ->setRegion($chunk->getAttribute('region')) +// ->addKey($key) +// ->trigger(); + } + } else { + Console::info("[{$time}] No certificates for renewal."); + } + } + // # of days in seconds (1 day = 86400s) $interval = (int) App::getEnv('_APP_MAINTENANCE_INTERVAL', '86400'); $executionLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', '1209600'); @@ -147,8 +171,9 @@ function notifyDeleteCache($interval) $usageStatsRetention30m = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_30M', '129600'); //36 hours $usageStatsRetention1d = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_1D', '8640000'); // 100 days $cacheRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_CACHE', '2592000'); // 30 days + $regionalCacheSyncRetention = (int) App::getEnv('_APP_MAINTENANCE_CACHE_SYNC', '300'); // 5 minutes - Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d, $cacheRetention) { + Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d, $cacheRetention, $regionalCacheSyncRetention) { $database = getConsoleDB(); $time = DateTime::now(); @@ -162,5 +187,6 @@ function notifyDeleteCache($interval) notifyDeleteExpiredSessions(); renewCertificates($database); notifyDeleteCache($cacheRetention); + syncRegionalCache($database); }, $interval); }); diff --git a/app/workers/deletes.php b/app/workers/deletes.php index b015043b1d..06205a961f 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -114,6 +114,9 @@ public function run(): void case DELETE_TYPE_CACHE_BY_TIMESTAMP: $this->deleteCacheByDate(); break; + case DELETE_TYPE_SYNCS: + $this->deleteRegionalCache(); + break; default: Console::error('No delete operation for type: ' . $type); break; @@ -675,4 +678,11 @@ protected function deleteBucket(Document $document, string $projectId) $device->deletePath($document->getId()); } + + protected function deleteRegionalCache() + { + $this->deleteByGroup('syncs', [ + Query::equal('region', [$this->args['region']]) + ], $this->getConsoleDB); + } } diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index af596e46d4..2498d9ebf6 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -4,6 +4,8 @@ use Appwrite\Resque\Worker; use Utopia\App; use Utopia\CLI\Console; +use Utopia\Database\DateTime; +use Utopia\Database\Document; require_once __DIR__ . '/../init.php'; @@ -12,8 +14,6 @@ class SyncsOutV1 extends Worker { - protected array $errors = []; - private array $regions = [ 'fra1' => '172.17.0.1', 'nyc1' => '172.17.0.1', @@ -35,36 +35,57 @@ public function run(): void $currentRegion = 'nyc1'; $data['keys'][] = $this->args['key']; - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode($data); + if (!empty($this->args['region'])) { + $this->regions = $this->regions[$this->args['region']]; + } + foreach ($this->regions as $region => $host) { if ($currentRegion === $region) { continue; } - $ch = curl_init($host . '/v1/syncs'); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Authorization: Bearer ' . $token, - 'Content-Type: application/json' - ]); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - - for ($attempts = 0; $attempts < 6; $attempts++) { - curl_exec($ch); - $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); - if ($responseStatus === 200) { - break; - } - - sleep(2); + + $status = $this->send($host, $token, $data); + if ($status !== 200) { + $this->getConsoleDB()->createDocument('syncs', new Document([ + 'requestedAt' => DateTime::now(), + 'region' => $region, + 'keys' => $data, + 'status' => $status, + ])); } - curl_close($ch); } } + private function send($host, $token, $data): int + { + + $ch = curl_init($host . '/v1/syncs'); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $token, + 'Content-Type: application/json' + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); + + for ($attempts = 0; $attempts < 3; $attempts++) { + curl_exec($ch); + $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($responseStatus === 200) { + return $responseStatus; + } + + sleep(2); + } + curl_close($ch); + return $responseStatus; + } + public function shutdown(): void { diff --git a/composer.json b/composer.json index 47317ed5e2..f302008567 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "utopia-php/abuse": "0.14.*", "utopia-php/analytics": "0.2.*", "utopia-php/audit": "0.15.*", - "utopia-php/cache": "0.6.*", + "utopia-php/cache": "dev-feat-redis-sync as 0.6.1", "utopia-php/cli": "0.13.*", "utopia-php/config": "0.2.*", "utopia-php/database": "0.26.*", diff --git a/composer.lock b/composer.lock index b4bbda3cef..3805593bd6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "08fdd139ad1285b02c4b4e555679e7de", + "content-hash": "1ceb54089b20b863e8685e1644ba51f9", "packages": [ { "name": "adhocore/jwt", @@ -1897,24 +1897,26 @@ }, { "name": "utopia-php/cache", - "version": "0.6.1", + "version": "dev-feat-redis-sync", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79" + "reference": "99e7085eb229d0f0159a4f2107ea5ea123f7b32b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/9889235a6d3da6cbb1f435201529da4d27c30e79", - "reference": "9889235a6d3da6cbb1f435201529da4d27c30e79", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/99e7085eb229d0f0159a4f2107ea5ea123f7b32b", + "reference": "99e7085eb229d0f0159a4f2107ea5ea123f7b32b", "shasum": "" }, "require": { "ext-json": "*", + "ext-memcached": "*", "ext-redis": "*", "php": ">=8.0" }, "require-dev": { + "laravel/pint": "1.2.*", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.13.1" }, @@ -1928,12 +1930,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], "description": "A simple cache library to manage application cache storing, loading and purging", "keywords": [ "cache", @@ -1944,9 +1940,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.6.1" + "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" }, - "time": "2022-08-10T08:12:46+00:00" + "time": "2022-10-18T06:58:42+00:00" }, { "name": "utopia-php/cli", @@ -3413,25 +3409,30 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.1", + "version": "1.6.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { @@ -3457,9 +3458,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" }, - "time": "2022-03-15T21:29:03+00:00" + "time": "2022-10-14T12:47:21+00:00" }, { "name": "phpspec/prophecy", @@ -5352,9 +5353,18 @@ "time": "2022-09-28T08:42:51+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "alias": "0.6.1", + "alias_normalized": "0.6.1.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/cache": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/docker-compose.yml b/docker-compose.yml index 55a4028ca6..cb34d788cc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -259,6 +259,7 @@ services: entrypoint: worker-syncs-out <<: *x-logging container_name: appwrite-worker-syncs-out + image: appwrite-dev build: context: . networks: @@ -266,8 +267,8 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: + - mariadb - redis environment: - _APP_ENV @@ -275,11 +276,17 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS appwrite-worker-syncs-in: entrypoint: worker-syncs-in <<: *x-logging container_name: appwrite-worker-syncs-in + image: appwrite-dev build: context: . networks: @@ -287,7 +294,6 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - redis environment: diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index 72ace2a86d..81de8ee939 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -13,6 +13,7 @@ class Delete extends Event protected ?string $datetime = null; protected ?string $dateTime30m = null; protected ?string $dateTime1d = null; + protected ?string $region = null; public function __construct() @@ -92,6 +93,16 @@ public function setDocument(Document $document): self return $this; } + /** + * Sets cloud region. + * + * @param string $region + */ + public function setRegion($region): void + { + $this->region = $region; + } + /** * Returns the resource for the delete event. * diff --git a/src/Appwrite/Event/SyncOut.php b/src/Appwrite/Event/SyncOut.php index 73946e7e01..bec0c65857 100644 --- a/src/Appwrite/Event/SyncOut.php +++ b/src/Appwrite/Event/SyncOut.php @@ -7,6 +7,7 @@ class SyncOut extends Event { protected string $key = ''; + protected string $region = ''; public function __construct() { @@ -36,6 +37,29 @@ public function getKey(): string return $this->key; } + /** + * Sets cloud region. + * + * @param string $region + * @return self + */ + public function setRegion(string $region): self + { + $this->host = $region; + + return $this; + } + + /** + * Returns cloud region. + * + * @return string + */ + public function getRegion(): string + { + return $this->region; + } + /** * Executes the event and sends it to the messaging worker. * From 70f1a3eaf8f279ff4b4568c134f70c75fb107bec Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 19 Oct 2022 12:36:45 +0300 Subject: [PATCH 07/87] cloud sync maintenance worker --- Dockerfile | 4 +- app/cli.php | 1 + app/config/collections.php | 13 ++- app/config/regions.php | 22 ++++++ app/config/services.php | 4 +- app/controllers/api/{syncs.php => edge.php} | 34 +++++++- app/init.php | 21 +---- app/tasks/maintenance.php | 29 +------ app/tasks/syncsCloud.php | 88 +++++++++++++++++++++ app/workers/deletes.php | 10 --- app/workers/syncsIn.php | 5 -- app/workers/syncsOut.php | 32 ++++---- bin/syncs-cloud | 3 + docker-compose.yml | 25 ++++++ src/Appwrite/Event/Delete.php | 10 --- 15 files changed, 207 insertions(+), 94 deletions(-) create mode 100644 app/config/regions.php rename app/controllers/api/{syncs.php => edge.php} (54%) create mode 100644 app/tasks/syncsCloud.php create mode 100644 bin/syncs-cloud diff --git a/Dockerfile b/Dockerfile index b2345f984e..1adc4d49e3 100755 --- a/Dockerfile +++ b/Dockerfile @@ -331,7 +331,8 @@ RUN mkdir -p /storage/uploads && \ # Executables RUN chmod +x /usr/local/bin/doctor && \ - chmod +x /usr/local/bin/maintenance && \ + chmod +x /usr/local/bin/maintenance && \ + chmod +x /usr/local/bin/syncs-cloud && \ chmod +x /usr/local/bin/usage && \ chmod +x /usr/local/bin/install && \ chmod +x /usr/local/bin/migrate && \ @@ -356,6 +357,7 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/worker-syncs-in + # Letsencrypt Permissions RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/ diff --git a/app/cli.php b/app/cli.php index 09b3dc9413..6fc8e73d3a 100644 --- a/app/cli.php +++ b/app/cli.php @@ -14,6 +14,7 @@ include 'tasks/doctor.php'; include 'tasks/maintenance.php'; +include 'tasks/syncsCloud.php'; include 'tasks/install.php'; include 'tasks/migrate.php'; include 'tasks/sdks.php'; diff --git a/app/config/collections.php b/app/config/collections.php index 58d00c85aa..5cfb09633a 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -24,9 +24,18 @@ 'name' => 'Syncs', 'attributes' => [ [ - '$id' => ID::custom('region'), + '$id' => ID::custom('regionOrg'), 'type' => Database::VAR_STRING, - 'size' => 256, + 'size' => 50, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('regionDest'), + 'type' => Database::VAR_STRING, + 'size' => 50, 'required' => true, 'signed' => true, 'array' => false, diff --git a/app/config/regions.php b/app/config/regions.php new file mode 100644 index 0000000000..75c7b6df56 --- /dev/null +++ b/app/config/regions.php @@ -0,0 +1,22 @@ + [ + 'name' => 'North america', + 'default' => true, + 'disabled' => false, + 'domain' => '172.17.0.1', + ], + 'blr1' => [ + 'name' => 'Asia', + 'default' => true, + 'disabled' => false, + 'domain' => '172.17.0.1', + ], + 'fra1' => [ + 'name' => 'Europe', + 'default' => true, + 'disabled' => false, + 'domain' => '172.17.0.1', + ], +]; diff --git a/app/config/services.php b/app/config/services.php index a1af27aa6e..9f4a5791f7 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -190,8 +190,8 @@ 'key' => 'syncs', 'name' => 'syncs', 'subtitle' => 'Appwrite\'s cloud regions syncs Endpoint', - 'description' => 'Syncs Endpoint', - 'controller' => 'api/syncs.php', + 'description' => 'Cloud edge Endpoint', + 'controller' => 'api/edge.php', 'sdk' => false, 'docs' => false, 'docsUrl' => '', diff --git a/app/controllers/api/syncs.php b/app/controllers/api/edge.php similarity index 54% rename from app/controllers/api/syncs.php rename to app/controllers/api/edge.php index ccd6f82c8f..61dc5f2916 100644 --- a/app/controllers/api/syncs.php +++ b/app/controllers/api/edge.php @@ -2,6 +2,7 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; +use Appwrite\Event\Delete; use Appwrite\Event\SyncIn; use Appwrite\Extend\Exception; use Appwrite\Utopia\Request; @@ -9,8 +10,9 @@ use Utopia\App; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; +use Utopia\Validator\WhiteList; -App::post('/v1/syncs') +App::post('/v1/edge') ->desc('Purge cache keys') ->label('scope', 'public') ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') @@ -18,9 +20,9 @@ ->inject('response') ->action(function (array $keys, Request $request, Response $response) { - //if (empty($keys)) { + if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - //} + } $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); @@ -42,3 +44,29 @@ ->setStatusCode(Response::STATUS_CODE_OK) ->send(); }); + +App::post('/v1/edge/notify') + ->desc('Flush notification') + ->label('scope', 'public') + ->param('region', '', new WhiteList(['nyc1', 'blr1', 'fra1']), 'Cloud regions') + ->inject('request') + ->inject('response') + ->action(function (string $region, Request $request, Response $response) { + + $token = $request->getHeader('authorization'); + $token = str_replace(["Bearer"," "], "", $token); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + try { + $payload = $jwt->decode($token); + } catch (JWTException $error) { + throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); + } + + (new Delete()) + ->setRegion($region) + ->trigger(); + + $response + ->setStatusCode(Response::STATUS_CODE_OK) + ->send(); + }); diff --git a/app/init.php b/app/init.php index efb6554c54..d0763c6295 100644 --- a/app/init.php +++ b/app/init.php @@ -37,7 +37,6 @@ use Appwrite\Event\Event; use Appwrite\Event\Mail; use Appwrite\Event\Phone; -use Appwrite\Event\SyncIn; use Appwrite\Network\Validator\Email; use Appwrite\Network\Validator\IP; use Appwrite\Network\Validator\URL; @@ -154,7 +153,6 @@ const DELETE_TYPE_SESSIONS = 'sessions'; const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp'; const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource'; -const DELETE_TYPE_SYNCS = 'syncs'; // Compression type const COMPRESSION_TYPE_NONE = 'none'; const COMPRESSION_TYPE_GZIP = 'gzip'; @@ -191,6 +189,7 @@ Config::load('scopes', __DIR__ . '/config/scopes.php'); // User roles and scopes Config::load('services', __DIR__ . '/config/services.php'); // List of services Config::load('variables', __DIR__ . '/config/variables.php'); // List of env variables +Config::load('regions', __DIR__ . '/config/regions.php'); // List of cloud regions Config::load('avatar-browsers', __DIR__ . '/config/avatars/browsers.php'); Config::load('avatar-credit-cards', __DIR__ . '/config/avatars/credit-cards.php'); Config::load('avatar-flags', __DIR__ . '/config/avatars/flags.php'); @@ -206,6 +205,7 @@ Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php'); Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php'); + $user = App::getEnv('_APP_REDIS_USER', ''); $pass = App::getEnv('_APP_REDIS_PASS', ''); if (!empty($user) || !empty($pass)) { @@ -931,10 +931,6 @@ function (mixed $value) { return new SyncOut(); }); -$register->set('deletes', function () { - return new Delete(); -}); - App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { $cache = new Cache(new RedisCache($cache)); @@ -952,12 +948,6 @@ function (mixed $value) { ->trigger(); }); - $cache->on(cache::EVENT_FLUSH, function ($region) use ($register) { - $register - ->get('deletes') - ->setRegion($region) - ->trigger(); - }); $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); @@ -984,13 +974,6 @@ function (mixed $value) { ->trigger(); }); - $cache->on(cache::EVENT_FLUSH, function ($region) use ($register) { - $register - ->get('deletes') - ->setRegion($region) - ->trigger(); - }); - $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_console'); diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index c60a7f24dd..fd111ca761 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -6,7 +6,6 @@ use Appwrite\Auth\Auth; use Appwrite\Event\Certificate; use Appwrite\Event\Delete; -use Appwrite\Event\SyncOut; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -140,30 +139,8 @@ function notifyDeleteCache($interval) ->trigger(); } - function syncRegionalCache($dbForConsole): void - { - $time = DateTime::now(); - - $chunks = $dbForConsole->find('syncs', [ - Query::notEqual('status', 200), - Query::limit(300) - ]); - - if (\count($chunks) > 0) { - Console::info("[{$time}] Found " . \count($chunks) . " cache chunks to purge."); - foreach ($chunks as $chunk) { - $keys = $chunk->getAttribute('keys'); -// (new SyncOut()) - // ->setRegion($chunk->getAttribute('region')) -// ->addKey($key) -// ->trigger(); - } - } else { - Console::info("[{$time}] No certificates for renewal."); - } - } - // # of days in seconds (1 day = 86400s) + // # of days in seconds (1 day = 86400s) $interval = (int) App::getEnv('_APP_MAINTENANCE_INTERVAL', '86400'); $executionLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', '1209600'); $auditLogRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', '1209600'); @@ -171,9 +148,8 @@ function syncRegionalCache($dbForConsole): void $usageStatsRetention30m = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_30M', '129600'); //36 hours $usageStatsRetention1d = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_1D', '8640000'); // 100 days $cacheRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_CACHE', '2592000'); // 30 days - $regionalCacheSyncRetention = (int) App::getEnv('_APP_MAINTENANCE_CACHE_SYNC', '300'); // 5 minutes - Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d, $cacheRetention, $regionalCacheSyncRetention) { + Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d, $cacheRetention) { $database = getConsoleDB(); $time = DateTime::now(); @@ -187,6 +163,5 @@ function syncRegionalCache($dbForConsole): void notifyDeleteExpiredSessions(); renewCertificates($database); notifyDeleteCache($cacheRetention); - syncRegionalCache($database); }, $interval); }); diff --git a/app/tasks/syncsCloud.php b/app/tasks/syncsCloud.php new file mode 100644 index 0000000000..276e20930f --- /dev/null +++ b/app/tasks/syncsCloud.php @@ -0,0 +1,88 @@ +get('cache'))); + $database = new Database(new MariaDB($register->get('db')), $cache); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + $database->setNamespace('_console'); // Main DB + + if (!$database->exists($database->getDefaultDatabase(), 'certificates')) { + throw new \Exception('Console project not ready'); + } + + break; // leave loop if successful + } catch (\Exception $e) { + Console::warning("Database not ready. Retrying connection ({$attempts})..."); + if ($attempts >= DATABASE_RECONNECT_MAX_ATTEMPTS) { + throw new \Exception('Failed to connect to database: ' . $e->getMessage()); + } + sleep(DATABASE_RECONNECT_SLEEP); + } + } while ($attempts < DATABASE_RECONNECT_MAX_ATTEMPTS); + + return $database; +} + +$cli + ->task('syncsCloud') + ->desc('Schedules cloud sync tasks') + ->action(function () { + Console::title('Syncs cloud V1'); + Console::success(APP_NAME . ' Syncs cloud process v1 has started'); + + function syncRegionalCache($dbForConsole, $regionOrg): void + { + $time = DateTime::now(); + $chunks = $dbForConsole->find('syncs', [ + Query::equal('regionOrg', [$regionOrg]), + Query::limit(500) + ]); + + if (count($chunks) > 0) { + Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); + foreach ($chunks as $chunk) { + $keys = $chunk->getAttribute('keys'); + foreach ($keys['keys'] ?? [] as $key) { + (new SyncOut()) + ->setRegion($chunk->getAttribute('region')) + ->addKey($key) + ->trigger(); + } + $dbForConsole->deleteDocument('syncs', $chunk->getId()); + } + } else { + Console::info("[{$time}] No cache key chunks where found."); + } + } + + $interval = (int) App::getEnv('_APP_SYNCS_CLOUD_INTERVAL', '180'); + + Console::loop(function () use ($interval) { + $database = getConsoleDatabase(); + $time = DateTime::now(); + $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); + Console::info("[{$time}] Notifying workers with cloud tasks every {$interval} seconds"); + syncRegionalCache($database, $currentRegion); + }, $interval); + }); diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 06205a961f..b015043b1d 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -114,9 +114,6 @@ public function run(): void case DELETE_TYPE_CACHE_BY_TIMESTAMP: $this->deleteCacheByDate(); break; - case DELETE_TYPE_SYNCS: - $this->deleteRegionalCache(); - break; default: Console::error('No delete operation for type: ' . $type); break; @@ -678,11 +675,4 @@ protected function deleteBucket(Document $document, string $projectId) $device->deletePath($document->getId()); } - - protected function deleteRegionalCache() - { - $this->deleteByGroup('syncs', [ - Query::equal('region', [$this->args['region']]) - ], $this->getConsoleDB); - } } diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php index 77841f6eb5..00c426ff10 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/syncsIn.php @@ -2,7 +2,6 @@ use Appwrite\Resque\Worker; use Utopia\Cache\Adapter\Redis as RedisCache; -use Utopia\Cache\Cache; use Utopia\CLI\Console; require_once __DIR__ . '/../init.php'; @@ -12,8 +11,6 @@ class SyncsInV1 extends Worker { - protected array $errors = []; - public function getName(): string { return "syncs-in"; @@ -26,8 +23,6 @@ public function init(): void public function run(): void { if (!empty($this->args['key'])) { - //var_dump('Purging -> ' . $this->args['key'] . ' from Redis cache'); - //$this->getCache()->purge($this->args['key']); $this->getCache()->purge($this->args['key']); } } diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index 2498d9ebf6..a622941768 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -2,10 +2,13 @@ use Ahc\Jwt\JWT; use Appwrite\Resque\Worker; +use Appwrite\Utopia\Response; use Utopia\App; use Utopia\CLI\Console; +use Utopia\Config\Config; use Utopia\Database\DateTime; use Utopia\Database\Document; +use Utopia\Response as ResponseAlias; require_once __DIR__ . '/../init.php'; @@ -14,11 +17,7 @@ class SyncsOutV1 extends Worker { - private array $regions = [ - 'fra1' => '172.17.0.1', - 'nyc1' => '172.17.0.1', - 'blr1' => '172.17.0.1', - ]; + private array $regions; public function getName(): string { @@ -27,14 +26,15 @@ public function getName(): string public function init(): void { + $this->regions = Config::getParam('regions', []); } public function run(): void { - //TODO current region env implementation - $currentRegion = 'nyc1'; - $data['keys'][] = $this->args['key']; + $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); + + $data[] = $this->args['key']; $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode($data); @@ -42,16 +42,18 @@ public function run(): void $this->regions = $this->regions[$this->args['region']]; } - foreach ($this->regions as $region => $host) { - if ($currentRegion === $region) { + foreach ($this->regions as $code => $region) { + if ($currentRegion === $code) { continue; } - $status = $this->send($host, $token, $data); - if ($status !== 200) { + $status = $this->send($region['domain'] . '/v1/edge', $token, ['keys' => $data]); + + if ($status !== Response::STATUS_CODE_OK) { $this->getConsoleDB()->createDocument('syncs', new Document([ 'requestedAt' => DateTime::now(), - 'region' => $region, + 'regionOrg' => $currentRegion, + 'regionDest' => $code, 'keys' => $data, 'status' => $status, ])); @@ -59,10 +61,10 @@ public function run(): void } } - private function send($host, $token, $data): int + private function send($url, $token, $data): int { - $ch = curl_init($host . '/v1/syncs'); + $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, 'Content-Type: application/json' diff --git a/bin/syncs-cloud b/bin/syncs-cloud new file mode 100644 index 0000000000..a321c87ed9 --- /dev/null +++ b/bin/syncs-cloud @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php syncsCloud $@ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index cb34d788cc..9868cbfe3e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -617,6 +617,31 @@ services: - _APP_MAINTENANCE_RETENTION_ABUSE - _APP_MAINTENANCE_RETENTION_AUDIT + appwrite-syncs-cloud: + entrypoint: syncs-cloud + <<: *x-logging + container_name: appwrite-syncs-cloud + image: appwrite-dev + networks: + - appwrite + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + appwrite-usage-timeseries: entrypoint: - usage diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index 81de8ee939..c7792f344f 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -93,16 +93,6 @@ public function setDocument(Document $document): self return $this; } - /** - * Sets cloud region. - * - * @param string $region - */ - public function setRegion($region): void - { - $this->region = $region; - } - /** * Returns the resource for the delete event. * From 45e8314b497b4bef99e4e2bb20ce7dcaa2ba30f8 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 20 Oct 2022 18:07:02 +0300 Subject: [PATCH 08/87] new worker --- app/controllers/api/edge.php | 52 +++----- app/init.php | 39 ++++-- app/preload.php | 1 + app/tasks/syncsCloud.php | 63 ++++++---- app/workers/syncsIn.php | 74 ++++++------ app/workers/syncsOut.php | 222 +++++++++++++++++++++++++---------- bin/worker-syncs-in | 9 +- bin/worker-syncs-out | 9 +- composer.json | 1 + composer.lock | 65 +++++++++- 10 files changed, 349 insertions(+), 186 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 61dc5f2916..fd124726c6 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -2,15 +2,16 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; -use Appwrite\Event\Delete; use Appwrite\Event\SyncIn; use Appwrite\Extend\Exception; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\Registry\Registry; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; -use Utopia\Validator\WhiteList; +use Utopia\Queue\Client; +use Utopia\Queue\Connection\Redis; App::post('/v1/edge') ->desc('Purge cache keys') @@ -18,11 +19,12 @@ ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') ->inject('request') ->inject('response') - ->action(function (array $keys, Request $request, Response $response) { + ->inject('register') + ->action(function (array $keys, Request $request, Response $response, Registry $register) { - if (empty($keys)) { + //if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - } + //} $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); @@ -33,39 +35,21 @@ throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); } - $syncIn = new SyncIn(); - foreach ($keys as $key) { - $syncIn - ->addKey($key) - ->trigger(); - } - - $response - ->setStatusCode(Response::STATUS_CODE_OK) - ->send(); - }); + $connection = $register + ->get('workerRedisConnection'); -App::post('/v1/edge/notify') - ->desc('Flush notification') - ->label('scope', 'public') - ->param('region', '', new WhiteList(['nyc1', 'blr1', 'fra1']), 'Cloud regions') - ->inject('request') - ->inject('response') - ->action(function (string $region, Request $request, Response $response) { + $client = new Client('syncIn', $connection); + $client->resetStats(); - $token = $request->getHeader('authorization'); - $token = str_replace(["Bearer"," "], "", $token); - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); - try { - $payload = $jwt->decode($token); - } catch (JWTException $error) { - throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); + foreach ($keys as $key) { + $client->enqueue([ + 'type' => 'from endpoint', + 'value' => [ + 'key' => $key + ] + ]); } - (new Delete()) - ->setRegion($region) - ->trigger(); - $response ->setStatusCode(Response::STATUS_CODE_OK) ->send(); diff --git a/app/init.php b/app/init.php index d0763c6295..470552fc74 100644 --- a/app/init.php +++ b/app/init.php @@ -48,6 +48,8 @@ use Utopia\Logger\Logger; use Utopia\Config\Config; use Utopia\Locale\Locale; +use Utopia\Queue\Client as clientQueue; +use Utopia\Queue\Connection\Redis as redisQueue; use Utopia\Registry\Registry; use MaxMind\Db\Reader; use PHPMailer\PHPMailer\PHPMailer; @@ -931,24 +933,47 @@ function (mixed $value) { return new SyncOut(); }); +$register->set('workerRedisConnection', function () { + return new redisQueue('redis', 6379); +}); + +$register->set('workerSyncOut', function () use ($register) { + return new clientQueue('syncOut', $register->get('workerRedisConnection')); +}); + + App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { $cache = new Cache(new RedisCache($cache)); $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { + $register - ->get('syncOut') - ->addKey($key) - ->trigger(); + ->get('workerSyncOut') + ->resetStats(); + $register + ->get('workerSyncOut') + ->enqueue([ + 'type' => 'saved from init', + 'value' => [ + 'key' => $key + ] + ]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { $register - ->get('syncOut') - ->addKey($key) - ->trigger(); + ->get('workerSyncOut') + ->resetStats(); + $register + ->get('workerSyncOut') + ->enqueue([ + 'type' => 'purge from init', + 'value' => [ + 'key' => $key + ] + ]); }); - $database = new Database(new MariaDB($db), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace("_{$project->getInternalId()}"); diff --git a/app/preload.php b/app/preload.php index fb63a381b6..e890f8fc83 100644 --- a/app/preload.php +++ b/app/preload.php @@ -36,6 +36,7 @@ realpath(__DIR__ . '/../vendor/mongodb'), realpath(__DIR__ . '/../vendor/utopia-php/websocket'), // TODO: remove workerman autoload realpath(__DIR__ . '/../vendor/utopia-php/cache'), // TODO: Remove when memcached ext issue get fixed + realpath(__DIR__ . '/../vendor/utopia-php/queue'), // TODO: Remove when memcached ext issue get fixed ] as $key => $value ) { if ($value !== false) { diff --git a/app/tasks/syncsCloud.php b/app/tasks/syncsCloud.php index 276e20930f..522a867a35 100644 --- a/app/tasks/syncsCloud.php +++ b/app/tasks/syncsCloud.php @@ -3,7 +3,6 @@ global $cli; global $register; -use Appwrite\Event\SyncOut; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -13,6 +12,7 @@ use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Database\Query; + function getConsoleDatabase(): Database { global $register; @@ -44,6 +44,42 @@ function getConsoleDatabase(): Database return $database; } +function syncRegionalCache($dbForConsole, $regionOrg): void +{ + global $register; + + $time = DateTime::now(); + $chunks = $dbForConsole->find('syncs', [ + Query::equal('regionOrg', [$regionOrg]), + Query::limit(500) + ]); + + if (count($chunks) > 0) { + Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); + foreach ($chunks as $chunk) { + $keys = $chunk->getAttribute('keys'); + foreach ($keys ?? [] as $key) { + $register + ->get('workerSyncOut') + ->resetStats(); + + $register + ->get('workerSyncOut') + ->enqueue([ + 'type' => 'from cloud maintenance', + 'value' => [ + 'region' => $chunk->getAttribute('regionDest'), + 'key' => $key + ] + ]); + } + $dbForConsole->deleteDocument('syncs', $chunk->getId()); + } + } else { + Console::info("[{$time}] No cache key chunks where found."); + } +} + $cli ->task('syncsCloud') ->desc('Schedules cloud sync tasks') @@ -51,31 +87,6 @@ function getConsoleDatabase(): Database Console::title('Syncs cloud V1'); Console::success(APP_NAME . ' Syncs cloud process v1 has started'); - function syncRegionalCache($dbForConsole, $regionOrg): void - { - $time = DateTime::now(); - $chunks = $dbForConsole->find('syncs', [ - Query::equal('regionOrg', [$regionOrg]), - Query::limit(500) - ]); - - if (count($chunks) > 0) { - Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); - foreach ($chunks as $chunk) { - $keys = $chunk->getAttribute('keys'); - foreach ($keys['keys'] ?? [] as $key) { - (new SyncOut()) - ->setRegion($chunk->getAttribute('region')) - ->addKey($key) - ->trigger(); - } - $dbForConsole->deleteDocument('syncs', $chunk->getId()); - } - } else { - Console::info("[{$time}] No cache key chunks where found."); - } - } - $interval = (int) App::getEnv('_APP_SYNCS_CLOUD_INTERVAL', '180'); Console::loop(function () use ($interval) { diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php index 00c426ff10..40031ca20e 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/syncsIn.php @@ -1,47 +1,49 @@ args['key'])) { - $this->getCache()->purge($this->args['key']); - } - } - - /** - * Get cache - * @return RedisCache - * @throws Exception - */ - private function getCache(): RedisCache - { - global $register; - - return new RedisCache($register->get('cache')); - } + global $register; + return new RedisCache($register->get('cache')); +} +$connection = new Queue\Connection\Redis('redis'); +$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncIn'); +$server = new Queue\Server($adapter); +$server->job() + ->inject('message') + ->action(function (Message $message) use (&$keys, &$counter) { - public function shutdown(): void - { - } -} + $payload = $message->getPayload()['value']; + if (!empty($payload['key'])) { + var_dump('purging ' . $payload['key']); + getCache()->purge($payload['key']); + } + }); + +$server + ->error() + ->inject('error') + ->action(function ($error) { + echo $error->getMessage() . PHP_EOL; + }); + +$server + ->workerStart(function () { + echo "In region [" . CURRENT_REGION . "] cache purging worker Started" . PHP_EOL; + }) + ->start(); diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index a622941768..46e924aa0b 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -1,95 +1,187 @@ regions = Config::getParam('regions', []); + switch ($type) { + case DATABASE_PROJECT: + if (!$projectId) { + throw new \Exception('ProjectID not provided - cannot get database'); + } + $namespace = "_{$projectInternalId}"; + break; + case DATABASE_CONSOLE: + $namespace = "_console"; + $sleep = 5; // ConsoleDB needs extra sleep time to ensure tables are created + break; + default: + throw new \Exception('Unknown database type: ' . $type); + break; } - public function run(): void - { + $attempts = 0; - $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); + do { + try { + $attempts++; + $cache = new Cache(new RedisCache($register->get('cache'))); + $database = new Database(new MariaDB($register->get('db')), $cache); + $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + $database->setNamespace($namespace); // Main DB - $data[] = $this->args['key']; - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); - $token = $jwt->encode($data); + if (!empty($projectId) && !$database->getDocument('projects', $projectId)->isEmpty()) { + throw new \Exception("Project does not exist: {$projectId}"); + } - if (!empty($this->args['region'])) { - $this->regions = $this->regions[$this->args['region']]; - } + if ($type === DATABASE_CONSOLE && !$database->exists($database->getDefaultDatabase(), Database::METADATA)) { + throw new \Exception('Console project not ready'); + } - foreach ($this->regions as $code => $region) { - if ($currentRegion === $code) { - continue; + break; // leave loop if successful + } catch (\Exception $e) { + Console::warning("Database not ready. Retrying connection ({$attempts})..."); + if ($attempts >= DATABASE_RECONNECT_MAX_ATTEMPTS) { + throw new \Exception('Failed to connect to database: ' . $e->getMessage()); } + sleep($sleep); + } + } while ($attempts < DATABASE_RECONNECT_MAX_ATTEMPTS); - $status = $this->send($region['domain'] . '/v1/edge', $token, ['keys' => $data]); + return $database; +} - if ($status !== Response::STATUS_CODE_OK) { - $this->getConsoleDB()->createDocument('syncs', new Document([ - 'requestedAt' => DateTime::now(), - 'regionOrg' => $currentRegion, - 'regionDest' => $code, - 'keys' => $data, - 'status' => $status, - ])); - } +function send($url, $token, $keys): int +{ + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $token, + 'Content-Type: application/json' + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($keys)); + + for ($attempts = 0; $attempts < 5; $attempts++) { + curl_exec($ch); + $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($responseStatus === 200) { + return $responseStatus; } + + sleep(2); } + curl_close($ch); + return $responseStatus; +} - private function send($url, $token, $data): int - { - - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Authorization: Bearer ' . $token, - 'Content-Type: application/json' - ]); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - - for ($attempts = 0; $attempts < 3; $attempts++) { - curl_exec($ch); - $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - if ($responseStatus === 200) { - return $responseStatus; - } +$connection = new Queue\Connection\Redis('redis'); +$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); +$server = new Queue\Server($adapter); + +$server->job() + ->inject('message') + ->action(function (Message $message) use (&$keys, &$counter) { + + $payload = $message->getPayload()['value']; + $regions = Config::getParam('regions', true); - sleep(2); + if (!empty($payload['region'])) { + $tmp = $regions[$payload['region']]; + $regions = []; + $regions[$payload['region']] = $tmp; } - curl_close($ch); - return $responseStatus; - } + $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); + $keys[$payload['key']] = null; + + if (count($keys) > MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { + + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + $token = $jwt->encode([]); + + foreach ($regions as $code => $region) { + if (CURRENT_REGION === $code) { + continue; + } + + $status = send($region['domain'] . '/v1/edge', $token, ['keys' => array_keys($keys)]); + +// var_dump([ +// 'keyscount' => count($keys), +// 'keys' => array_keys($keys), +// 'timestamp' => date('m/d/Y H:i:s', $counter) +// ]); + + if ($status !== Response::STATUS_CODE_OK) { + getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ + 'requestedAt' => DateTime::now(), + 'regionOrg' => $currentRegion, + 'regionDest' => $code, + 'keys' => array_keys($keys), + 'status' => $status, + ])); + } + } - public function shutdown(): void - { - } -} + $counter = time(); + $keys = []; + //var_dump('new time set -> ' . $counter); + //var_dump($keys); + } + }); + +$server + ->error() + ->inject('error') + ->action(function ($error) { + echo $error->getMessage() . PHP_EOL; + echo $error->getLine() . PHP_EOL; + }); + +$server + ->workerStart(function () { + echo "Out region [" . CURRENT_REGION . "] cache purging worker Started" . PHP_EOL; + }) + ->start(); diff --git a/bin/worker-syncs-in b/bin/worker-syncs-in index f82d859e1f..6b973c44fe 100644 --- a/bin/worker-syncs-in +++ b/bin/worker-syncs-in @@ -1,10 +1,3 @@ #!/bin/sh -if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] -then - REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -else - REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -fi - -INTERVAL=0.1 QUEUE='v1-syncs-in' APP_INCLUDE='/usr/src/code/app/workers/syncsIn.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file +php /usr/src/code/app/workers/syncsIn.php $@ \ No newline at end of file diff --git a/bin/worker-syncs-out b/bin/worker-syncs-out index 523ecd5270..8117e84b34 100644 --- a/bin/worker-syncs-out +++ b/bin/worker-syncs-out @@ -1,10 +1,3 @@ #!/bin/sh -if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] -then - REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -else - REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -fi - -INTERVAL=0.1 QUEUE='v1-syncs-out' APP_INCLUDE='/usr/src/code/app/workers/syncsOut.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file +php /usr/src/code/app/workers/syncsOut.php $@ \ No newline at end of file diff --git a/composer.json b/composer.json index f302008567..58f3070f7e 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,7 @@ "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.6.*", + "utopia-php/queue": "0.3.*", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", "dragonmantank/cron-expression": "3.3.1", diff --git a/composer.lock b/composer.lock index db9ee209a7..6f7efe70a3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1ceb54089b20b863e8685e1644ba51f9", + "content-hash": "73ea3ea466d02c3c6427d235c11554ff", "packages": [ { "name": "adhocore/jwt", @@ -2492,6 +2492,67 @@ }, "time": "2020-10-24T07:04:59+00:00" }, + { + "name": "utopia-php/queue", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/queue.git", + "reference": "42b132c6f2431b726c2bc629c386921e4934b863" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/42b132c6f2431b726c2bc629c386921e4934b863", + "reference": "42b132c6f2431b726c2bc629c386921e4934b863", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.13.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "^0.2.3", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.8.8", + "workerman/workerman": "^4.0" + }, + "suggest": { + "ext-swoole": "Needed to support Swoole.", + "workerman/workerman": "Needed to support Workerman." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Queue\\": "src/Queue" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A powerful task queue.", + "keywords": [ + "Tasks", + "framework", + "php", + "queue", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/queue/issues", + "source": "https://github.com/utopia-php/queue/tree/0.3.0" + }, + "time": "2022-10-19T13:22:07+00:00" + }, { "name": "utopia-php/registry", "version": "0.5.0", @@ -5388,5 +5449,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } From 7cfdde3d91209c777b43a1a61203cba05b2c477d Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 09:39:50 +0300 Subject: [PATCH 09/87] support for failed log --- app/controllers/api/edge.php | 4 +- app/tasks/syncsCloud.php | 6 +-- app/workers/syncsOut.php | 88 ++++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index fd124726c6..c8c8c13719 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -22,9 +22,9 @@ ->inject('register') ->action(function (array $keys, Request $request, Response $response, Registry $register) { - //if (empty($keys)) { + if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - //} + } $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); diff --git a/app/tasks/syncsCloud.php b/app/tasks/syncsCloud.php index 522a867a35..fff3dafa94 100644 --- a/app/tasks/syncsCloud.php +++ b/app/tasks/syncsCloud.php @@ -57,8 +57,6 @@ function syncRegionalCache($dbForConsole, $regionOrg): void if (count($chunks) > 0) { Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); foreach ($chunks as $chunk) { - $keys = $chunk->getAttribute('keys'); - foreach ($keys ?? [] as $key) { $register ->get('workerSyncOut') ->resetStats(); @@ -69,10 +67,10 @@ function syncRegionalCache($dbForConsole, $regionOrg): void 'type' => 'from cloud maintenance', 'value' => [ 'region' => $chunk->getAttribute('regionDest'), - 'key' => $key + 'chunk' => $chunk->getAttribute('keys') ] ]); - } + $dbForConsole->deleteDocument('syncs', $chunk->getId()); } } else { diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index 46e924aa0b..b0029a10dd 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -13,6 +13,8 @@ use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\DateTime; +use Utopia\Database\Exception\Authorization; +use Utopia\Database\Exception\Structure; use Utopia\Queue; use Utopia\Queue\Message; @@ -23,10 +25,12 @@ const DATABASE_PROJECT = 'project'; const DATABASE_CONSOLE = 'console'; -const SUBMITION_INTERVAL = 10; -const MAX_KEY_COUNT = 100; +const SUBMITION_INTERVAL = 20; +const MAX_KEY_COUNT = 10; +const MAX_CURL_SEND_ATTEMPTS = 4; define("CURRENT_REGION", App::getEnv('_APP_REGION', 'nyc1')); + /** * Get console database * @param string $type One of (internal, external, console) @@ -39,7 +43,6 @@ function getDB(string $type, string $projectId = '', string $projectInternalId = { global $register; - $namespace = ''; $sleep = DATABASE_RECONNECT_SLEEP; // overwritten when necessary switch ($type) { @@ -102,7 +105,7 @@ function send($url, $token, $keys): int curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($keys)); - for ($attempts = 0; $attempts < 5; $attempts++) { + for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { curl_exec($ch); $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); @@ -116,6 +119,31 @@ function send($url, $token, $keys): int return $responseStatus; } +/** + * @throws Authorization + * @throws Structure + * @throws Exception + */ +function call($regions, $keys): void +{ + + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + $token = $jwt->encode([]); + + foreach ($regions as $code => $region) { + $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); + if ($status !== Response::STATUS_CODE_OK) { + getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ + 'requestedAt' => DateTime::now(), + 'regionOrg' => CURRENT_REGION, + 'regionDest' => $code, + 'keys' => $keys, + 'status' => $status, + ])); + } + } +} + $connection = new Queue\Connection\Redis('redis'); $adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); $server = new Queue\Server($adapter); @@ -126,49 +154,31 @@ function send($url, $token, $keys): int $payload = $message->getPayload()['value']; $regions = Config::getParam('regions', true); + $regions = array_filter( + $regions, + fn ($region) => CURRENT_REGION !== $region, + ARRAY_FILTER_USE_KEY + ); if (!empty($payload['region'])) { - $tmp = $regions[$payload['region']]; - $regions = []; - $regions[$payload['region']] = $tmp; + $regions = array_filter( + $regions, + fn ($region) => $payload['region'] === $region, + ARRAY_FILTER_USE_KEY + ); } - $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); - $keys[$payload['key']] = null; - - if (count($keys) > MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { - - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); - $token = $jwt->encode([]); - - foreach ($regions as $code => $region) { - if (CURRENT_REGION === $code) { - continue; - } - $status = send($region['domain'] . '/v1/edge', $token, ['keys' => array_keys($keys)]); - -// var_dump([ -// 'keyscount' => count($keys), -// 'keys' => array_keys($keys), -// 'timestamp' => date('m/d/Y H:i:s', $counter) -// ]); - - if ($status !== Response::STATUS_CODE_OK) { - getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ - 'requestedAt' => DateTime::now(), - 'regionOrg' => $currentRegion, - 'regionDest' => $code, - 'keys' => array_keys($keys), - 'status' => $status, - ])); - } - } + if (!empty($payload['chunk'])) { + call($regions, $payload['chunk']); + return; + } + $keys[$payload['key']] = null; + if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { + call($regions, array_keys($keys)); $counter = time(); $keys = []; - //var_dump('new time set -> ' . $counter); - //var_dump($keys); } }); From e30952c48ba51192f6bc89a33dd65174682844d5 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 09:57:02 +0300 Subject: [PATCH 10/87] support for failed log --- app/tasks/syncsCloud.php | 4 +- app/workers/syncsOut.php | 13 ++++++ src/Appwrite/Event/Delete.php | 1 - src/Appwrite/Event/Event.php | 6 --- src/Appwrite/Event/SyncIn.php | 51 ----------------------- src/Appwrite/Event/SyncOut.php | 75 ---------------------------------- 6 files changed, 15 insertions(+), 135 deletions(-) delete mode 100644 src/Appwrite/Event/SyncIn.php delete mode 100644 src/Appwrite/Event/SyncOut.php diff --git a/app/tasks/syncsCloud.php b/app/tasks/syncsCloud.php index fff3dafa94..3f1adef031 100644 --- a/app/tasks/syncsCloud.php +++ b/app/tasks/syncsCloud.php @@ -44,7 +44,7 @@ function getConsoleDatabase(): Database return $database; } -function syncRegionalCache($dbForConsole, $regionOrg): void +function resendFailedRequest($dbForConsole, $regionOrg): void { global $register; @@ -92,6 +92,6 @@ function syncRegionalCache($dbForConsole, $regionOrg): void $time = DateTime::now(); $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); Console::info("[{$time}] Notifying workers with cloud tasks every {$interval} seconds"); - syncRegionalCache($database, $currentRegion); + resendFailedRequest($database, $currentRegion); }, $interval); }); diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index b0029a10dd..a300052bf9 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -132,6 +132,7 @@ function call($regions, $keys): void foreach ($regions as $code => $region) { $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); + var_dump('Sending request...............'); if ($status !== Response::STATUS_CODE_OK) { getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ 'requestedAt' => DateTime::now(), @@ -170,12 +171,24 @@ function call($regions, $keys): void if (!empty($payload['chunk'])) { + var_dump('from chunk'); call($regions, $payload['chunk']); return; } $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { + var_dump('from key'); + var_dump([ + 'regions' => array_keys($regions), + 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), + 'because_count' => count($keys) >= MAX_KEY_COUNT, + 'count' => count($keys), + 'counter' => $counter + SUBMITION_INTERVAL, + 'time' => time(), + + + ]); call($regions, array_keys($keys)); $counter = time(); $keys = []; diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index c7792f344f..72ace2a86d 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -13,7 +13,6 @@ class Delete extends Event protected ?string $datetime = null; protected ?string $dateTime30m = null; protected ?string $dateTime1d = null; - protected ?string $region = null; public function __construct() diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index 4315de44b5..222cf59444 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -35,12 +35,6 @@ class Event public const MESSAGING_QUEUE_NAME = 'v1-messaging'; public const MESSAGING_CLASS_NAME = 'MessagingV1'; - public const SYNCS_IN_QUEUE_NAME = 'v1-syncs-in'; - public const SYNCS_IN_CLASS_NAME = 'SyncsInV1'; - - public const SYNCS_OUT_QUEUE_NAME = 'v1-syncs-out'; - public const SYNCS_OUT_CLASS_NAME = 'SyncsOutV1'; - protected string $queue = ''; protected string $class = ''; protected string $event = ''; diff --git a/src/Appwrite/Event/SyncIn.php b/src/Appwrite/Event/SyncIn.php deleted file mode 100644 index 8413bbc5a8..0000000000 --- a/src/Appwrite/Event/SyncIn.php +++ /dev/null @@ -1,51 +0,0 @@ -key = $key; - - return $this; - } - - /** - * Returns cache key. - * - * @return string - */ - public function getKey(): string - { - return $this->key; - } - - /** - * Executes the event and sends it to the messaging worker. - * - * @return string|bool - * @throws \InvalidArgumentException - */ - public function trigger(): string|bool - { - return Resque::enqueue($this->queue, $this->class, [ - 'key' => $this->key, - ]); - } -} diff --git a/src/Appwrite/Event/SyncOut.php b/src/Appwrite/Event/SyncOut.php deleted file mode 100644 index bec0c65857..0000000000 --- a/src/Appwrite/Event/SyncOut.php +++ /dev/null @@ -1,75 +0,0 @@ -key = $key; - - return $this; - } - - /** - * Returns cache key. - * - * @return string - */ - public function getKey(): string - { - return $this->key; - } - - /** - * Sets cloud region. - * - * @param string $region - * @return self - */ - public function setRegion(string $region): self - { - $this->host = $region; - - return $this; - } - - /** - * Returns cloud region. - * - * @return string - */ - public function getRegion(): string - { - return $this->region; - } - - /** - * Executes the event and sends it to the messaging worker. - * - * @return string|bool - * @throws \InvalidArgumentException - */ - public function trigger(): string|bool - { - return Resque::enqueue($this->queue, $this->class, [ - 'key' => $this->key, - ]); - } -} From d70dd6a6bc7c9ba0c043951cd8dadfa659688634 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 09:59:10 +0300 Subject: [PATCH 11/87] support for failed log --- app/workers/syncsOut.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index a300052bf9..b0029a10dd 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -132,7 +132,6 @@ function call($regions, $keys): void foreach ($regions as $code => $region) { $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); - var_dump('Sending request...............'); if ($status !== Response::STATUS_CODE_OK) { getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ 'requestedAt' => DateTime::now(), @@ -171,24 +170,12 @@ function call($regions, $keys): void if (!empty($payload['chunk'])) { - var_dump('from chunk'); call($regions, $payload['chunk']); return; } $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { - var_dump('from key'); - var_dump([ - 'regions' => array_keys($regions), - 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), - 'because_count' => count($keys) >= MAX_KEY_COUNT, - 'count' => count($keys), - 'counter' => $counter + SUBMITION_INTERVAL, - 'time' => time(), - - - ]); call($regions, array_keys($keys)); $counter = time(); $keys = []; From 7e2ae346241c5879eef4f71a652a93ca5af7b463 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 10:15:09 +0300 Subject: [PATCH 12/87] remove requestedAt attr --- app/config/collections.php | 15 ++------------- app/init.php | 33 +++++++++++++++++++++------------ app/workers/syncsOut.php | 14 +++++++++++++- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 5cfb09633a..d148e31b9d 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -52,17 +52,6 @@ 'array' => false, 'filters' => ['json'], ], - [ - '$id' => ID::custom('requestedAt'), - 'type' => Database::VAR_DATETIME, - 'format' => '', - 'size' => 0, - 'signed' => false, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => ['datetime'], - ], [ '$id' => ID::custom('status'), 'type' => Database::VAR_INTEGER, @@ -75,9 +64,9 @@ ], 'indexes' => [ [ - '$id' => ID::custom('_key_requestedAt_status'), + '$id' => ID::custom('_key_status'), 'type' => Database::INDEX_KEY, - 'attributes' => ['requestedAt', 'status'], + 'attributes' => ['status'], 'lengths' => [], 'orders' => [], ], diff --git a/app/init.php b/app/init.php index 470552fc74..6cf3ef3953 100644 --- a/app/init.php +++ b/app/init.php @@ -929,10 +929,6 @@ function (mixed $value) { ]); }, []); -$register->set('syncOut', function () { - return new SyncOut(); -}); - $register->set('workerRedisConnection', function () { return new redisQueue('redis', 6379); }); @@ -982,21 +978,34 @@ function (mixed $value) { }, ['db', 'cache', 'project', 'register']); App::setResource('dbForConsole', function ($db, $cache, $register) { - $cache = new Cache(new RedisCache($cache)); - $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { + $register - ->get('syncOut') - ->addKey($key) - ->trigger(); + ->get('workerSyncOut') + ->resetStats(); + $register + ->get('workerSyncOut') + ->enqueue([ + 'type' => 'saved from init', + 'value' => [ + 'key' => $key + ] + ]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { $register - ->get('syncOut') - ->addKey($key) - ->trigger(); + ->get('workerSyncOut') + ->resetStats(); + $register + ->get('workerSyncOut') + ->enqueue([ + 'type' => 'purge from init', + 'value' => [ + 'key' => $key + ] + ]); }); $database = new Database(new MariaDB($db), $cache); diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index b0029a10dd..000af2bf5c 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -132,9 +132,9 @@ function call($regions, $keys): void foreach ($regions as $code => $region) { $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); + var_dump('Sending request...............'); if ($status !== Response::STATUS_CODE_OK) { getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ - 'requestedAt' => DateTime::now(), 'regionOrg' => CURRENT_REGION, 'regionDest' => $code, 'keys' => $keys, @@ -170,12 +170,24 @@ function call($regions, $keys): void if (!empty($payload['chunk'])) { + var_dump('from chunk'); call($regions, $payload['chunk']); return; } $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { + var_dump('from key'); + var_dump([ + 'regions' => array_keys($regions), + 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), + 'because_count' => count($keys) >= MAX_KEY_COUNT, + 'count' => count($keys), + 'counter' => $counter + SUBMITION_INTERVAL, + 'time' => time(), + + + ]); call($regions, array_keys($keys)); $counter = time(); $keys = []; From 1e2e82593fde0383da5e118977f27a7601c34e03 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 10:17:35 +0300 Subject: [PATCH 13/87] remove requestedAt attr --- app/workers/syncsOut.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index 000af2bf5c..326862fa31 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -132,7 +132,6 @@ function call($regions, $keys): void foreach ($regions as $code => $region) { $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); - var_dump('Sending request...............'); if ($status !== Response::STATUS_CODE_OK) { getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ 'regionOrg' => CURRENT_REGION, @@ -170,24 +169,12 @@ function call($regions, $keys): void if (!empty($payload['chunk'])) { - var_dump('from chunk'); call($regions, $payload['chunk']); return; } $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { - var_dump('from key'); - var_dump([ - 'regions' => array_keys($regions), - 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), - 'because_count' => count($keys) >= MAX_KEY_COUNT, - 'count' => count($keys), - 'counter' => $counter + SUBMITION_INTERVAL, - 'time' => time(), - - - ]); call($regions, array_keys($keys)); $counter = time(); $keys = []; From 59c02ddf84055372aa3fa3c8ead25f330fc280f4 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 23 Oct 2022 18:10:49 +0300 Subject: [PATCH 14/87] addressing comments --- Dockerfile | 6 +- app/cli.php | 2 +- app/config/collections.php | 15 ++++- app/config/regions.php | 8 +-- app/config/services.php | 4 +- app/controllers/api/edge.php | 44 +++++++------ app/init.php | 59 ++++------------- app/realtime.php | 1 - app/tasks/{syncsCloud.php => sync-edge.php} | 70 +++++++++------------ app/workers/{syncsIn.php => sync-In.php} | 13 ++-- app/workers/{syncsOut.php => sync-out.php} | 58 +++++++++++------ bin/sync-edge | 3 + bin/syncs-cloud | 3 - bin/worker-sync-in | 3 + bin/worker-sync-out | 3 + bin/worker-syncs-in | 3 - bin/worker-syncs-out | 3 - docker-compose.yml | 21 +++---- 18 files changed, 152 insertions(+), 167 deletions(-) rename app/tasks/{syncsCloud.php => sync-edge.php} (55%) rename app/workers/{syncsIn.php => sync-In.php} (69%) rename app/workers/{syncsOut.php => sync-out.php} (76%) create mode 100644 bin/sync-edge delete mode 100644 bin/syncs-cloud create mode 100644 bin/worker-sync-in create mode 100644 bin/worker-sync-out delete mode 100644 bin/worker-syncs-in delete mode 100644 bin/worker-syncs-out diff --git a/Dockerfile b/Dockerfile index 1adc4d49e3..73593be925 100755 --- a/Dockerfile +++ b/Dockerfile @@ -332,7 +332,7 @@ RUN mkdir -p /storage/uploads && \ # Executables RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/maintenance && \ - chmod +x /usr/local/bin/syncs-cloud && \ + chmod +x /usr/local/bin/sync-edge && \ chmod +x /usr/local/bin/usage && \ chmod +x /usr/local/bin/install && \ chmod +x /usr/local/bin/migrate && \ @@ -353,8 +353,8 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/worker-mails && \ chmod +x /usr/local/bin/worker-messaging && \ chmod +x /usr/local/bin/worker-webhooks && \ - chmod +x /usr/local/bin/worker-syncs-out && \ - chmod +x /usr/local/bin/worker-syncs-in + chmod +x /usr/local/bin/worker-sync-out && \ + chmod +x /usr/local/bin/worker-sync-in diff --git a/app/cli.php b/app/cli.php index 6fc8e73d3a..ec3d5124f9 100644 --- a/app/cli.php +++ b/app/cli.php @@ -14,7 +14,7 @@ include 'tasks/doctor.php'; include 'tasks/maintenance.php'; -include 'tasks/syncsCloud.php'; +include 'tasks/sync-edge.php'; include 'tasks/install.php'; include 'tasks/migrate.php'; include 'tasks/sdks.php'; diff --git a/app/config/collections.php b/app/config/collections.php index d148e31b9d..e087b323ab 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -24,7 +24,7 @@ 'name' => 'Syncs', 'attributes' => [ [ - '$id' => ID::custom('regionOrg'), + '$id' => ID::custom('region'), 'type' => Database::VAR_STRING, 'size' => 50, 'required' => true, @@ -33,7 +33,7 @@ 'filters' => [], ], [ - '$id' => ID::custom('regionDest'), + '$id' => ID::custom('target'), 'type' => Database::VAR_STRING, 'size' => 50, 'required' => true, @@ -61,6 +61,17 @@ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('payload'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => true, + 'default' => [], + 'array' => false, + 'filters' => ['json'], + ], ], 'indexes' => [ [ diff --git a/app/config/regions.php b/app/config/regions.php index 75c7b6df56..dc4f3f92d4 100644 --- a/app/config/regions.php +++ b/app/config/regions.php @@ -2,19 +2,19 @@ return [ 'nyc1' => [ - 'name' => 'North america', + 'name' => 'New york', 'default' => true, 'disabled' => false, 'domain' => '172.17.0.1', ], - 'blr1' => [ - 'name' => 'Asia', + 'spg1' => [ + 'name' => 'Singapore', 'default' => true, 'disabled' => false, 'domain' => '172.17.0.1', ], 'fra1' => [ - 'name' => 'Europe', + 'name' => 'Frankfurt', 'default' => true, 'disabled' => false, 'domain' => '172.17.0.1', diff --git a/app/config/services.php b/app/config/services.php index 9f4a5791f7..88a387a213 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -187,8 +187,8 @@ 'icon' => '', ], 'syncs' => [ - 'key' => 'syncs', - 'name' => 'syncs', + 'key' => 'edge', + 'name' => 'edge', 'subtitle' => 'Appwrite\'s cloud regions syncs Endpoint', 'description' => 'Cloud edge Endpoint', 'controller' => 'api/edge.php', diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index c8c8c13719..3a02ec2c24 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -2,7 +2,6 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; -use Appwrite\Event\SyncIn; use Appwrite\Extend\Exception; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; @@ -11,10 +10,26 @@ use Utopia\Validator\ArrayList; use Utopia\Validator\Text; use Utopia\Queue\Client; -use Utopia\Queue\Connection\Redis; -App::post('/v1/edge') +App::init() + ->groups(['edge']) + ->inject('request') + ->action(function (Request $request) { + + $token = $request->getHeader('authorization'); + $token = str_replace(["Bearer"," "], "", $token); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + try { + $payload = $jwt->decode($token); + } catch (JWTException $error) { + throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); + } + }); + + +App::post('/v1/edge/sync') ->desc('Purge cache keys') + ->groups(['edge']) ->label('scope', 'public') ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') ->inject('request') @@ -26,29 +41,12 @@ throw new Exception(Exception::KEY_NOT_FOUND); } - $token = $request->getHeader('authorization'); - $token = str_replace(["Bearer"," "], "", $token); - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); - try { - $payload = $jwt->decode($token); - } catch (JWTException $error) { - throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); - } - $connection = $register - ->get('workerRedisConnection'); + ->get('queue'); $client = new Client('syncIn', $connection); - $client->resetStats(); - - foreach ($keys as $key) { - $client->enqueue([ - 'type' => 'from endpoint', - 'value' => [ - 'key' => $key - ] - ]); - } + + $client->enqueue(['value' => ['keys' => $keys]]); $response ->setStatusCode(Response::STATUS_CODE_OK) diff --git a/app/init.php b/app/init.php index 6cf3ef3953..9d5e2fb05e 100644 --- a/app/init.php +++ b/app/init.php @@ -207,7 +207,6 @@ Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php'); Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php'); - $user = App::getEnv('_APP_REDIS_USER', ''); $pass = App::getEnv('_APP_REDIS_PASS', ''); if (!empty($user) || !empty($pass)) { @@ -929,45 +928,29 @@ function (mixed $value) { ]); }, []); -$register->set('workerRedisConnection', function () { +$register->set('queue', function () { return new redisQueue('redis', 6379); }); -$register->set('workerSyncOut', function () use ($register) { - return new clientQueue('syncOut', $register->get('workerRedisConnection')); +$register->set('syncOut', function () use ($register) { + return new clientQueue('syncOut', $register->get('queue')); }); - App::setResource('dbForProject', function ($db, $cache, Document $project, $register) { $cache = new Cache(new RedisCache($cache)); $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { $register - ->get('workerSyncOut') - ->resetStats(); - $register - ->get('workerSyncOut') - ->enqueue([ - 'type' => 'saved from init', - 'value' => [ - 'key' => $key - ] - ]); + ->get('syncOut') + ->enqueue(['value' => ['key' => $key]]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { + $register - ->get('workerSyncOut') - ->resetStats(); - $register - ->get('workerSyncOut') - ->enqueue([ - 'type' => 'purge from init', - 'value' => [ - 'key' => $key - ] - ]); + ->get('syncOut') + ->enqueue(['value' => ['key' => $key]]); }); $database = new Database(new MariaDB($db), $cache); @@ -979,33 +962,17 @@ function (mixed $value) { App::setResource('dbForConsole', function ($db, $cache, $register) { $cache = new Cache(new RedisCache($cache)); - $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { + $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { $register - ->get('workerSyncOut') - ->resetStats(); - $register - ->get('workerSyncOut') - ->enqueue([ - 'type' => 'saved from init', - 'value' => [ - 'key' => $key - ] - ]); + ->get('syncOut') + ->enqueue(['value' => ['key' => $key]]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { $register - ->get('workerSyncOut') - ->resetStats(); - $register - ->get('workerSyncOut') - ->enqueue([ - 'type' => 'purge from init', - 'value' => [ - 'key' => $key - ] - ]); + ->get('syncOut') + ->enqueue(['value' => ['key' => $key]]); }); $database = new Database(new MariaDB($db), $cache); diff --git a/app/realtime.php b/app/realtime.php index 2263f3c396..cb733299cd 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -188,7 +188,6 @@ function () use ($register, $db, $redis) { Authorization::skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument)); } catch (\Throwable $th) { - call_user_func($logError, $th, "updateWorkerDocument"); } finally { call_user_func($returnDatabase); diff --git a/app/tasks/syncsCloud.php b/app/tasks/sync-edge.php similarity index 55% rename from app/tasks/syncsCloud.php rename to app/tasks/sync-edge.php index 3f1adef031..efce04f225 100644 --- a/app/tasks/syncsCloud.php +++ b/app/tasks/sync-edge.php @@ -44,54 +44,44 @@ function getConsoleDatabase(): Database return $database; } -function resendFailedRequest($dbForConsole, $regionOrg): void -{ - global $register; - - $time = DateTime::now(); - $chunks = $dbForConsole->find('syncs', [ - Query::equal('regionOrg', [$regionOrg]), - Query::limit(500) - ]); - - if (count($chunks) > 0) { - Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); - foreach ($chunks as $chunk) { - $register - ->get('workerSyncOut') - ->resetStats(); - - $register - ->get('workerSyncOut') - ->enqueue([ - 'type' => 'from cloud maintenance', - 'value' => [ - 'region' => $chunk->getAttribute('regionDest'), - 'chunk' => $chunk->getAttribute('keys') - ] - ]); - - $dbForConsole->deleteDocument('syncs', $chunk->getId()); - } - } else { - Console::info("[{$time}] No cache key chunks where found."); - } -} - $cli - ->task('syncsCloud') - ->desc('Schedules cloud sync tasks') + ->task('sync-edge') + ->desc('Schedules edge sync tasks') ->action(function () { - Console::title('Syncs cloud V1'); + Console::title('Syncs edges V1'); Console::success(APP_NAME . ' Syncs cloud process v1 has started'); - $interval = (int) App::getEnv('_APP_SYNCS_CLOUD_INTERVAL', '180'); + $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); Console::loop(function () use ($interval) { $database = getConsoleDatabase(); $time = DateTime::now(); - $currentRegion = App::getEnv('_APP_REGION', 'nyc1'); + $region = App::getEnv('_APP_REGION', 'nyc1'); Console::info("[{$time}] Notifying workers with cloud tasks every {$interval} seconds"); - resendFailedRequest($database, $currentRegion); + global $register; + + $time = DateTime::now(); + $chunks = $database->find('syncs', [ + Query::equal('region', [$region]), + Query::limit(500) + ]); + + if (count($chunks) > 0) { + Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); + foreach ($chunks as $chunk) { + $register + ->get('syncOut') + ->enqueue([ + 'value' => [ + 'region' => $chunk->getAttribute('regionDest'), + 'chunk' => $chunk->getAttribute('keys') + ] + ]); + + $database->deleteDocument('syncs', $chunk->getId()); + } + } else { + Console::info("[{$time}] No cache key chunks where found."); + } }, $interval); }); diff --git a/app/workers/syncsIn.php b/app/workers/sync-In.php similarity index 69% rename from app/workers/syncsIn.php rename to app/workers/sync-In.php index 40031ca20e..29eca3eb03 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/sync-In.php @@ -9,8 +9,6 @@ require_once __DIR__ . '/../init.php'; -define("CURRENT_REGION", App::getEnv('_APP_REGION', 'nyc1')); - /** * @return RedisCache */ @@ -26,12 +24,12 @@ function getCache(): RedisCache $server->job() ->inject('message') - ->action(function (Message $message) use (&$keys, &$counter) { + ->action(function (Message $message) { $payload = $message->getPayload()['value']; - if (!empty($payload['key'])) { - var_dump('purging ' . $payload['key']); - getCache()->purge($payload['key']); + foreach ($payload['keys'] ?? [] as $key) { + var_dump('purging ' . $key); + var_dump(getCache()->purge($key)); } }); @@ -40,10 +38,11 @@ function getCache(): RedisCache ->inject('error') ->action(function ($error) { echo $error->getMessage() . PHP_EOL; + echo $error->getLine() . PHP_EOL; }); $server ->workerStart(function () { - echo "In region [" . CURRENT_REGION . "] cache purging worker Started" . PHP_EOL; + echo "In region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; }) ->start(); diff --git a/app/workers/syncsOut.php b/app/workers/sync-out.php similarity index 76% rename from app/workers/syncsOut.php rename to app/workers/sync-out.php index 326862fa31..ea76098281 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/sync-out.php @@ -12,7 +12,6 @@ use Utopia\Database\Adapter\MariaDB; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Database\DateTime; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; use Utopia\Queue; @@ -29,8 +28,6 @@ const MAX_KEY_COUNT = 10; const MAX_CURL_SEND_ATTEMPTS = 4; -define("CURRENT_REGION", App::getEnv('_APP_REGION', 'nyc1')); - /** * Get console database * @param string $type One of (internal, external, console) @@ -92,7 +89,13 @@ function getDB(string $type, string $projectId = '', string $projectInternalId = return $database; } -function send($url, $token, $keys): int +/** + * @param string $url + * @param string $token + * @param array $keys + * @return array\ + */ +function send(string $url, string $token, array $keys): array { $ch = curl_init($url); @@ -106,17 +109,23 @@ function send($url, $token, $keys): int curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($keys)); for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { - curl_exec($ch); - $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - if ($responseStatus === 200) { - return $responseStatus; + $response = curl_exec($ch); + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $payload = [ + 'status' => $status, + 'payload' => json_decode($response, true) + ]; + + if ($status === 200) { + return $payload; } sleep(2); } + curl_close($ch); - return $responseStatus; + + return $payload; } /** @@ -131,13 +140,16 @@ function call($regions, $keys): void $token = $jwt->encode([]); foreach ($regions as $code => $region) { - $status = send($region['domain'] . '/v1/edge', $token, ['keys' => $keys]); - if ($status !== Response::STATUS_CODE_OK) { + var_dump('Sending request to ' . $code . '...............'); + $payload = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $keys]); + var_dump($payload); + if ($payload['status'] !== Response::STATUS_CODE_OK) { getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ - 'regionOrg' => CURRENT_REGION, - 'regionDest' => $code, + 'region' => App::getEnv('_APP_REGION', 'nyc1'), + 'target' => $code, 'keys' => $keys, - 'status' => $status, + 'status' => $payload['status'], + 'payload' => $payload['payload'], ])); } } @@ -155,7 +167,7 @@ function call($regions, $keys): void $regions = Config::getParam('regions', true); $regions = array_filter( $regions, - fn ($region) => CURRENT_REGION !== $region, + fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region, ARRAY_FILTER_USE_KEY ); @@ -167,14 +179,24 @@ function call($regions, $keys): void ); } - if (!empty($payload['chunk'])) { + var_dump('from chunk'); call($regions, $payload['chunk']); return; } $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { + var_dump('From key'); + var_dump([ + 'regions' => array_keys($regions), + 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), + 'because_count' => count($keys) >= MAX_KEY_COUNT, + 'count' => count($keys), + 'counter' => $counter + SUBMITION_INTERVAL, + 'time' => time(), + 'keys' => array_keys($keys), + ]); call($regions, array_keys($keys)); $counter = time(); $keys = []; @@ -191,6 +213,6 @@ function call($regions, $keys): void $server ->workerStart(function () { - echo "Out region [" . CURRENT_REGION . "] cache purging worker Started" . PHP_EOL; + echo "Out region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; }) ->start(); diff --git a/bin/sync-edge b/bin/sync-edge new file mode 100644 index 0000000000..5ff317eff5 --- /dev/null +++ b/bin/sync-edge @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php sync-edge $@ \ No newline at end of file diff --git a/bin/syncs-cloud b/bin/syncs-cloud deleted file mode 100644 index a321c87ed9..0000000000 --- a/bin/syncs-cloud +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php /usr/src/code/app/cli.php syncsCloud $@ \ No newline at end of file diff --git a/bin/worker-sync-in b/bin/worker-sync-in new file mode 100644 index 0000000000..0f38627454 --- /dev/null +++ b/bin/worker-sync-in @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/workers/sync-in.php $@ \ No newline at end of file diff --git a/bin/worker-sync-out b/bin/worker-sync-out new file mode 100644 index 0000000000..4c076fd25c --- /dev/null +++ b/bin/worker-sync-out @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/workers/sync-out.php $@ \ No newline at end of file diff --git a/bin/worker-syncs-in b/bin/worker-syncs-in deleted file mode 100644 index 6b973c44fe..0000000000 --- a/bin/worker-syncs-in +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php /usr/src/code/app/workers/syncsIn.php $@ \ No newline at end of file diff --git a/bin/worker-syncs-out b/bin/worker-syncs-out deleted file mode 100644 index 8117e84b34..0000000000 --- a/bin/worker-syncs-out +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php /usr/src/code/app/workers/syncsOut.php $@ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 9868cbfe3e..7a77fd5174 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -108,7 +108,6 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb - redis @@ -207,7 +206,6 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb - redis @@ -255,10 +253,10 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - appwrite-worker-syncs-out: - entrypoint: worker-syncs-out + appwrite-worker-sync-out: + entrypoint: worker-sync-out <<: *x-logging - container_name: appwrite-worker-syncs-out + container_name: appwrite-worker-sync-out image: appwrite-dev build: context: . @@ -282,10 +280,10 @@ services: - _APP_DB_USER - _APP_DB_PASS - appwrite-worker-syncs-in: - entrypoint: worker-syncs-in + appwrite-worker-sync-in: + entrypoint: worker-sync-in <<: *x-logging - container_name: appwrite-worker-syncs-in + container_name: appwrite-worker-sync-in image: appwrite-dev build: context: . @@ -617,10 +615,10 @@ services: - _APP_MAINTENANCE_RETENTION_ABUSE - _APP_MAINTENANCE_RETENTION_AUDIT - appwrite-syncs-cloud: - entrypoint: syncs-cloud + appwrite-sync-edge: + entrypoint: sync-edge <<: *x-logging - container_name: appwrite-syncs-cloud + container_name: appwrite-sync-edge image: appwrite-dev networks: - appwrite @@ -641,6 +639,7 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_SYNC_EDGE_INTERVAL appwrite-usage-timeseries: entrypoint: From 209cf6be1ee8c6d3553af837883c6a53078583e9 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 25 Oct 2022 12:33:10 +0300 Subject: [PATCH 15/87] addressing comments --- app/controllers/api/edge.php | 17 +++-- app/init.php | 44 ++++++------ app/tasks/sync-edge.php | 60 +++++----------- app/workers/sync-In.php | 54 ++++++++++----- app/workers/sync-out.php | 129 ++++++++++++++--------------------- composer.json | 4 +- composer.lock | 111 ++++++++++++++++++++++-------- docker-compose.yml | 16 +++-- 8 files changed, 236 insertions(+), 199 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 3a02ec2c24..7ee2091e49 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -6,10 +6,11 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\Queue\Client as SyncIn; +use Utopia\Queue\Connection\Redis as QueueRedis; use Utopia\Registry\Registry; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; -use Utopia\Queue\Client; App::init() ->groups(['edge']) @@ -26,7 +27,6 @@ } }); - App::post('/v1/edge/sync') ->desc('Purge cache keys') ->groups(['edge']) @@ -41,12 +41,17 @@ throw new Exception(Exception::KEY_NOT_FOUND); } - $connection = $register - ->get('queue'); + $pools = $register->get('pools'); + $queue = $pools + ->get('queue') + ->pop() + ->getResource() + ; - $client = new Client('syncIn', $connection); + $client = new SyncIn('syncIn', new QueueRedis(fn() => $queue)); - $client->enqueue(['value' => ['keys' => $keys]]); + $client-> + enqueue(['value' => ['keys' => $keys]]); $response ->setStatusCode(Response::STATUS_CODE_OK) diff --git a/app/init.php b/app/init.php index dedcbbfbee..d0ec741e86 100644 --- a/app/init.php +++ b/app/init.php @@ -38,8 +38,8 @@ use Appwrite\Network\Validator\URL; use Appwrite\OpenSSL\OpenSSL; use Appwrite\URL\URL as AppwriteURL; -use Utopia\Queue\Client as clientQueue; -use Utopia\Queue\Connection\Redis as redisQueue; +use Utopia\Queue\Client as SyncOut; +use Utopia\Queue\Connection\Redis as QueueRedis; use Appwrite\Usage\Stats; use Appwrite\Utopia\View; use Utopia\App; @@ -500,6 +500,7 @@ function (mixed $value) { $adapter = new $classname($providerConfig); return new Logger($adapter); }); + $register->set('pools', function () { $group = new Group(); @@ -638,12 +639,9 @@ function (mixed $value) { }; $adapter->setDefaultDatabase($dsn->getDatabase()); - - break; - case 'queue': - $adapter = $resource(); break; case 'pubsub': + case 'queue': $adapter = $resource(); break; case 'cache': @@ -675,6 +673,7 @@ function (mixed $value) { return $group; }); + $register->set('influxdb', function () { // Register DB connection $host = App::getEnv('_APP_INFLUXDB_HOST', ''); @@ -1026,13 +1025,12 @@ function (mixed $value) { ]); }, []); -$register->set('queue', function () { - return new redisQueue('redis', 6379); -}); - -$register->set('syncOut', function () use ($register) { - return new clientQueue('syncOut', $register->get('queue')); -}); +App::setResource('queue', function (Group $pools) { + return $pools + ->get('queue') + ->pop() + ->getResource(); +}, ['pools']); App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, Cache $cache, Document $project) { if ($project->isEmpty() || $project->getId() === 'console') { @@ -1059,13 +1057,12 @@ function (mixed $value) { ; $database = new Database($dbAdapter, $cache); - $database->setNamespace('console'); return $database; }, ['pools', 'cache']); -App::setResource('cache', function (Group $pools) { +App::setResource('cache', function (Group $pools, $queue) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -1076,21 +1073,22 @@ function (mixed $value) { ->getResource() ; } - $cache = new Cache(new Sharding($adapters)); - $cache->on(cache::EVENT_SAVE, function ($key) use ($register) { - $register - ->get('syncOut') + $cache = new Cache(new Sharding($adapters)); + + $client = new SyncOut('syncOut', new QueueRedis(fn() => $queue)); + + $cache->on(cache::EVENT_SAVE, function ($key) use ($client) { + $client ->enqueue(['value' => ['key' => $key]]); }); - $cache->on(cache::EVENT_PURGE, function ($key) use ($register) { - $register - ->get('syncOut') + $cache->on(cache::EVENT_PURGE, function ($key) use ($client) { + $client ->enqueue(['value' => ['key' => $key]]); }); return $cache; -}, ['pools']); +}, ['pools', 'queue']); App::setResource('deviceLocal', function () { return new Local(); diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index efce04f225..c158895747 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -4,61 +4,25 @@ global $register; use Utopia\App; -use Utopia\Cache\Cache; use Utopia\CLI\Console; -use Utopia\Database\Adapter\MariaDB; -use Utopia\Database\Database; use Utopia\Database\DateTime; -use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Database\Query; - - -function getConsoleDatabase(): Database -{ - global $register; - - $attempts = 0; - - do { - try { - $attempts++; - $cache = new Cache(new RedisCache($register->get('cache'))); - $database = new Database(new MariaDB($register->get('db')), $cache); - $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); - $database->setNamespace('_console'); // Main DB - - if (!$database->exists($database->getDefaultDatabase(), 'certificates')) { - throw new \Exception('Console project not ready'); - } - - break; // leave loop if successful - } catch (\Exception $e) { - Console::warning("Database not ready. Retrying connection ({$attempts})..."); - if ($attempts >= DATABASE_RECONNECT_MAX_ATTEMPTS) { - throw new \Exception('Failed to connect to database: ' . $e->getMessage()); - } - sleep(DATABASE_RECONNECT_SLEEP); - } - } while ($attempts < DATABASE_RECONNECT_MAX_ATTEMPTS); - - return $database; -} +use Utopia\Queue\Client as SyncIn; +use Utopia\Queue\Connection\Redis as QueueRedis; $cli ->task('sync-edge') ->desc('Schedules edge sync tasks') - ->action(function () { + ->action(function () use ($register) { Console::title('Syncs edges V1'); Console::success(APP_NAME . ' Syncs cloud process v1 has started'); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - - Console::loop(function () use ($interval) { - $database = getConsoleDatabase(); + Console::loop(function () use ($interval, $register) { + $database = getConsoleDB(); $time = DateTime::now(); $region = App::getEnv('_APP_REGION', 'nyc1'); Console::info("[{$time}] Notifying workers with cloud tasks every {$interval} seconds"); - global $register; $time = DateTime::now(); $chunks = $database->find('syncs', [ @@ -68,9 +32,17 @@ function getConsoleDatabase(): Database if (count($chunks) > 0) { Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); + + $pools = $register->get('pools'); + $queue = $pools + ->get('queue') + ->pop() + ->getResource() + ; + + $client = new SyncIn('syncIn', new QueueRedis(fn() => $queue)); foreach ($chunks as $chunk) { - $register - ->get('syncOut') + $client ->enqueue([ 'value' => [ 'region' => $chunk->getAttribute('regionDest'), @@ -83,5 +55,5 @@ function getConsoleDatabase(): Database } else { Console::info("[{$time}] No cache key chunks where found."); } - }, $interval); + }, $interval); }); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 29eca3eb03..03f52ad827 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -1,35 +1,55 @@ get('pools'); +$queue = $pools + ->get('queue') + ->pop() + ->getResource() +; + +$connection = new Queue\Connection\Redis(fn() => $queue); +$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncIn'); +$server = new Queue\Server($adapter); + +Server::setResource('cache', function () use ($register) { + + $pools = $register->get('pools'); + $list = Config::getParam('pools-cache', []); + $adapters = []; -/** - * @return RedisCache - */ -function getCache(): RedisCache -{ - global $register; - return new RedisCache($register->get('cache')); -} + foreach ($list as $value) { + $adapters[] = $pools + ->get($value) + ->pop() + ->getResource() + ; + } -$connection = new Queue\Connection\Redis('redis'); -$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncIn'); -$server = new Queue\Server($adapter); + return new Cache(new Sharding($adapters)); +}); $server->job() ->inject('message') - ->action(function (Message $message) { + ->inject('cache') + ->action(function (Message $message, Cache $cache) { $payload = $message->getPayload()['value']; foreach ($payload['keys'] ?? [] as $key) { - var_dump('purging ' . $key); - var_dump(getCache()->purge($key)); + var_dump('purging -> ' . $key); + var_dump($cache->purge($key)); } }); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index ea76098281..cc71ee7fb6 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -1,103 +1,39 @@ get('cache'))); - $database = new Database(new MariaDB($register->get('db')), $cache); - $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); - $database->setNamespace($namespace); // Main DB - - if (!empty($projectId) && !$database->getDocument('projects', $projectId)->isEmpty()) { - throw new \Exception("Project does not exist: {$projectId}"); - } - - if ($type === DATABASE_CONSOLE && !$database->exists($database->getDefaultDatabase(), Database::METADATA)) { - throw new \Exception('Console project not ready'); - } - - break; // leave loop if successful - } catch (\Exception $e) { - Console::warning("Database not ready. Retrying connection ({$attempts})..."); - if ($attempts >= DATABASE_RECONNECT_MAX_ATTEMPTS) { - throw new \Exception('Failed to connect to database: ' . $e->getMessage()); - } - sleep($sleep); - } - } while ($attempts < DATABASE_RECONNECT_MAX_ATTEMPTS); - - return $database; -} /** * @param string $url * @param string $token * @param array $keys - * @return array\ + * @return array */ function send(string $url, string $token, array $keys): array { - + $payload = []; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, @@ -133,7 +69,7 @@ function send(string $url, string $token, array $keys): array * @throws Structure * @throws Exception */ -function call($regions, $keys): void +function call($database, $regions, $keys): void { $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); @@ -144,7 +80,7 @@ function call($regions, $keys): void $payload = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $keys]); var_dump($payload); if ($payload['status'] !== Response::STATUS_CODE_OK) { - getDB(DATABASE_CONSOLE)->createDocument('syncs', new Document([ + $database->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION', 'nyc1'), 'target' => $code, 'keys' => $keys, @@ -155,13 +91,55 @@ function call($regions, $keys): void } } -$connection = new Queue\Connection\Redis('redis'); +global $register; + +$pools = $register->get('pools'); +$queue = $pools + ->get('queue') + ->pop() + ->getResource() +; + +$connection = new Queue\Connection\Redis(fn() => $queue); $adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); $server = new Queue\Server($adapter); +Server::setResource('dbForConsole', function (Cache $cache) use ($register) { + + $pools = $register->get('pools'); + $dbAdapter = $pools + ->get('console') + ->pop() + ->getResource() + ; + + $database = new Database($dbAdapter, $cache); + $database->setNamespace('console'); + + return $database; +}, ['cache']); + +Server::setResource('cache', function () use ($register) { + + $pools = $register->get('pools'); + $list = Config::getParam('pools-cache', []); + $adapters = []; + + foreach ($list as $value) { + $adapters[] = $pools + ->get($value) + ->pop() + ->getResource() + ; + } + + return new Cache(new Sharding($adapters)); +}); + $server->job() ->inject('message') - ->action(function (Message $message) use (&$keys, &$counter) { + ->inject('dbForConsole') + ->action(function (Message $message, Database $dbForConsole) use (&$keys, &$counter) { $payload = $message->getPayload()['value']; $regions = Config::getParam('regions', true); @@ -180,8 +158,7 @@ function call($regions, $keys): void } if (!empty($payload['chunk'])) { - var_dump('from chunk'); - call($regions, $payload['chunk']); + call($dbForConsole, $regions, $payload['chunk']); return; } @@ -197,7 +174,7 @@ function call($regions, $keys): void 'time' => time(), 'keys' => array_keys($keys), ]); - call($regions, array_keys($keys)); + call($dbForConsole, $regions, array_keys($keys)); $counter = time(); $keys = []; } diff --git a/composer.json b/composer.json index 2f1db06bbb..7ca5939359 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "utopia-php/abuse": "0.14.*", "utopia-php/analytics": "0.2.*", "utopia-php/audit": "0.15.*", - "utopia-php/cache": "dev-feat-redis-sync as 0.6.1", + "utopia-php/cache": "dev-feat-redis-sync as 0.8.1", "utopia-php/cli": "0.13.*", "utopia-php/config": "0.2.*", "utopia-php/database": "dev-feat-update-cache-lib as 0.26.1", @@ -61,7 +61,7 @@ "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.6.*", - "utopia-php/queue": "0.3.*", + "utopia-php/queue": "dev-refactor-redis-client as 0.3.0", "utopia-php/pools": "0.1.*", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", diff --git a/composer.lock b/composer.lock index 6f7efe70a3..7ef8f25135 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "73ea3ea466d02c3c6427d235c11554ff", + "content-hash": "0b5f0fd08db65ca4c2e2f1a6d33cd299", "packages": [ { "name": "adhocore/jwt", @@ -2050,16 +2050,16 @@ }, { "name": "utopia-php/database", - "version": "0.26.0", + "version": "dev-feat-update-cache-lib", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "d172af2541137c83a86d066f82f48914b5a3a610" + "reference": "44ae47dfd49c9c7c0cba29f6867347e25c23b57b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/d172af2541137c83a86d066f82f48914b5a3a610", - "reference": "d172af2541137c83a86d066f82f48914b5a3a610", + "url": "https://api.github.com/repos/utopia-php/database/zipball/44ae47dfd49c9c7c0cba29f6867347e25c23b57b", + "reference": "44ae47dfd49c9c7c0cba29f6867347e25c23b57b", "shasum": "" }, "require": { @@ -2068,7 +2068,7 @@ "ext-redis": "*", "mongodb/mongodb": "1.8.0", "php": ">=8.0", - "utopia-php/cache": "0.6.*", + "utopia-php/cache": "0.8.*", "utopia-php/framework": "0.*.*" }, "require-dev": { @@ -2088,16 +2088,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Brandon Leckemby", - "email": "brandon@appwrite.io" - } - ], "description": "A simple library to manage application persistency using multiple database adapters", "keywords": [ "database", @@ -2108,9 +2098,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.26.0" + "source": "https://github.com/utopia-php/database/tree/feat-update-cache-lib" }, - "time": "2022-10-03T17:12:01+00:00" + "time": "2022-10-16T17:35:26+00:00" }, { "name": "utopia-php/domains", @@ -2439,6 +2429,59 @@ }, "time": "2022-07-13T16:47:18+00:00" }, + { + "name": "utopia-php/pools", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/pools.git", + "reference": "5a467a569a80aefc846a97dc195b4adc2fd71805" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/5a467a569a80aefc846a97dc195b4adc2fd71805", + "reference": "5a467a569a80aefc846a97dc195b4adc2fd71805", + "shasum": "" + }, + "require": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Pools\\": "src/Pools" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Team Appwrite", + "email": "team@appwrite.io" + } + ], + "description": "A simple library to manage connection pools", + "keywords": [ + "framework", + "php", + "pools", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/pools/issues", + "source": "https://github.com/utopia-php/pools/tree/0.1.0" + }, + "time": "2022-10-11T19:31:07+00:00" + }, { "name": "utopia-php/preloader", "version": "0.2.4", @@ -2494,16 +2537,16 @@ }, { "name": "utopia-php/queue", - "version": "0.3.0", + "version": "dev-refactor-redis-client", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "42b132c6f2431b726c2bc629c386921e4934b863" + "reference": "3e49bcbfc343792ea4899d60b24e7b6b334e5910" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/42b132c6f2431b726c2bc629c386921e4934b863", - "reference": "42b132c6f2431b726c2bc629c386921e4934b863", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/3e49bcbfc343792ea4899d60b24e7b6b334e5910", + "reference": "3e49bcbfc343792ea4899d60b24e7b6b334e5910", "shasum": "" }, "require": { @@ -2549,9 +2592,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.3.0" + "source": "https://github.com/utopia-php/queue/tree/refactor-redis-client" }, - "time": "2022-10-19T13:22:07+00:00" + "time": "2022-10-24T14:29:47+00:00" }, { "name": "utopia-php/registry", @@ -5418,13 +5461,27 @@ { "package": "utopia-php/cache", "version": "dev-feat-redis-sync", - "alias": "0.6.1", - "alias_normalized": "0.6.1.0" + "alias": "0.8.1", + "alias_normalized": "0.8.1.0" + }, + { + "package": "utopia-php/database", + "version": "dev-feat-update-cache-lib", + "alias": "0.26.1", + "alias_normalized": "0.26.1.0" + }, + { + "package": "utopia-php/queue", + "version": "dev-refactor-redis-client", + "alias": "0.3.0", + "alias_normalized": "0.3.0.0" } ], "minimum-stability": "stable", "stability-flags": { - "utopia-php/cache": 20 + "utopia-php/cache": 20, + "utopia-php/database": 20, + "utopia-php/queue": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/docker-compose.yml b/docker-compose.yml index 1e24b0bf11..a441d056b5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -273,8 +273,6 @@ services: <<: *x-logging container_name: appwrite-worker-sync-out image: appwrite-dev - build: - context: . networks: - appwrite volumes: @@ -294,14 +292,16 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE appwrite-worker-sync-in: entrypoint: worker-sync-in <<: *x-logging container_name: appwrite-worker-sync-in image: appwrite-dev - build: - context: . networks: - appwrite volumes: @@ -315,6 +315,10 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -681,6 +685,10 @@ services: - _APP_DB_USER - _APP_DB_PASS - _APP_SYNC_EDGE_INTERVAL + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE appwrite-usage-timeseries: entrypoint: From b0fe5f3e90cd29e3a2e2a11883b0f5209a0b9582 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 26 Oct 2022 09:54:15 +0300 Subject: [PATCH 16/87] addressing comments --- app/config/regions.php | 12 +++- app/config/services.php | 4 +- app/controllers/api/edge.php | 12 ++-- app/worker.php | 47 ++++++++++++++ app/workers/sync-In.php | 22 +------ app/workers/sync-out.php | 65 +++++-------------- docker-compose.yml | 1 + src/Appwrite/Utopia/Response.php | 3 + .../Utopia/Response/Model/EdgeSync.php | 43 ++++++++++++ 9 files changed, 128 insertions(+), 81 deletions(-) create mode 100644 app/worker.php create mode 100644 src/Appwrite/Utopia/Response/Model/EdgeSync.php diff --git a/app/config/regions.php b/app/config/regions.php index dc4f3f92d4..d405b6f778 100644 --- a/app/config/regions.php +++ b/app/config/regions.php @@ -1,21 +1,27 @@ [ + 'name' => 'default', + 'default' => true, + 'disabled' => false, + 'domain' => '', + ], 'nyc1' => [ 'name' => 'New york', - 'default' => true, + 'default' => false, 'disabled' => false, 'domain' => '172.17.0.1', ], 'spg1' => [ 'name' => 'Singapore', - 'default' => true, + 'default' => false, 'disabled' => false, 'domain' => '172.17.0.1', ], 'fra1' => [ 'name' => 'Frankfurt', - 'default' => true, + 'default' => false, 'disabled' => false, 'domain' => '172.17.0.1', ], diff --git a/app/config/services.php b/app/config/services.php index 88a387a213..3783696db8 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -189,8 +189,8 @@ 'syncs' => [ 'key' => 'edge', 'name' => 'edge', - 'subtitle' => 'Appwrite\'s cloud regions syncs Endpoint', - 'description' => 'Cloud edge Endpoint', + 'subtitle' => 'Appwrite\'s cache edges sync Endpoint', + 'description' => 'Cache edges sync Endpoint', 'controller' => 'api/edge.php', 'sdk' => false, 'docs' => false, diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 7ee2091e49..5edf899589 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -6,6 +6,7 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\Database\Document; use Utopia\Queue\Client as SyncIn; use Utopia\Queue\Connection\Redis as QueueRedis; use Utopia\Registry\Registry; @@ -31,7 +32,7 @@ ->desc('Purge cache keys') ->groups(['edge']) ->label('scope', 'public') - ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') + ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') ->inject('register') @@ -50,10 +51,9 @@ $client = new SyncIn('syncIn', new QueueRedis(fn() => $queue)); - $client-> - enqueue(['value' => ['keys' => $keys]]); + $client->enqueue(['value' => ['keys' => $keys]]); - $response - ->setStatusCode(Response::STATUS_CODE_OK) - ->send(); + $response->dynamic(new Document([ + 'keys' => $keys + ]), Response::MODEL_EDGE_SYNC); }); diff --git a/app/worker.php b/app/worker.php new file mode 100644 index 0000000000..897c49c029 --- /dev/null +++ b/app/worker.php @@ -0,0 +1,47 @@ + $register); + +Server::setResource('dbForConsole', function (Cache $cache, Registry $register) { + + $pools = $register->get('pools'); + $dbAdapter = $pools + ->get('console') + ->pop() + ->getResource() + ; + + $database = new Database($dbAdapter, $cache); + $database->setNamespace('console'); + + return $database; +}, ['cache', 'register']); + +Server::setResource('cache', function (Registry $register) { + + $pools = $register->get('pools'); + $list = Config::getParam('pools-cache', []); + $adapters = []; + + foreach ($list as $value) { + $adapters[] = $pools + ->get($value) + ->pop() + ->getResource() + ; + } + + return new Cache(new Sharding($adapters)); +}, ['register']); + diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 03f52ad827..5ce9518583 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -1,15 +1,12 @@ get('pools'); - $list = Config::getParam('pools-cache', []); - $adapters = []; - - foreach ($list as $value) { - $adapters[] = $pools - ->get($value) - ->pop() - ->getResource() - ; - } - - return new Cache(new Sharding($adapters)); -}); - $server->job() ->inject('message') ->inject('cache') diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index cc71ee7fb6..bff16cd17d 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -1,12 +1,10 @@ $region) { var_dump('Sending request to ' . $code . '...............'); - $payload = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $keys]); - var_dump($payload); - if ($payload['status'] !== Response::STATUS_CODE_OK) { + $response = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $keys]); + var_dump([ + 'keys' => $keys, + 'response' => $response + ]); + if ($response['status'] !== Response::STATUS_CODE_OK) { $database->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION', 'nyc1'), 'target' => $code, 'keys' => $keys, - 'status' => $payload['status'], - 'payload' => $payload['payload'], + 'status' => $response['status'], + 'payload' => $response['payload'], ])); } } } -global $register; - $pools = $register->get('pools'); $queue = $pools ->get('queue') @@ -101,41 +99,9 @@ function call($database, $regions, $keys): void ; $connection = new Queue\Connection\Redis(fn() => $queue); -$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); +$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncOut'); $server = new Queue\Server($adapter); -Server::setResource('dbForConsole', function (Cache $cache) use ($register) { - - $pools = $register->get('pools'); - $dbAdapter = $pools - ->get('console') - ->pop() - ->getResource() - ; - - $database = new Database($dbAdapter, $cache); - $database->setNamespace('console'); - - return $database; -}, ['cache']); - -Server::setResource('cache', function () use ($register) { - - $pools = $register->get('pools'); - $list = Config::getParam('pools-cache', []); - $adapters = []; - - foreach ($list as $value) { - $adapters[] = $pools - ->get($value) - ->pop() - ->getResource() - ; - } - - return new Cache(new Sharding($adapters)); -}); - $server->job() ->inject('message') ->inject('dbForConsole') @@ -145,7 +111,8 @@ function call($database, $regions, $keys): void $regions = Config::getParam('regions', true); $regions = array_filter( $regions, - fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region, + fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region + && $region !== 'default', ARRAY_FILTER_USE_KEY ); @@ -164,9 +131,9 @@ function call($database, $regions, $keys): void $keys[$payload['key']] = null; if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { - var_dump('From key'); var_dump([ 'regions' => array_keys($regions), + 'time_h' => date('m/d/Y H:i:s', $counter), 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), 'because_count' => count($keys) >= MAX_KEY_COUNT, 'count' => count($keys), diff --git a/docker-compose.yml b/docker-compose.yml index a441d056b5..9757f9dd42 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -278,6 +278,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/queue:/usr/src/code/vendor/utopia-php/queue depends_on: - mariadb - redis diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 07134c6ea9..4808218ddd 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -81,6 +81,7 @@ use Appwrite\Utopia\Response\Model\UsageStorage; use Appwrite\Utopia\Response\Model\UsageUsers; use Appwrite\Utopia\Response\Model\Variable; +use Appwrite\Utopia\Response\Model\EdgeSync; /** * @method Response setStatusCode(int $code = 200) @@ -200,6 +201,7 @@ class Response extends SwooleResponse public const MODEL_DOMAIN_LIST = 'domainList'; public const MODEL_VARIABLE = 'variable'; public const MODEL_VARIABLE_LIST = 'variableList'; + public const MODEL_EDGE_SYNC = 'edgeSync'; // Health public const MODEL_HEALTH_STATUS = 'healthStatus'; @@ -336,6 +338,7 @@ public function __construct(SwooleHTTPResponse $response) ->setModel(new UsageFunctions()) ->setModel(new UsageFunction()) ->setModel(new UsageProject()) + ->setModel(new EdgeSync()) // Verification // Recovery // Tests (keep last) diff --git a/src/Appwrite/Utopia/Response/Model/EdgeSync.php b/src/Appwrite/Utopia/Response/Model/EdgeSync.php new file mode 100644 index 0000000000..dde34d3bfc --- /dev/null +++ b/src/Appwrite/Utopia/Response/Model/EdgeSync.php @@ -0,0 +1,43 @@ +addRule('keys', [ + 'type' => self::TYPE_STRING, + 'description' => 'Cache keys array to be purged.', + 'default' => '', + 'example' => '["cache-console:_metadata:users", "cache-console:_metadata:buckets"]', + ]) + + ; + } + + /** + * Get Name + * + * @return string + */ + public function getName(): string + { + return 'EdgeSync'; + } + + /** + * Get Type + * + * @return string + */ + public function getType(): string + { + return Response::MODEL_EDGE_SYNC; + } +} From b7d7f43aefe05b35428bf63cb4a3cbde7b8dee06 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 26 Oct 2022 15:10:24 +0300 Subject: [PATCH 17/87] addressing comments --- app/config/services.php | 4 ++-- app/workers/sync-out.php | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/app/config/services.php b/app/config/services.php index 3783696db8..ac6fa5b9d6 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -189,8 +189,8 @@ 'syncs' => [ 'key' => 'edge', 'name' => 'edge', - 'subtitle' => 'Appwrite\'s cache edges sync Endpoint', - 'description' => 'Cache edges sync Endpoint', + 'subtitle' => 'Appwrite\'s cache edge sync Endpoint', + 'description' => 'Cache edge sync Endpoint', 'controller' => 'api/edge.php', 'sdk' => false, 'docs' => false, diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index bff16cd17d..b6d34096d2 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -4,6 +4,8 @@ use Ahc\Jwt\JWT; use Appwrite\Utopia\Response; +use Swoole\Runtime; +use Swoole\Timer; use Utopia\App; use Utopia\Config\Config; use Utopia\Database\Database; @@ -102,6 +104,8 @@ function call($database, $regions, $keys): void $adapter = new Queue\Adapter\Swoole($connection, 2, 'syncOut'); $server = new Queue\Server($adapter); + + $server->job() ->inject('message') ->inject('dbForConsole') @@ -130,23 +134,16 @@ function call($database, $regions, $keys): void } $keys[$payload['key']] = null; - if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { - var_dump([ - 'regions' => array_keys($regions), - 'time_h' => date('m/d/Y H:i:s', $counter), - 'because_time' => ($counter + SUBMITION_INTERVAL) < time(), - 'because_count' => count($keys) >= MAX_KEY_COUNT, - 'count' => count($keys), - 'counter' => $counter + SUBMITION_INTERVAL, - 'time' => time(), - 'keys' => array_keys($keys), - ]); - call($dbForConsole, $regions, array_keys($keys)); - $counter = time(); - $keys = []; - } + +// if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { +// call($dbForConsole, $regions, array_keys($keys)); +// $counter = time(); +// $keys = []; +// } }); +Runtime::enableCoroutine(SWOOLE_HOOK_ALL); + $server ->error() ->inject('error') @@ -157,6 +154,10 @@ function call($database, $regions, $keys): void $server ->workerStart(function () { + Timer::tick(1000, function () { + var_dump(date('m/d/Y H:i:s', time())); + }); echo "Out region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; }) ->start(); + From d7d98d9866d5ff707d891cdff9182c07d321dc5f Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 27 Oct 2022 12:51:53 +0300 Subject: [PATCH 18/87] Timer::tick --- app/controllers/api/edge.php | 16 ++--- app/init.php | 35 ++++++----- app/tasks/sync-edge.php | 24 +++---- app/worker.php | 46 ++++++++++++++ app/workers/sync-In.php | 11 +--- app/workers/sync-out.php | 118 ++++++++++++++++++----------------- composer.json | 2 +- composer.lock | 43 ++++++------- 8 files changed, 158 insertions(+), 137 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 5edf899589..bd80b91843 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -35,21 +35,13 @@ ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') - ->inject('register') - ->action(function (array $keys, Request $request, Response $response, Registry $register) { + ->action(function (array $keys, Request $request, Response $response) { - if (empty($keys)) { + //if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - } - - $pools = $register->get('pools'); - $queue = $pools - ->get('queue') - ->pop() - ->getResource() - ; + //} - $client = new SyncIn('syncIn', new QueueRedis(fn() => $queue)); + $client = new SyncIn('syncIn', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); $client->enqueue(['value' => ['keys' => $keys]]); diff --git a/app/init.php b/app/init.php index d0ec741e86..94a60e581e 100644 --- a/app/init.php +++ b/app/init.php @@ -533,12 +533,12 @@ function (mixed $value) { 'multiple' => true, 'schemes' => ['mariadb', 'mysql'], ], - 'queue' => [ - 'type' => 'queue', - 'dsns' => App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), - 'multiple' => false, - 'schemes' => ['redis'], - ], +// 'queue' => [ +// 'type' => 'queue', +// 'dsns' => App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), +// 'multiple' => false, +// 'schemes' => ['redis'], +// ], 'pubsub' => [ 'type' => 'pubsub', 'dsns' => App::getEnv('_APP_CONNECTIONS_PUBSUB', $fallbackForRedis), @@ -641,9 +641,11 @@ function (mixed $value) { $adapter->setDefaultDatabase($dsn->getDatabase()); break; case 'pubsub': - case 'queue': - $adapter = $resource(); break; + $adapter = $resource(); +// case 'queue': +// $adapter = $resource(); +// break; case 'cache': $adapter = match ($dsn->getScheme()) { 'redis' => new RedisCache($resource()), @@ -1025,12 +1027,11 @@ function (mixed $value) { ]); }, []); -App::setResource('queue', function (Group $pools) { - return $pools - ->get('queue') - ->pop() - ->getResource(); -}, ['pools']); +//App::setResource('queue', function (Group $pools) { +// $pools->get('queue') +// ->pop() +// ->getResource(); +//}, ['pools']); App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, Cache $cache, Document $project) { if ($project->isEmpty() || $project->getId() === 'console') { @@ -1062,7 +1063,7 @@ function (mixed $value) { return $database; }, ['pools', 'cache']); -App::setResource('cache', function (Group $pools, $queue) { +App::setResource('cache', function (Group $pools) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -1075,7 +1076,7 @@ function (mixed $value) { } $cache = new Cache(new Sharding($adapters)); - $client = new SyncOut('syncOut', new QueueRedis(fn() => $queue)); + $client = new SyncOut('syncOut', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); $cache->on(cache::EVENT_SAVE, function ($key) use ($client) { $client @@ -1088,7 +1089,7 @@ function (mixed $value) { }); return $cache; -}, ['pools', 'queue']); +}, ['pools']); App::setResource('deviceLocal', function () { return new Local(); diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index c158895747..b9530b2d84 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -7,7 +7,7 @@ use Utopia\CLI\Console; use Utopia\Database\DateTime; use Utopia\Database\Query; -use Utopia\Queue\Client as SyncIn; +use Utopia\Queue\Client as SyncOut; use Utopia\Queue\Connection\Redis as QueueRedis; $cli @@ -15,14 +15,14 @@ ->desc('Schedules edge sync tasks') ->action(function () use ($register) { Console::title('Syncs edges V1'); - Console::success(APP_NAME . ' Syncs cloud process v1 has started'); + Console::success(APP_NAME . ' Syncs Edge process v1 has started'); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); Console::loop(function () use ($interval, $register) { $database = getConsoleDB(); $time = DateTime::now(); $region = App::getEnv('_APP_REGION', 'nyc1'); - Console::info("[{$time}] Notifying workers with cloud tasks every {$interval} seconds"); + Console::info("[{$time}] Notifying workers with edges tasks every {$interval} seconds"); $time = DateTime::now(); $chunks = $database->find('syncs', [ @@ -31,22 +31,14 @@ ]); if (count($chunks) > 0) { - Console::info("[{$time}] Found " . \count($chunks) . " cache key chunks to purge."); - - $pools = $register->get('pools'); - $queue = $pools - ->get('queue') - ->pop() - ->getResource() - ; - - $client = new SyncIn('syncIn', new QueueRedis(fn() => $queue)); - foreach ($chunks as $chunk) { + $client = new SyncOut('syncOut', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); + foreach ($chunks as $counter => $chunk) { + Console::info("[{$time}] Sending chunk .($counter+1). ot of " . count($chunks) . " to {$chunk->getAttribute('target')}"); $client ->enqueue([ 'value' => [ - 'region' => $chunk->getAttribute('regionDest'), - 'chunk' => $chunk->getAttribute('keys') + 'region' => $chunk->getAttribute('target'), + 'keys' => $chunk->getAttribute('keys') ] ]); diff --git a/app/worker.php b/app/worker.php index 897c49c029..eef1248f36 100644 --- a/app/worker.php +++ b/app/worker.php @@ -45,3 +45,49 @@ return new Cache(new Sharding($adapters)); }, ['register']); +/** + * Get console database + * @return Database + */ +function getConsoleDB(): Database +{ + global $register; + + $pools = $register->get('pools'); /** @var \Utopia\Pools\Group $pools */ + + $dbAdapter = $pools + ->get('console') + ->pop() + ->getResource() + ; + + $database = new Database($dbAdapter, getCache()); + + $database->setNamespace('console'); + + return $database; +} + +/** + * Get Cache + * @return Cache + */ +function getCache(): Cache +{ + global $register; + + $pools = $register->get('pools'); /** @var \Utopia\Pools\Group $pools */ + + $list = Config::getParam('pools-cache', []); + $adapters = []; + + foreach ($list as $value) { + $adapters[] = $pools + ->get($value) + ->pop() + ->getResource() + ; + } + + return new Cache(new Sharding($adapters)); +} diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 5ce9518583..0482f92b08 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -10,15 +10,8 @@ global $register; -$pools = $register->get('pools'); -$queue = $pools - ->get('queue') - ->pop() - ->getResource() -; - -$connection = new Queue\Connection\Redis(fn() => $queue); -$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncIn'); +$connection = new Queue\Connection\Redis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379')); +$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncIn'); $server = new Queue\Server($adapter); $server->job() diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index b6d34096d2..b8dc9d8e2e 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -7,30 +7,39 @@ use Swoole\Runtime; use Swoole\Timer; use Utopia\App; +use Utopia\CLI\Console; use Utopia\Config\Config; -use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; use Utopia\Queue; use Utopia\Queue\Message; -global $register; -$keys = []; -$counter = 0; +$regions = array_filter( + Config::getParam('regions', []), + fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region + && $region !== 'default', + ARRAY_FILTER_USE_KEY +); -const SUBMITION_INTERVAL = 20; -const MAX_KEY_COUNT = 10; +$stack = [ + 'regions' => $regions, + 'keys' => [], +]; + +$failures = []; + +const MAX_KEY_COUNT = 2; const MAX_CURL_SEND_ATTEMPTS = 4; /** * @param string $url * @param string $token - * @param array $keys + * @param array $stack * @return array */ -function send(string $url, string $token, array $keys): array +function send(string $url, string $token, array $stack): array { $payload = []; $ch = curl_init($url); @@ -41,7 +50,7 @@ function send(string $url, string $token, array $keys): array curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($keys)); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($stack)); for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { $response = curl_exec($ch); @@ -68,24 +77,20 @@ function send(string $url, string $token, array $keys): array * @throws Structure * @throws Exception */ -function call($database, $regions, $keys): void +function call($database, $regions, $stack): void { $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode([]); foreach ($regions as $code => $region) { - var_dump('Sending request to ' . $code . '...............'); - $response = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $keys]); - var_dump([ - 'keys' => $keys, - 'response' => $response - ]); + Console::info("Sending request to {$code}"); + $response = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); if ($response['status'] !== Response::STATUS_CODE_OK) { $database->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION', 'nyc1'), 'target' => $code, - 'keys' => $keys, + 'keys' => $stack, 'status' => $response['status'], 'payload' => $response['payload'], ])); @@ -93,53 +98,35 @@ function call($database, $regions, $keys): void } } -$pools = $register->get('pools'); -$queue = $pools - ->get('queue') - ->pop() - ->getResource() -; - -$connection = new Queue\Connection\Redis(fn() => $queue); -$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncOut'); +$connection = new Queue\Connection\Redis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379')); +$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); $server = new Queue\Server($adapter); - - $server->job() ->inject('message') ->inject('dbForConsole') - ->action(function (Message $message, Database $dbForConsole) use (&$keys, &$counter) { - - $payload = $message->getPayload()['value']; - $regions = Config::getParam('regions', true); - $regions = array_filter( - $regions, - fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region - && $region !== 'default', - ARRAY_FILTER_USE_KEY - ); - - if (!empty($payload['region'])) { + ->action(function (Message $message) use (&$stack, &$failures) { + + $payload = $message->getPayload()['value'] ?? []; + + if (!empty($payload['keys'])) { $regions = array_filter( - $regions, - fn ($region) => $payload['region'] === $region, + Config::getParam('regions', []), + fn ($region) => $payload['region'] === $region, ARRAY_FILTER_USE_KEY ); - } - if (!empty($payload['chunk'])) { - call($dbForConsole, $regions, $payload['chunk']); - return; + $failures[] = [ + 'regions' => $regions, + 'keys' => $payload['keys'] + ]; } - $keys[$payload['key']] = null; - -// if (count($keys) >= MAX_KEY_COUNT || ($counter + SUBMITION_INTERVAL) < time()) { -// call($dbForConsole, $regions, array_keys($keys)); -// $counter = time(); -// $keys = []; -// } + if (!empty($payload['key'])) { + if (!in_array($payload['key'], $stack['keys'] ?? [])) { + $stack['keys'][] = $payload['key']; + } + } }); Runtime::enableCoroutine(SWOOLE_HOOK_ALL); @@ -153,11 +140,28 @@ function call($database, $regions, $keys): void }); $server - ->workerStart(function () { - Timer::tick(1000, function () { - var_dump(date('m/d/Y H:i:s', time())); + ->workerStart(function () use (&$stack, &$failures) { + Timer::tick(10000, function () use (&$stack, &$failures) { + if (empty($stack['keys']) && count($failures) === 0) { + Console::info("Stack is empty"); + return; + } + + if (count($failures) > 0) { + $i = 0; + while ($i < count($failures)) { + $failure = array_shift($failures); + call(getConsoleDB(), $failure['regions'], $failure['keys']); + $i++; + } + return; + } + + $chunk = array_slice($stack['keys'], 0, MAX_KEY_COUNT); + array_splice($stack['keys'], 0, MAX_KEY_COUNT); + call(getConsoleDB(), $stack['regions'], $chunk); + $chunk = []; }); echo "Out region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; }) ->start(); - diff --git a/composer.json b/composer.json index 7ca5939359..ccfadca27d 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.6.*", - "utopia-php/queue": "dev-refactor-redis-client as 0.3.0", + "utopia-php/queue": "0.3.0", "utopia-php/pools": "0.1.*", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", diff --git a/composer.lock b/composer.lock index 7ef8f25135..76d15fb9f8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0b5f0fd08db65ca4c2e2f1a6d33cd299", + "content-hash": "d2d51b9a3dcbb3542243d1a68a078ece", "packages": [ { "name": "adhocore/jwt", @@ -693,16 +693,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.4.1", + "version": "2.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa", + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa", "shasum": "" }, "require": { @@ -792,7 +792,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.1" + "source": "https://github.com/guzzle/psr7/tree/2.4.2" }, "funding": [ { @@ -808,7 +808,7 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:45:39+00:00" + "time": "2022-10-25T13:49:28+00:00" }, { "name": "influxdb/influxdb-php", @@ -1901,12 +1901,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "99e7085eb229d0f0159a4f2107ea5ea123f7b32b" + "reference": "d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/99e7085eb229d0f0159a4f2107ea5ea123f7b32b", - "reference": "99e7085eb229d0f0159a4f2107ea5ea123f7b32b", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d", + "reference": "d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d", "shasum": "" }, "require": { @@ -1942,7 +1942,7 @@ "issues": "https://github.com/utopia-php/cache/issues", "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" }, - "time": "2022-10-18T06:58:42+00:00" + "time": "2022-10-26T08:25:43+00:00" }, { "name": "utopia-php/cli", @@ -2537,16 +2537,16 @@ }, { "name": "utopia-php/queue", - "version": "dev-refactor-redis-client", + "version": "0.3.0", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "3e49bcbfc343792ea4899d60b24e7b6b334e5910" + "reference": "42b132c6f2431b726c2bc629c386921e4934b863" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/3e49bcbfc343792ea4899d60b24e7b6b334e5910", - "reference": "3e49bcbfc343792ea4899d60b24e7b6b334e5910", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/42b132c6f2431b726c2bc629c386921e4934b863", + "reference": "42b132c6f2431b726c2bc629c386921e4934b863", "shasum": "" }, "require": { @@ -2592,9 +2592,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/refactor-redis-client" + "source": "https://github.com/utopia-php/queue/tree/0.3.0" }, - "time": "2022-10-24T14:29:47+00:00" + "time": "2022-10-19T13:22:07+00:00" }, { "name": "utopia-php/registry", @@ -5469,19 +5469,12 @@ "version": "dev-feat-update-cache-lib", "alias": "0.26.1", "alias_normalized": "0.26.1.0" - }, - { - "package": "utopia-php/queue", - "version": "dev-refactor-redis-client", - "alias": "0.3.0", - "alias_normalized": "0.3.0.0" } ], "minimum-stability": "stable", "stability-flags": { "utopia-php/cache": 20, - "utopia-php/database": 20, - "utopia-php/queue": 20 + "utopia-php/database": 20 }, "prefer-stable": false, "prefer-lowest": false, From 601569805f60eecb6ac1e8de301a4c8da12031dc Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 27 Oct 2022 17:01:42 +0300 Subject: [PATCH 19/87] Timer::tick --- app/controllers/api/edge.php | 4 +-- app/tasks/sync-edge.php | 2 +- app/workers/sync-out.php | 48 ++++++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index bd80b91843..22c845a557 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -37,9 +37,9 @@ ->inject('response') ->action(function (array $keys, Request $request, Response $response) { - //if (empty($keys)) { + if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - //} + } $client = new SyncIn('syncIn', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index b9530b2d84..a3564a3685 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -16,7 +16,7 @@ ->action(function () use ($register) { Console::title('Syncs edges V1'); Console::success(APP_NAME . ' Syncs Edge process v1 has started'); - + sleep(3); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); Console::loop(function () use ($interval, $register) { $database = getConsoleDB(); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index b8dc9d8e2e..34aae45e34 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -9,13 +9,13 @@ use Utopia\App; use Utopia\CLI\Console; use Utopia\Config\Config; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; use Utopia\Queue; use Utopia\Queue\Message; - $regions = array_filter( Config::getParam('regions', []), fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region @@ -27,10 +27,9 @@ 'regions' => $regions, 'keys' => [], ]; - $failures = []; -const MAX_KEY_COUNT = 2; +const CHUNK_MAX_KEYS = 2; const MAX_CURL_SEND_ATTEMPTS = 4; /** @@ -77,23 +76,31 @@ function send(string $url, string $token, array $stack): array * @throws Structure * @throws Exception */ -function call($database, $regions, $stack): void +function call($regions, $stack): void { + global $register; + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode([]); foreach ($regions as $code => $region) { - Console::info("Sending request to {$code}"); + $time = DateTime::now(); $response = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); if ($response['status'] !== Response::STATUS_CODE_OK) { - $database->createDocument('syncs', new Document([ - 'region' => App::getEnv('_APP_REGION', 'nyc1'), - 'target' => $code, - 'keys' => $stack, - 'status' => $response['status'], - 'payload' => $response['payload'], - ])); + Console::error("[{$time}] Request to {$code} has failed"); + try { + $database = getConsoleDB(); + $database->createDocument('syncs', new Document([ + 'region' => App::getEnv('_APP_REGION', 'nyc1'), + 'target' => $code, + 'keys' => $stack, + 'status' => $response['status'], + 'payload' => $response['payload'], + ])); + } catch (\Throwable $th) { + $register->get('pools')->reclaim(); + } } } } @@ -108,7 +115,7 @@ function call($database, $regions, $stack): void ->action(function (Message $message) use (&$stack, &$failures) { $payload = $message->getPayload()['value'] ?? []; - + var_dump($message->getPayload()); if (!empty($payload['keys'])) { $regions = array_filter( Config::getParam('regions', []), @@ -141,9 +148,10 @@ function call($database, $regions, $stack): void $server ->workerStart(function () use (&$stack, &$failures) { - Timer::tick(10000, function () use (&$stack, &$failures) { + Timer::tick(1000, function () use (&$stack, &$failures) { + $time = DateTime::now(); if (empty($stack['keys']) && count($failures) === 0) { - Console::info("Stack is empty"); + Console::info("[{$time}] Stack is empty"); return; } @@ -151,15 +159,17 @@ function call($database, $regions, $stack): void $i = 0; while ($i < count($failures)) { $failure = array_shift($failures); - call(getConsoleDB(), $failure['regions'], $failure['keys']); + Console::info("[{$time}] ReSending " . count($failure['keys']) . " to " . key($failure['regions'])); + call($failure['regions'], $failure['keys']); $i++; } return; } - $chunk = array_slice($stack['keys'], 0, MAX_KEY_COUNT); - array_splice($stack['keys'], 0, MAX_KEY_COUNT); - call(getConsoleDB(), $stack['regions'], $chunk); + $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS); + array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); + Console::info("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); + call($stack['regions'], $chunk); $chunk = []; }); echo "Out region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; From 7708859d7ddba5793e5907d809f9b6ac545386f3 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 30 Oct 2022 12:10:23 +0200 Subject: [PATCH 20/87] Timer::tick --- app/init.php | 1 + app/workers/sync-In.php | 12 ++++++++---- app/workers/sync-out.php | 9 +++++---- composer.lock | 32 ++++++++++++++++---------------- docker-compose.yml | 6 ++++++ 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/app/init.php b/app/init.php index 94a60e581e..8a427e72ee 100644 --- a/app/init.php +++ b/app/init.php @@ -931,6 +931,7 @@ function (mixed $value) { if ($project->isEmpty()) { $user = new Document(['$id' => ID::custom(''), '$collection' => 'users']); } else { + var_dump('Save cache invoked'); $user = $dbForProject->getDocument('users', Auth::$unique); } } else { diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 0482f92b08..5c52df08df 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -5,6 +5,8 @@ use Utopia\App; use Utopia\Cache\Cache; +use Utopia\CLI\Console; +use Utopia\Database\DateTime; use Utopia\Queue; use Utopia\Queue\Message; @@ -18,12 +20,14 @@ ->inject('message') ->inject('cache') ->action(function (Message $message, Cache $cache) { - + $time = DateTime::now(); $payload = $message->getPayload()['value']; + $cache->setDisableListeners(true); foreach ($payload['keys'] ?? [] as $key) { - var_dump('purging -> ' . $key); - var_dump($cache->purge($key)); + Console::info("[{$time}] Purging {$key}"); + $cache->purge($key); } + $cache->setDisableListeners(false); }); $server @@ -36,6 +40,6 @@ $server ->workerStart(function () { - echo "In region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; + echo "In [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started" . PHP_EOL; }) ->start(); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 34aae45e34..00d7f4bfcf 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -63,7 +63,7 @@ function send(string $url, string $token, array $stack): array return $payload; } - sleep(2); + sleep(1); } curl_close($ch); @@ -115,7 +115,7 @@ function call($regions, $stack): void ->action(function (Message $message) use (&$stack, &$failures) { $payload = $message->getPayload()['value'] ?? []; - var_dump($message->getPayload()); + if (!empty($payload['keys'])) { $regions = array_filter( Config::getParam('regions', []), @@ -148,7 +148,7 @@ function call($regions, $stack): void $server ->workerStart(function () use (&$stack, &$failures) { - Timer::tick(1000, function () use (&$stack, &$failures) { + Timer::tick(20000, function () use (&$stack, &$failures) { $time = DateTime::now(); if (empty($stack['keys']) && count($failures) === 0) { Console::info("[{$time}] Stack is empty"); @@ -170,8 +170,9 @@ function call($regions, $stack): void array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); Console::info("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); call($stack['regions'], $chunk); + //var_dump($stack['keys']); $chunk = []; }); - echo "Out region [" . App::getEnv('_APP_REGION', 'nyc1') . "] cache purging worker Started" . PHP_EOL; + echo "Out [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started" . PHP_EOL; }) ->start(); diff --git a/composer.lock b/composer.lock index 76d15fb9f8..e57e277ad2 100644 --- a/composer.lock +++ b/composer.lock @@ -693,16 +693,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.4.2", + "version": "2.4.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "3148458748274be1546f8f2809a6c09fe66f44aa" + "reference": "67c26b443f348a51926030c83481b85718457d3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa", - "reference": "3148458748274be1546f8f2809a6c09fe66f44aa", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", + "reference": "67c26b443f348a51926030c83481b85718457d3d", "shasum": "" }, "require": { @@ -792,7 +792,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.2" + "source": "https://github.com/guzzle/psr7/tree/2.4.3" }, "funding": [ { @@ -808,7 +808,7 @@ "type": "tidelift" } ], - "time": "2022-10-25T13:49:28+00:00" + "time": "2022-10-26T14:07:24+00:00" }, { "name": "influxdb/influxdb-php", @@ -1901,12 +1901,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d" + "reference": "c29179055def7827b27fde979cefe07c3e4858da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d", - "reference": "d0cd43b679fa23dc720c3bb9dff4c47c0eb4790d", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/c29179055def7827b27fde979cefe07c3e4858da", + "reference": "c29179055def7827b27fde979cefe07c3e4858da", "shasum": "" }, "require": { @@ -1942,7 +1942,7 @@ "issues": "https://github.com/utopia-php/cache/issues", "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" }, - "time": "2022-10-26T08:25:43+00:00" + "time": "2022-10-27T14:35:59+00:00" }, { "name": "utopia-php/cli", @@ -3635,16 +3635,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.18", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", + "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", "shasum": "" }, "require": { @@ -3700,7 +3700,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" }, "funding": [ { @@ -3708,7 +3708,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2022-10-27T13:35:33+00:00" }, { "name": "phpunit/php-file-iterator", diff --git a/docker-compose.yml b/docker-compose.yml index 9757f9dd42..c5bf54a205 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -108,6 +108,8 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - mariadb - redis @@ -279,6 +281,8 @@ services: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - ./vendor/utopia-php/queue:/usr/src/code/vendor/utopia-php/queue + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - mariadb - redis @@ -308,6 +312,8 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - redis environment: From 545d86d994d3a302cfa2d3a41a1fbd3652d87c01 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 31 Oct 2022 15:38:50 +0200 Subject: [PATCH 21/87] Timer::tick --- .env | 5 +- app/controllers/api/edge.php | 25 ++++++- app/init.php | 9 ++- app/tasks/sync-edge.php | 40 ++++++++++-- app/worker.php | 122 ++++++++++++++++++++++------------- app/workers/sync-In.php | 26 +++++--- app/workers/sync-out.php | 57 +++++++++------- composer.json | 2 +- composer.lock | 14 ++-- docker-compose.yml | 8 +-- 10 files changed, 204 insertions(+), 104 deletions(-) diff --git a/.env b/.env index 950fd44821..900a443080 100644 --- a/.env +++ b/.env @@ -84,8 +84,9 @@ _APP_MAINTENANCE_RETENTION_AUDIT=1209600 _APP_USAGE_TIMESERIES_INTERVAL=2 _APP_USAGE_DATABASE_INTERVAL=15 _APP_USAGE_STATS=enabled -_APP_LOGGING_PROVIDER= -_APP_LOGGING_CONFIG= +_APP_LOGGING_PROVIDER=sentry +_APP_LOGGING_CONFIG=4190483bb7d14d659e526aa61b0c7b5e;4504077395230720 +_APP_REGION=nyc1 DOCKERHUB_PULL_USERNAME= DOCKERHUB_PULL_PASSWORD= DOCKERHUB_PULL_EMAIL= \ No newline at end of file diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 22c845a557..858a39c87d 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -2,14 +2,16 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; +use Appwrite\DSN\DSN; use Appwrite\Extend\Exception; +use Appwrite\URL\URL as AppwriteURL; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Queue\Client as SyncIn; use Utopia\Queue\Connection\Redis as QueueRedis; -use Utopia\Registry\Registry; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; @@ -41,7 +43,26 @@ throw new Exception(Exception::KEY_NOT_FOUND); } - $client = new SyncIn('syncIn', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); + $fallbackForRedis = AppwriteURL::unparse([ + 'scheme' => 'redis', + 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), + 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), + 'user' => App::getEnv('_APP_REDIS_USER', ''), + 'pass' => App::getEnv('_APP_REDIS_PASS', ''), + ]); + + $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); + $dsns = explode(',', $connection ?? ''); + + if (empty($dsns)) { + Console::error("No Dsn found"); + } + + $dsn = explode('=', $dsns[0]); + $dsn = $dsn[1] ?? ''; + $dsn = new DSN($dsn); + + $client = new SyncIn('syncIn', new QueueRedis($dsn->getHost(), $dsn->getPort())); $client->enqueue(['value' => ['keys' => $keys]]); diff --git a/app/init.php b/app/init.php index 8a427e72ee..4673ccb59f 100644 --- a/app/init.php +++ b/app/init.php @@ -931,7 +931,7 @@ function (mixed $value) { if ($project->isEmpty()) { $user = new Document(['$id' => ID::custom(''), '$collection' => 'users']); } else { - var_dump('Save cache invoked'); + //Todo fix cache save re-invoked $user = $dbForProject->getDocument('users', Auth::$unique); } } else { @@ -1080,11 +1080,18 @@ function (mixed $value) { $client = new SyncOut('syncOut', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); $cache->on(cache::EVENT_SAVE, function ($key) use ($client) { + //Todo fix cache re-invoked + if ($key === 'cache-console:_metadata:users') { + return; + } $client ->enqueue(['value' => ['key' => $key]]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($client) { + if ($key === 'cache-console:_metadata:users') { + return; + } $client ->enqueue(['value' => ['key' => $key]]); }); diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index a3564a3685..18ad595f02 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -3,6 +3,8 @@ global $cli; global $register; +use Appwrite\DSN\DSN; +use Appwrite\URL\URL as AppwriteURL; use Utopia\App; use Utopia\CLI\Console; use Utopia\Database\DateTime; @@ -15,13 +17,39 @@ ->desc('Schedules edge sync tasks') ->action(function () use ($register) { Console::title('Syncs edges V1'); - Console::success(APP_NAME . ' Syncs Edge process v1 has started'); - sleep(3); + Console::success(APP_NAME . ' Sync Edge process v1 has started'); + + $fallbackForRedis = AppwriteURL::unparse([ + 'scheme' => 'redis', + 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), + 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), + 'user' => App::getEnv('_APP_REDIS_USER', ''), + 'pass' => App::getEnv('_APP_REDIS_PASS', ''), + ]); + + $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); + $dsns = explode(',', $connection ?? ''); + + if (empty($dsns)) { + Console::error("No Dsn found"); + } + + $dsn = explode('=', $dsns[0]); + $dsn = $dsn[1] ?? ''; + $dsn = new DSN($dsn); + + // Todo fix pdo PDOException + //Table 'appwrite.console__metadata' doesn't exist + sleep(4); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $register) { + Console::loop(function () use ($interval, $register, $dsn) { $database = getConsoleDB(); $time = DateTime::now(); - $region = App::getEnv('_APP_REGION', 'nyc1'); + $region = App::getEnv('_APP_REGION', 'default'); + if (App::getEnv('_APP_REGION', 'default') === 'default') { + return; + } + Console::info("[{$time}] Notifying workers with edges tasks every {$interval} seconds"); $time = DateTime::now(); @@ -31,9 +59,9 @@ ]); if (count($chunks) > 0) { - $client = new SyncOut('syncOut', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); + $client = new SyncOut('syncOut', new QueueRedis($dsn->getHost(), $dsn->getPort())); foreach ($chunks as $counter => $chunk) { - Console::info("[{$time}] Sending chunk .($counter+1). ot of " . count($chunks) . " to {$chunk->getAttribute('target')}"); + Console::info("[{$time}] Sending chunk .$counter. ot of " . count($chunks) . " to {$chunk->getAttribute('target')}"); $client ->enqueue([ 'value' => [ diff --git a/app/worker.php b/app/worker.php index eef1248f36..d1a68ea278 100644 --- a/app/worker.php +++ b/app/worker.php @@ -2,19 +2,28 @@ require_once __DIR__ . '/init.php'; +use Appwrite\DSN\DSN; +use Appwrite\URL\URL as AppwriteURL; +use Swoole\Runtime; +use Utopia\App; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; +use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; +use Utopia\Database\Validator\Authorization; +use Utopia\Logger\Log; +use Utopia\Logger\Logger; use Utopia\Queue\Server; use Utopia\Registry\Registry; global $register; +Runtime::enableCoroutine(SWOOLE_HOOK_ALL); + Server::setResource('register', fn() => $register); Server::setResource('dbForConsole', function (Cache $cache, Registry $register) { - $pools = $register->get('pools'); $dbAdapter = $pools ->get('console') @@ -29,7 +38,6 @@ }, ['cache', 'register']); Server::setResource('cache', function (Registry $register) { - $pools = $register->get('pools'); $list = Config::getParam('pools-cache', []); $adapters = []; @@ -45,49 +53,71 @@ return new Cache(new Sharding($adapters)); }, ['register']); -/** - * Get console database - * @return Database - */ -function getConsoleDB(): Database -{ - global $register; - - $pools = $register->get('pools'); /** @var \Utopia\Pools\Group $pools */ - - $dbAdapter = $pools - ->get('console') - ->pop() - ->getResource() - ; - - $database = new Database($dbAdapter, getCache()); - - $database->setNamespace('console'); - - return $database; +Server::setResource('ErrorLog', function (Logger $logger) { + return function (Throwable $error, $action) use ($logger) { + + if ($logger) { + $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); + + if ($error->getCode() >= 500 || $error->getCode() === 0) { + $log = new Log(); + + $log->setNamespace("http"); + $log->setServer(\gethostname()); + $log->setVersion($version); + $log->setType(Log::TYPE_ERROR); + $log->setMessage($error->getMessage()); + + $log->setAction($action); + + $log->addTag('verboseType', get_class($error)); + $log->addTag('code', $error->getCode()); + + $log->addExtra('file', $error->getFile()); + $log->addExtra('line', $error->getLine()); + $log->addExtra('trace', $error->getTraceAsString()); + $log->addExtra('detailedTrace', $error->getTrace()); + $log->addExtra('roles', Authorization::$roles); + + $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; + $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); + + $responseCode = $logger->addLog($log); + Console::info('Log pushed with status code: ' . $responseCode); + } + } + + $code = $error->getCode(); + $message = $error->getMessage(); + $file = $error->getFile(); + $line = $error->getLine(); + $trace = $error->getTrace(); + + Console::error('[Error] Timestamp: ' . date('c', time())); + Console::error('[Error] Type: ' . get_class($error)); + Console::error('[Error] Message: ' . $message); + Console::error('[Error] File: ' . $file); + Console::error('[Error] Line: ' . $line); + Console::error('[Error] Code: ' . $code); + Console::error('[Error] Trace: ' . $trace); + }; +}); + +$fallbackForRedis = AppwriteURL::unparse([ + 'scheme' => 'redis', + 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), + 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), + 'user' => App::getEnv('_APP_REDIS_USER', ''), + 'pass' => App::getEnv('_APP_REDIS_PASS', ''), +]); + +$connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); +$dsns = explode(',', $connection ?? ''); + +if (empty($dsns)) { + Console::error("Dsn not found"); } -/** - * Get Cache - * @return Cache - */ -function getCache(): Cache -{ - global $register; - - $pools = $register->get('pools'); /** @var \Utopia\Pools\Group $pools */ - - $list = Config::getParam('pools-cache', []); - $adapters = []; - - foreach ($list as $value) { - $adapters[] = $pools - ->get($value) - ->pop() - ->getResource() - ; - } - - return new Cache(new Sharding($adapters)); -} +$dsn = explode('=', $dsns[0]); +$dsn = $dsn[1] ?? ''; +$dsn = new DSN($dsn); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 5c52df08df..86f957a0e3 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -2,7 +2,7 @@ require_once __DIR__ . '/../worker.php'; - +use Appwrite\Extend\Exception; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -10,9 +10,14 @@ use Utopia\Queue; use Utopia\Queue\Message; +if (App::getEnv('_APP_REGION', 'default') === 'default') { + throw new Exception(Exception::GENERAL_SERVER_ERROR); +} + global $register; +global $dsn; -$connection = new Queue\Connection\Redis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379')); +$connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); $adapter = new Queue\Adapter\Swoole($connection, 2, 'syncIn'); $server = new Queue\Server($adapter); @@ -33,13 +38,16 @@ $server ->error() ->inject('error') - ->action(function ($error) { - echo $error->getMessage() . PHP_EOL; - echo $error->getLine() . PHP_EOL; + ->inject('logError') + ->action(function ($error, $logError) { + Console::error($error->getMessage() . ' ' . $error->getFile() . ' ' . $error->getLine()); + call_user_func($logError, $error, 'sync-in-worker'); }); $server - ->workerStart(function () { - echo "In [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started" . PHP_EOL; - }) - ->start(); + ->workerStart() + ->action(function () { + Console::success("In [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started"); + }); + +$server->start(); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 00d7f4bfcf..ee89c4bf0b 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -3,8 +3,8 @@ require_once __DIR__ . '/../worker.php'; use Ahc\Jwt\JWT; +use Appwrite\Extend\Exception; use Appwrite\Utopia\Response; -use Swoole\Runtime; use Swoole\Timer; use Utopia\App; use Utopia\CLI\Console; @@ -16,9 +16,15 @@ use Utopia\Queue; use Utopia\Queue\Message; +if (App::getEnv('_APP_REGION', 'default') === 'default') { + throw new Exception(Exception::GENERAL_SERVER_ERROR); +} + +global $dsn; + $regions = array_filter( Config::getParam('regions', []), - fn ($region) => App::getEnv('_APP_REGION', 'nyc1') !== $region + fn ($region) => App::getEnv('_APP_REGION') !== $region && $region !== 'default', ARRAY_FILTER_USE_KEY ); @@ -38,7 +44,7 @@ * @param array $stack * @return array */ -function send(string $url, string $token, array $stack): array +function call(string $url, string $token, array $stack): array { $payload = []; $ch = curl_init($url); @@ -76,7 +82,7 @@ function send(string $url, string $token, array $stack): array * @throws Structure * @throws Exception */ -function call($regions, $stack): void +function handle($dbForConsole, $regions, $stack): void { global $register; @@ -86,13 +92,12 @@ function call($regions, $stack): void foreach ($regions as $code => $region) { $time = DateTime::now(); - $response = send($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); + $response = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); if ($response['status'] !== Response::STATUS_CODE_OK) { Console::error("[{$time}] Request to {$code} has failed"); try { - $database = getConsoleDB(); - $database->createDocument('syncs', new Document([ - 'region' => App::getEnv('_APP_REGION', 'nyc1'), + $dbForConsole->createDocument('syncs', new Document([ + 'region' => App::getEnv('_APP_REGION'), 'target' => $code, 'keys' => $stack, 'status' => $response['status'], @@ -105,13 +110,11 @@ function call($regions, $stack): void } } -$connection = new Queue\Connection\Redis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379')); -$adapter = new Queue\Adapter\Swoole($connection, 1, 'syncOut'); +$connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); +$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncOut'); $server = new Queue\Server($adapter); - $server->job() ->inject('message') - ->inject('dbForConsole') ->action(function (Message $message) use (&$stack, &$failures) { $payload = $message->getPayload()['value'] ?? []; @@ -136,20 +139,24 @@ function call($regions, $stack): void } }); -Runtime::enableCoroutine(SWOOLE_HOOK_ALL); - $server ->error() ->inject('error') - ->action(function ($error) { - echo $error->getMessage() . PHP_EOL; - echo $error->getLine() . PHP_EOL; + ->inject('errorLog') + ->action(function ($error, $errorLog) { + var_dump($error); + Console::error($error->getMessage() . ' ' . $error->getFile() . ' ' . $error->getLine()); + call_user_func($errorLog, $error, 'sync-out-worker'); }); $server - ->workerStart(function () use (&$stack, &$failures) { - Timer::tick(20000, function () use (&$stack, &$failures) { + ->workerStart() + ->inject('dbForConsole') + ->action(function ($dbForConsole) use (&$stack, &$failures) { + + Timer::tick(5000, function () use ($dbForConsole, &$stack, &$failures) { $time = DateTime::now(); + if (empty($stack['keys']) && count($failures) === 0) { Console::info("[{$time}] Stack is empty"); return; @@ -160,7 +167,7 @@ function call($regions, $stack): void while ($i < count($failures)) { $failure = array_shift($failures); Console::info("[{$time}] ReSending " . count($failure['keys']) . " to " . key($failure['regions'])); - call($failure['regions'], $failure['keys']); + handle($dbForConsole, $failure['regions'], $failure['keys']); $i++; } return; @@ -169,10 +176,10 @@ function call($regions, $stack): void $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS); array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); Console::info("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); - call($stack['regions'], $chunk); - //var_dump($stack['keys']); + handle($dbForConsole, $stack['regions'], $chunk); $chunk = []; }); - echo "Out [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started" . PHP_EOL; - }) - ->start(); + Console::success("Out [" . App::getEnv('_APP_REGION') . "] edge cache purging worker Started"); + }); + + $server->start(); diff --git a/composer.json b/composer.json index ccfadca27d..110e44ca9d 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,7 @@ "utopia-php/websocket": "0.1.0", "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.6.*", - "utopia-php/queue": "0.3.0", + "utopia-php/queue": "0.4.0", "utopia-php/pools": "0.1.*", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", diff --git a/composer.lock b/composer.lock index e57e277ad2..2aa790ead4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d2d51b9a3dcbb3542243d1a68a078ece", + "content-hash": "a02c3502dca5a3a9f0f283e06e11e30e", "packages": [ { "name": "adhocore/jwt", @@ -2537,16 +2537,16 @@ }, { "name": "utopia-php/queue", - "version": "0.3.0", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "42b132c6f2431b726c2bc629c386921e4934b863" + "reference": "0cad4cf4231377aa6c67956b51ba1954e0d02166" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/42b132c6f2431b726c2bc629c386921e4934b863", - "reference": "42b132c6f2431b726c2bc629c386921e4934b863", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/0cad4cf4231377aa6c67956b51ba1954e0d02166", + "reference": "0cad4cf4231377aa6c67956b51ba1954e0d02166", "shasum": "" }, "require": { @@ -2592,9 +2592,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.3.0" + "source": "https://github.com/utopia-php/queue/tree/0.4.0" }, - "time": "2022-10-19T13:22:07+00:00" + "time": "2022-10-31T06:23:08+00:00" }, { "name": "utopia-php/registry", diff --git a/docker-compose.yml b/docker-compose.yml index c5bf54a205..612b9d7b60 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -280,9 +280,6 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/queue:/usr/src/code/vendor/utopia-php/queue - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache - - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - mariadb - redis @@ -301,6 +298,7 @@ services: - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE + - _APP_REGION appwrite-worker-sync-in: entrypoint: worker-sync-in @@ -312,8 +310,6 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache - - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database depends_on: - redis environment: @@ -326,6 +322,7 @@ services: - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE + - _APP_REGION appwrite-worker-webhooks: entrypoint: worker-webhooks @@ -696,6 +693,7 @@ services: - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE + - _APP_REGION appwrite-usage-timeseries: entrypoint: From 6842286a3a8925a9d8ab195d4f2ac425729de8c1 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 31 Oct 2022 15:39:11 +0200 Subject: [PATCH 22/87] Timer::tick --- app/workers/sync-out.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index ee89c4bf0b..89fc35d776 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -144,7 +144,6 @@ function handle($dbForConsole, $regions, $stack): void ->inject('error') ->inject('errorLog') ->action(function ($error, $errorLog) { - var_dump($error); Console::error($error->getMessage() . ' ' . $error->getFile() . ' ' . $error->getLine()); call_user_func($errorLog, $error, 'sync-out-worker'); }); From e291d81be3d608887d93b0e736ddd23ba5d8d2ad Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 2 Nov 2022 11:39:16 +0200 Subject: [PATCH 23/87] addressing comments --- app/controllers/api/edge.php | 4 +-- app/init.php | 22 +++++++++--- app/tasks/sync-edge.php | 69 ++++++++++++++++++++---------------- app/worker.php | 11 +++++- app/workers/sync-In.php | 52 ++++++++++++++++++++------- app/workers/sync-out.php | 62 +++++++++++++++++++++++--------- docker-compose.yml | 2 ++ 7 files changed, 153 insertions(+), 69 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 858a39c87d..14bc4fff9b 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -8,7 +8,6 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; -use Utopia\CLI\Console; use Utopia\Database\Document; use Utopia\Queue\Client as SyncIn; use Utopia\Queue\Connection\Redis as QueueRedis; @@ -55,13 +54,12 @@ $dsns = explode(',', $connection ?? ''); if (empty($dsns)) { - Console::error("No Dsn found"); + throw new Exception(Exception::GENERAL_SERVER_ERROR); } $dsn = explode('=', $dsns[0]); $dsn = $dsn[1] ?? ''; $dsn = new DSN($dsn); - $client = new SyncIn('syncIn', new QueueRedis($dsn->getHost(), $dsn->getPort())); $client->enqueue(['value' => ['keys' => $keys]]); diff --git a/app/init.php b/app/init.php index 4673ccb59f..3c97c1f2d0 100644 --- a/app/init.php +++ b/app/init.php @@ -1028,11 +1028,23 @@ function (mixed $value) { ]); }, []); -//App::setResource('queue', function (Group $pools) { -// $pools->get('queue') -// ->pop() -// ->getResource(); -//}, ['pools']); +App::setResource('queue', function () { + + $fallbackForRedis = AppwriteURL::unparse([ + 'scheme' => 'redis', + 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), + 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), + 'user' => App::getEnv('_APP_REDIS_USER', ''), + 'pass' => App::getEnv('_APP_REDIS_PASS', ''), + ]); + + $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); + + $dsns = explode(',', $connection ?? ''); + $dsn = explode('=', $dsns[0]); + $dsn = $dsn[1] ?? ''; + return new DSN($dsn); +}, []); App::setResource('dbForProject', function (Group $pools, Database $dbForConsole, Cache $cache, Document $project) { if ($project->isEmpty() || $project->getId() === 'console') { diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index 18ad595f02..3310704ffa 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -9,15 +9,15 @@ use Utopia\CLI\Console; use Utopia\Database\DateTime; use Utopia\Database\Query; +use Utopia\Queue; use Utopia\Queue\Client as SyncOut; -use Utopia\Queue\Connection\Redis as QueueRedis; $cli ->task('sync-edge') ->desc('Schedules edge sync tasks') ->action(function () use ($register) { Console::title('Syncs edges V1'); - Console::success(APP_NAME . ' Sync Edge process v1 has started'); + Console::success(APP_NAME . ' Sync failed cache purge process v1 has started'); $fallbackForRedis = AppwriteURL::unparse([ 'scheme' => 'redis', @@ -37,43 +37,52 @@ $dsn = explode('=', $dsns[0]); $dsn = $dsn[1] ?? ''; $dsn = new DSN($dsn); + $redisConnection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); + $client = new SyncOut('syncOut', $redisConnection); + // Todo fix pdo PDOException - //Table 'appwrite.console__metadata' doesn't exist + // Table 'appwrite.console__metadata' doesn't exist sleep(4); + $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $register, $dsn) { + Console::loop(function () use ($interval, $register, $client) { + $database = getConsoleDB(); $time = DateTime::now(); - $region = App::getEnv('_APP_REGION', 'default'); - if (App::getEnv('_APP_REGION', 'default') === 'default') { - return; - } + $count = 0; + $chunk = 0; + $limit = 50; + $sum = $limit; - Console::info("[{$time}] Notifying workers with edges tasks every {$interval} seconds"); + Console::success("[{$time}] New task every {$interval} seconds"); - $time = DateTime::now(); - $chunks = $database->find('syncs', [ - Query::equal('region', [$region]), - Query::limit(500) - ]); - - if (count($chunks) > 0) { - $client = new SyncOut('syncOut', new QueueRedis($dsn->getHost(), $dsn->getPort())); - foreach ($chunks as $counter => $chunk) { - Console::info("[{$time}] Sending chunk .$counter. ot of " . count($chunks) . " to {$chunk->getAttribute('target')}"); - $client - ->enqueue([ - 'value' => [ - 'region' => $chunk->getAttribute('target'), - 'keys' => $chunk->getAttribute('keys') - ] - ]); - - $database->deleteDocument('syncs', $chunk->getId()); + while ($sum === $limit) { + $chunk++; + + $results = $database->find('syncs', [ + Query::equal('region', [App::getEnv('_APP_REGION')]), + Query::limit($limit) + ]); + + $sum = count($results); + if ($sum > 0) { + foreach ($results as $document) { + Console::info("[{$time}] Enqueueing keys chunk {$count} to {$document->getAttribute('target')}"); + $client + ->enqueue([ + 'value' => [ + 'region' => $document->getAttribute('target'), + 'keys' => $document->getAttribute('keys') + ] + ]); + + $database->deleteDocument('syncs', $document->getId()); + $count++; + } + } else { + Console::info("[{$time}] No cache keys where found."); } - } else { - Console::info("[{$time}] No cache key chunks where found."); } }, $interval); }); diff --git a/app/worker.php b/app/worker.php index d1a68ea278..77f78c3096 100644 --- a/app/worker.php +++ b/app/worker.php @@ -16,6 +16,7 @@ use Utopia\Logger\Logger; use Utopia\Queue\Server; use Utopia\Registry\Registry; +use Utopia\Queue; global $register; @@ -53,6 +54,10 @@ return new Cache(new Sharding($adapters)); }, ['register']); +App::setResource('logger', function ($register) { + return $register->get('logger'); +}, ['register']); + Server::setResource('ErrorLog', function (Logger $logger) { return function (Throwable $error, $action) use ($logger) { @@ -114,10 +119,14 @@ $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); $dsns = explode(',', $connection ?? ''); -if (empty($dsns)) { +if (empty($dsns[0])) { Console::error("Dsn not found"); } $dsn = explode('=', $dsns[0]); $dsn = $dsn[1] ?? ''; $dsn = new DSN($dsn); + +$redisConnection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); +$workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); +$workerNumber = 1; diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 86f957a0e3..2df457083a 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -2,23 +2,18 @@ require_once __DIR__ . '/../worker.php'; -use Appwrite\Extend\Exception; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\DateTime; +use Utopia\Logger\Log; use Utopia\Queue; use Utopia\Queue\Message; -if (App::getEnv('_APP_REGION', 'default') === 'default') { - throw new Exception(Exception::GENERAL_SERVER_ERROR); -} +global $redisConnection; +global $workerNumber; -global $register; -global $dsn; - -$connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); -$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncIn'); +$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncIn'); $server = new Queue\Server($adapter); $server->job() @@ -38,10 +33,41 @@ $server ->error() ->inject('error') - ->inject('logError') - ->action(function ($error, $logError) { - Console::error($error->getMessage() . ' ' . $error->getFile() . ' ' . $error->getLine()); - call_user_func($logError, $error, 'sync-in-worker'); + ->inject('logger') + ->action(function ($error, $logger) { + $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); + + if ($error instanceof PDOException) { + throw $error; + } + + if ($error->getCode() >= 500 || $error->getCode() === 0) { + $log = new Log(); + + $log->setNamespace("worker"); + $log->setServer(\gethostname()); + $log->setVersion($version); + $log->setType(Log::TYPE_ERROR); + $log->setMessage($error->getMessage()); + $log->setAction('worker-sync-out'); + $log->addTag('verboseType', get_class($error)); + $log->addTag('code', $error->getCode()); + $log->addExtra('file', $error->getFile()); + $log->addExtra('line', $error->getLine()); + $log->addExtra('trace', $error->getTraceAsString()); + $log->addExtra('detailedTrace', $error->getTrace()); + $log->addExtra('roles', \Utopia\Database\Validator\Authorization::$roles); + + $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; + $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); + + $logger->addLog($log); + } + + Console::error('[Error] Type: ' . get_class($error)); + Console::error('[Error] Message: ' . $error->getMessage()); + Console::error('[Error] File: ' . $error->getFile()); + Console::error('[Error] Line: ' . $error->getLine()); }); $server diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 89fc35d776..fa15114580 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -13,14 +13,12 @@ use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; +use Utopia\Logger\Log; use Utopia\Queue; use Utopia\Queue\Message; -if (App::getEnv('_APP_REGION', 'default') === 'default') { - throw new Exception(Exception::GENERAL_SERVER_ERROR); -} - -global $dsn; +global $redisConnection; +global $workerNumber; $regions = array_filter( Config::getParam('regions', []), @@ -85,8 +83,6 @@ function call(string $url, string $token, array $stack): array function handle($dbForConsole, $regions, $stack): void { - global $register; - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode([]); @@ -95,7 +91,7 @@ function handle($dbForConsole, $regions, $stack): void $response = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); if ($response['status'] !== Response::STATUS_CODE_OK) { Console::error("[{$time}] Request to {$code} has failed"); - try { + $dbForConsole->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION'), 'target' => $code, @@ -103,16 +99,13 @@ function handle($dbForConsole, $regions, $stack): void 'status' => $response['status'], 'payload' => $response['payload'], ])); - } catch (\Throwable $th) { - $register->get('pools')->reclaim(); - } } } } -$connection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); -$adapter = new Queue\Adapter\Swoole($connection, 2, 'syncOut'); +$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncOut'); $server = new Queue\Server($adapter); + $server->job() ->inject('message') ->action(function (Message $message) use (&$stack, &$failures) { @@ -142,10 +135,45 @@ function handle($dbForConsole, $regions, $stack): void $server ->error() ->inject('error') - ->inject('errorLog') - ->action(function ($error, $errorLog) { - Console::error($error->getMessage() . ' ' . $error->getFile() . ' ' . $error->getLine()); - call_user_func($errorLog, $error, 'sync-out-worker'); + ->inject('logger') + ->inject('register') + ->action(function ($error, $logger, $register) { + + $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); + + if ($error instanceof PDOException) { + throw $error; + } + + if ($error->getCode() >= 500 || $error->getCode() === 0) { + $log = new Log(); + + $log->setNamespace("worker"); + $log->setServer(\gethostname()); + $log->setVersion($version); + $log->setType(Log::TYPE_ERROR); + $log->setMessage($error->getMessage()); + $log->setAction('worker-sync-out'); + $log->addTag('verboseType', get_class($error)); + $log->addTag('code', $error->getCode()); + $log->addExtra('file', $error->getFile()); + $log->addExtra('line', $error->getLine()); + $log->addExtra('trace', $error->getTraceAsString()); + $log->addExtra('detailedTrace', $error->getTrace()); + $log->addExtra('roles', \Utopia\Database\Validator\Authorization::$roles); + + $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; + $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); + + $logger->addLog($log); + } + + Console::error('[Error] Type: ' . get_class($error)); + Console::error('[Error] Message: ' . $error->getMessage()); + Console::error('[Error] File: ' . $error->getFile()); + Console::error('[Error] Line: ' . $error->getLine()); + + $register->get('pools')->reclaim(); }); $server diff --git a/docker-compose.yml b/docker-compose.yml index 612b9d7b60..97d85b2413 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -298,6 +298,7 @@ services: - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE + - _APP_WORKER_PER_CORE - _APP_REGION appwrite-worker-sync-in: @@ -322,6 +323,7 @@ services: - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE + - _APP_WORKER_PER_CORE - _APP_REGION appwrite-worker-webhooks: From 7bd16180c3c9903e032f923184d4f2aba51dd166 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 2 Nov 2022 11:45:52 +0200 Subject: [PATCH 24/87] addressing comments --- app/worker.php | 50 +--------------------------------------- app/workers/sync-out.php | 1 + 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/app/worker.php b/app/worker.php index 77f78c3096..e1d46d4f46 100644 --- a/app/worker.php +++ b/app/worker.php @@ -58,56 +58,8 @@ return $register->get('logger'); }, ['register']); -Server::setResource('ErrorLog', function (Logger $logger) { - return function (Throwable $error, $action) use ($logger) { - - if ($logger) { - $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); - - if ($error->getCode() >= 500 || $error->getCode() === 0) { - $log = new Log(); - - $log->setNamespace("http"); - $log->setServer(\gethostname()); - $log->setVersion($version); - $log->setType(Log::TYPE_ERROR); - $log->setMessage($error->getMessage()); - - $log->setAction($action); - - $log->addTag('verboseType', get_class($error)); - $log->addTag('code', $error->getCode()); - - $log->addExtra('file', $error->getFile()); - $log->addExtra('line', $error->getLine()); - $log->addExtra('trace', $error->getTraceAsString()); - $log->addExtra('detailedTrace', $error->getTrace()); - $log->addExtra('roles', Authorization::$roles); - - $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; - $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); - - $responseCode = $logger->addLog($log); - Console::info('Log pushed with status code: ' . $responseCode); - } - } - - $code = $error->getCode(); - $message = $error->getMessage(); - $file = $error->getFile(); - $line = $error->getLine(); - $trace = $error->getTrace(); - - Console::error('[Error] Timestamp: ' . date('c', time())); - Console::error('[Error] Type: ' . get_class($error)); - Console::error('[Error] Message: ' . $message); - Console::error('[Error] File: ' . $file); - Console::error('[Error] Line: ' . $line); - Console::error('[Error] Code: ' . $code); - Console::error('[Error] Trace: ' . $trace); - }; -}); +// Todo better job to inject the client as a resource $fallbackForRedis = AppwriteURL::unparse([ 'scheme' => 'redis', 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index fa15114580..b8d55d212c 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -139,6 +139,7 @@ function handle($dbForConsole, $regions, $stack): void ->inject('register') ->action(function ($error, $logger, $register) { + // Todo better job of abstracting the error log $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); if ($error instanceof PDOException) { From da5addf2f2bc672ce24922f7a1789c6368eaa81c Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 2 Nov 2022 16:43:42 +0200 Subject: [PATCH 25/87] addressing comments --- .env | 4 ++-- app/worker.php | 9 +++------ app/workers/sync-out.php | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.env b/.env index 900a443080..32c60b7935 100644 --- a/.env +++ b/.env @@ -84,8 +84,8 @@ _APP_MAINTENANCE_RETENTION_AUDIT=1209600 _APP_USAGE_TIMESERIES_INTERVAL=2 _APP_USAGE_DATABASE_INTERVAL=15 _APP_USAGE_STATS=enabled -_APP_LOGGING_PROVIDER=sentry -_APP_LOGGING_CONFIG=4190483bb7d14d659e526aa61b0c7b5e;4504077395230720 +_APP_LOGGING_PROVIDER= +_APP_LOGGING_CONFIG= _APP_REGION=nyc1 DOCKERHUB_PULL_USERNAME= DOCKERHUB_PULL_PASSWORD= diff --git a/app/worker.php b/app/worker.php index e1d46d4f46..f705636bf8 100644 --- a/app/worker.php +++ b/app/worker.php @@ -3,17 +3,14 @@ require_once __DIR__ . '/init.php'; use Appwrite\DSN\DSN; +use Appwrite\Extend\Exception; use Appwrite\URL\URL as AppwriteURL; use Swoole\Runtime; use Utopia\App; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; -use Utopia\CLI\Console; use Utopia\Config\Config; use Utopia\Database\Database; -use Utopia\Database\Validator\Authorization; -use Utopia\Logger\Log; -use Utopia\Logger\Logger; use Utopia\Queue\Server; use Utopia\Registry\Registry; use Utopia\Queue; @@ -71,8 +68,8 @@ $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); $dsns = explode(',', $connection ?? ''); -if (empty($dsns[0])) { - Console::error("Dsn not found"); +if (empty($dsns)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR); } $dsn = explode('=', $dsns[0]); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index b8d55d212c..8c36cbe808 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -92,7 +92,7 @@ function handle($dbForConsole, $regions, $stack): void if ($response['status'] !== Response::STATUS_CODE_OK) { Console::error("[{$time}] Request to {$code} has failed"); - $dbForConsole->createDocument('syncs', new Document([ + $dbForConsole->createDocument('sync', new Document([ 'region' => App::getEnv('_APP_REGION'), 'target' => $code, 'keys' => $stack, @@ -103,8 +103,8 @@ function handle($dbForConsole, $regions, $stack): void } } -$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncOut'); -$server = new Queue\Server($adapter); +$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncOut'); +$server = new Queue\Server($adapter); $server->job() ->inject('message') From 848b997a5fc44e589ea645c0759d356bcdd0beab Mon Sep 17 00:00:00 2001 From: shimon Date: Fri, 4 Nov 2022 13:01:47 +0200 Subject: [PATCH 26/87] pools::queue client injection --- app/controllers/api/edge.php | 25 ++++--------------------- app/init.php | 36 ++++++++++++++++++++---------------- app/tasks/sync-edge.php | 27 ++++----------------------- app/worker.php | 34 ++++++++++------------------------ app/workers/sync-In.php | 8 ++++---- app/workers/sync-out.php | 8 ++++---- composer.json | 2 +- composer.lock | 26 +++++++++++++++++--------- docker-compose.yml | 1 + 9 files changed, 65 insertions(+), 102 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 14bc4fff9b..353befb83e 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -9,8 +9,8 @@ use Appwrite\Utopia\Response; use Utopia\App; use Utopia\Database\Document; +use Utopia\Pools\Group; use Utopia\Queue\Client as SyncIn; -use Utopia\Queue\Connection\Redis as QueueRedis; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; @@ -36,31 +36,14 @@ ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') - ->action(function (array $keys, Request $request, Response $response) { + ->inject('pools') + ->action(function (array $keys, Request $request, Response $response, Group $pools) { if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); } - $fallbackForRedis = AppwriteURL::unparse([ - 'scheme' => 'redis', - 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => App::getEnv('_APP_REDIS_USER', ''), - 'pass' => App::getEnv('_APP_REDIS_PASS', ''), - ]); - - $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); - $dsns = explode(',', $connection ?? ''); - - if (empty($dsns)) { - throw new Exception(Exception::GENERAL_SERVER_ERROR); - } - - $dsn = explode('=', $dsns[0]); - $dsn = $dsn[1] ?? ''; - $dsn = new DSN($dsn); - $client = new SyncIn('syncIn', new QueueRedis($dsn->getHost(), $dsn->getPort())); + $client = new SyncIn('syncIn', $pools->get('queue')->pop()->getResource()); $client->enqueue(['value' => ['keys' => $keys]]); diff --git a/app/init.php b/app/init.php index 3c97c1f2d0..4c38024e5a 100644 --- a/app/init.php +++ b/app/init.php @@ -77,6 +77,7 @@ use MaxMind\Db\Reader; use PHPMailer\PHPMailer\PHPMailer; use Swoole\Database\PDOProxy; +use Utopia\Queue; const APP_NAME = 'Appwrite'; const APP_DOMAIN = 'appwrite.io'; @@ -526,30 +527,35 @@ function (mixed $value) { 'dsns' => App::getEnv('_APP_CONNECTIONS_DB_CONSOLE', $fallbackForDB), 'multiple' => false, 'schemes' => ['mariadb', 'mysql'], + 'useResource' => true, ], 'database' => [ 'type' => 'database', 'dsns' => App::getEnv('_APP_CONNECTIONS_DB_PROJECT', $fallbackForDB), 'multiple' => true, 'schemes' => ['mariadb', 'mysql'], + 'useResource' => true, + ], + 'queue' => [ + 'type' => 'queue', + 'dsns' => App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), + 'multiple' => false, + 'schemes' => ['redis'], + 'useResource' => false, ], -// 'queue' => [ -// 'type' => 'queue', -// 'dsns' => App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), -// 'multiple' => false, -// 'schemes' => ['redis'], -// ], 'pubsub' => [ 'type' => 'pubsub', 'dsns' => App::getEnv('_APP_CONNECTIONS_PUBSUB', $fallbackForRedis), 'multiple' => false, 'schemes' => ['redis'], + 'useResource' => true, ], 'cache' => [ 'type' => 'cache', 'dsns' => App::getEnv('_APP_CONNECTIONS_CACHE', $fallbackForRedis), 'multiple' => true, 'schemes' => ['redis'], + 'useResource' => true, ], ]; @@ -558,6 +564,7 @@ function (mixed $value) { $dsns = $connection['dsns'] ?? ''; $multipe = $connection['multiple'] ?? false; $schemes = $connection['schemes'] ?? []; + $useResource = $connection['useResource'] ?? true; $config = []; $dsns = explode(',', $connection['dsns'] ?? ''); @@ -580,7 +587,7 @@ function (mixed $value) { $dsnScheme = $dsn->getScheme(); $dsnDatabase = $dsn->getDatabase(); - if (!in_array($dsnScheme, $schemes)) { + if (!in_array($dsnScheme, $schemes) && $useResource) { throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid console database scheme"); } @@ -643,9 +650,12 @@ function (mixed $value) { case 'pubsub': break; $adapter = $resource(); -// case 'queue': -// $adapter = $resource(); -// break; + case 'queue': + $adapter = match ($dsn->getScheme()) { + 'redis' => new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()), + default => 'bla' + }; + break; case 'cache': $adapter = match ($dsn->getScheme()) { 'redis' => new RedisCache($resource()), @@ -667,12 +677,6 @@ function (mixed $value) { Config::setParam('pools-' . $key, $config); } - try { - $group->fill(); - } catch (\Throwable $th) { - Console::error('Connection failure: ' . $th->getMessage()); - } - return $group; }); diff --git a/app/tasks/sync-edge.php b/app/tasks/sync-edge.php index 3310704ffa..102d5ca2a2 100644 --- a/app/tasks/sync-edge.php +++ b/app/tasks/sync-edge.php @@ -19,36 +19,17 @@ Console::title('Syncs edges V1'); Console::success(APP_NAME . ' Sync failed cache purge process v1 has started'); - $fallbackForRedis = AppwriteURL::unparse([ - 'scheme' => 'redis', - 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => App::getEnv('_APP_REDIS_USER', ''), - 'pass' => App::getEnv('_APP_REDIS_PASS', ''), - ]); - - $connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); - $dsns = explode(',', $connection ?? ''); - - if (empty($dsns)) { - Console::error("No Dsn found"); - } - - $dsn = explode('=', $dsns[0]); - $dsn = $dsn[1] ?? ''; - $dsn = new DSN($dsn); - $redisConnection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); - $client = new SyncOut('syncOut', $redisConnection); - + $pools = $register->get('pools'); + $client = new SyncOut('syncOut', $pools->get('queue')->pop()->getResource()); + $database = getConsoleDB(); // Todo fix pdo PDOException // Table 'appwrite.console__metadata' doesn't exist sleep(4); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $register, $client) { + Console::loop(function () use ($interval, $database, $register, $client) { - $database = getConsoleDB(); $time = DateTime::now(); $count = 0; $chunk = 0; diff --git a/app/worker.php b/app/worker.php index f705636bf8..d2668f6417 100644 --- a/app/worker.php +++ b/app/worker.php @@ -2,9 +2,7 @@ require_once __DIR__ . '/init.php'; -use Appwrite\DSN\DSN; -use Appwrite\Extend\Exception; -use Appwrite\URL\URL as AppwriteURL; + use Swoole\Runtime; use Utopia\App; use Utopia\Cache\Adapter\Sharding; @@ -13,11 +11,11 @@ use Utopia\Database\Database; use Utopia\Queue\Server; use Utopia\Registry\Registry; -use Utopia\Queue; + global $register; -Runtime::enableCoroutine(SWOOLE_HOOK_ALL); + Server::setResource('register', fn() => $register); @@ -56,26 +54,14 @@ }, ['register']); -// Todo better job to inject the client as a resource -$fallbackForRedis = AppwriteURL::unparse([ - 'scheme' => 'redis', - 'host' => App::getEnv('_APP_REDIS_HOST', 'redis'), - 'port' => App::getEnv('_APP_REDIS_PORT', '6379'), - 'user' => App::getEnv('_APP_REDIS_USER', ''), - 'pass' => App::getEnv('_APP_REDIS_PASS', ''), -]); +$pools = $register->get('pools'); +$client = $pools + ->get('queue') + ->pop() + ->getResource(); -$connection = App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis); -$dsns = explode(',', $connection ?? ''); -if (empty($dsns)) { - throw new Exception(Exception::GENERAL_SERVER_ERROR); -} - -$dsn = explode('=', $dsns[0]); -$dsn = $dsn[1] ?? ''; -$dsn = new DSN($dsn); - -$redisConnection = new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()); $workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); $workerNumber = 1; + +Runtime::enableCoroutine(SWOOLE_HOOK_ALL); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 2df457083a..e359a954e4 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -10,10 +10,10 @@ use Utopia\Queue; use Utopia\Queue\Message; -global $redisConnection; +global $client; global $workerNumber; -$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncIn'); +$adapter = new Queue\Adapter\Swoole($client, $workerNumber, 'syncIn'); $server = new Queue\Server($adapter); $server->job() @@ -44,12 +44,12 @@ if ($error->getCode() >= 500 || $error->getCode() === 0) { $log = new Log(); - $log->setNamespace("worker"); + $log->setNamespace("appwrite-worker"); $log->setServer(\gethostname()); $log->setVersion($version); $log->setType(Log::TYPE_ERROR); $log->setMessage($error->getMessage()); - $log->setAction('worker-sync-out'); + $log->setAction('appwrite-worker-sync-out'); $log->addTag('verboseType', get_class($error)); $log->addTag('code', $error->getCode()); $log->addExtra('file', $error->getFile()); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 8c36cbe808..564e39e0d7 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -17,7 +17,7 @@ use Utopia\Queue; use Utopia\Queue\Message; -global $redisConnection; +global $client; global $workerNumber; $regions = array_filter( @@ -103,7 +103,7 @@ function handle($dbForConsole, $regions, $stack): void } } -$adapter = new Queue\Adapter\Swoole($redisConnection, $workerNumber, 'syncOut'); +$adapter = new Queue\Adapter\Swoole($client, $workerNumber, 'syncOut'); $server = new Queue\Server($adapter); $server->job() @@ -149,12 +149,12 @@ function handle($dbForConsole, $regions, $stack): void if ($error->getCode() >= 500 || $error->getCode() === 0) { $log = new Log(); - $log->setNamespace("worker"); + $log->setNamespace("appwrite-worker"); $log->setServer(\gethostname()); $log->setVersion($version); $log->setType(Log::TYPE_ERROR); $log->setMessage($error->getMessage()); - $log->setAction('worker-sync-out'); + $log->setAction('appwrite-worker-sync-out'); $log->addTag('verboseType', get_class($error)); $log->addTag('code', $error->getCode()); $log->addExtra('file', $error->getFile()); diff --git a/composer.json b/composer.json index 110e44ca9d..d2fef924fe 100644 --- a/composer.json +++ b/composer.json @@ -62,7 +62,7 @@ "utopia-php/image": "0.5.*", "utopia-php/orchestration": "0.6.*", "utopia-php/queue": "0.4.0", - "utopia-php/pools": "0.1.*", + "utopia-php/pools": "dev-upgrade-cli as 0.2.0", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", "dragonmantank/cron-expression": "3.3.1", diff --git a/composer.lock b/composer.lock index 2aa790ead4..d39044963f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a02c3502dca5a3a9f0f283e06e11e30e", + "content-hash": "88fa95b378e538da3ff62fe81bf76bc1", "packages": [ { "name": "adhocore/jwt", @@ -2431,23 +2431,24 @@ }, { "name": "utopia-php/pools", - "version": "0.1.0", + "version": "dev-upgrade-cli", "source": { "type": "git", "url": "https://github.com/utopia-php/pools.git", - "reference": "5a467a569a80aefc846a97dc195b4adc2fd71805" + "reference": "88a2c1ed2badbfdf2787ce0a12def2c988fc1097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/5a467a569a80aefc846a97dc195b4adc2fd71805", - "reference": "5a467a569a80aefc846a97dc195b4adc2fd71805", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/88a2c1ed2badbfdf2787ce0a12def2c988fc1097", + "reference": "88a2c1ed2badbfdf2787ce0a12def2c988fc1097", "shasum": "" }, "require": { "ext-mongodb": "*", "ext-pdo": "*", "ext-redis": "*", - "php": ">=8.0" + "php": ">=8.0", + "utopia-php/cli": "0.13.*" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -2478,9 +2479,9 @@ ], "support": { "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/0.1.0" + "source": "https://github.com/utopia-php/pools/tree/upgrade-cli" }, - "time": "2022-10-11T19:31:07+00:00" + "time": "2022-11-04T08:33:04+00:00" }, { "name": "utopia-php/preloader", @@ -5469,12 +5470,19 @@ "version": "dev-feat-update-cache-lib", "alias": "0.26.1", "alias_normalized": "0.26.1.0" + }, + { + "package": "utopia-php/pools", + "version": "dev-upgrade-cli", + "alias": "0.2.0", + "alias_normalized": "0.2.0.0" } ], "minimum-stability": "stable", "stability-flags": { "utopia-php/cache": 20, - "utopia-php/database": 20 + "utopia-php/database": 20, + "utopia-php/pools": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/docker-compose.yml b/docker-compose.yml index 97d85b2413..df87436ae8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -280,6 +280,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/pools:/usr/src/code/vendor/utopia-php/pools depends_on: - mariadb - redis From 9ac55e88061914c1fd81789368a10cc643704a4b Mon Sep 17 00:00:00 2001 From: shimon Date: Fri, 4 Nov 2022 18:11:59 +0200 Subject: [PATCH 27/87] pools::queue client injection --- app/worker.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/worker.php b/app/worker.php index d2668f6417..eaef650d99 100644 --- a/app/worker.php +++ b/app/worker.php @@ -55,10 +55,7 @@ $pools = $register->get('pools'); -$client = $pools - ->get('queue') - ->pop() - ->getResource(); +$client = $pools->get('queue')->pop()->getResource(); $workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); From 27249c236bd3dd017e1da3d02129c1b515e45017 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 17 Nov 2022 12:57:18 +0200 Subject: [PATCH 28/87] minor changes --- app/init.php | 12 +--- composer.lock | 154 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 114 insertions(+), 52 deletions(-) diff --git a/app/init.php b/app/init.php index 4c38024e5a..8d43362926 100644 --- a/app/init.php +++ b/app/init.php @@ -527,35 +527,30 @@ function (mixed $value) { 'dsns' => App::getEnv('_APP_CONNECTIONS_DB_CONSOLE', $fallbackForDB), 'multiple' => false, 'schemes' => ['mariadb', 'mysql'], - 'useResource' => true, ], 'database' => [ 'type' => 'database', 'dsns' => App::getEnv('_APP_CONNECTIONS_DB_PROJECT', $fallbackForDB), 'multiple' => true, 'schemes' => ['mariadb', 'mysql'], - 'useResource' => true, ], 'queue' => [ 'type' => 'queue', 'dsns' => App::getEnv('_APP_CONNECTIONS_QUEUE', $fallbackForRedis), 'multiple' => false, 'schemes' => ['redis'], - 'useResource' => false, ], 'pubsub' => [ 'type' => 'pubsub', 'dsns' => App::getEnv('_APP_CONNECTIONS_PUBSUB', $fallbackForRedis), 'multiple' => false, 'schemes' => ['redis'], - 'useResource' => true, ], 'cache' => [ 'type' => 'cache', 'dsns' => App::getEnv('_APP_CONNECTIONS_CACHE', $fallbackForRedis), 'multiple' => true, 'schemes' => ['redis'], - 'useResource' => true, ], ]; @@ -564,7 +559,6 @@ function (mixed $value) { $dsns = $connection['dsns'] ?? ''; $multipe = $connection['multiple'] ?? false; $schemes = $connection['schemes'] ?? []; - $useResource = $connection['useResource'] ?? true; $config = []; $dsns = explode(',', $connection['dsns'] ?? ''); @@ -587,7 +581,7 @@ function (mixed $value) { $dsnScheme = $dsn->getScheme(); $dsnDatabase = $dsn->getDatabase(); - if (!in_array($dsnScheme, $schemes) && $useResource) { + if (!in_array($dsnScheme, $schemes)) { throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid console database scheme"); } @@ -648,12 +642,12 @@ function (mixed $value) { $adapter->setDefaultDatabase($dsn->getDatabase()); break; case 'pubsub': - break; $adapter = $resource(); + break; case 'queue': $adapter = match ($dsn->getScheme()) { 'redis' => new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort()), - default => 'bla' + default => null }; break; case 'cache': diff --git a/composer.lock b/composer.lock index d39044963f..4e25d64165 100644 --- a/composer.lock +++ b/composer.lock @@ -115,15 +115,15 @@ }, { "name": "appwrite/php-runtimes", - "version": "0.11.0", + "version": "0.11.1", "source": { "type": "git", "url": "https://github.com/appwrite/runtimes.git", - "reference": "547fc026e11c0946846a8ac690898f5bf53be101" + "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" }, "require": { "php": ">=8.0", - "utopia-php/system": "0.4.*" + "utopia-php/system": "0.6.*" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -154,7 +154,7 @@ "php", "runtimes" ], - "time": "2022-08-15T14:03:36+00:00" + "time": "2022-11-07T16:45:52+00:00" }, { "name": "chillerlan/php-qrcode", @@ -300,16 +300,16 @@ }, { "name": "colinmollenhour/credis", - "version": "v1.13.1", + "version": "v1.14.0", "source": { "type": "git", "url": "https://github.com/colinmollenhour/credis.git", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49" + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/85df015088e00daf8ce395189de22c8eb45c8d49", - "reference": "85df015088e00daf8ce395189de22c8eb45c8d49", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", "shasum": "" }, "require": { @@ -341,9 +341,9 @@ "homepage": "https://github.com/colinmollenhour/credis", "support": { "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.13.1" + "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" }, - "time": "2022-06-20T22:56:59+00:00" + "time": "2022-11-09T01:18:39+00:00" }, { "name": "composer/package-versions-deprecated", @@ -931,6 +931,72 @@ }, "time": "2021-02-04T16:20:16+00:00" }, + { + "name": "laravel/pint", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", + "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11.0", + "illuminate/view": "^9.27", + "laravel-zero/framework": "^9.1.3", + "mockery/mockery": "^1.5.0", + "nunomaduro/larastan": "^2.2", + "nunomaduro/termwind": "^1.14.0", + "pestphp/pest": "^1.22.1" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2022-09-13T15:07:15+00:00" + }, { "name": "matomo/device-detector", "version": "6.0.0", @@ -1658,16 +1724,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -1676,7 +1742,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1721,7 +1787,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -1737,7 +1803,7 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "utopia-php/abuse", @@ -2762,23 +2828,25 @@ }, { "name": "utopia-php/system", - "version": "0.4.0", + "version": "0.6.0", "source": { "type": "git", "url": "https://github.com/utopia-php/system.git", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0" + "reference": "289c4327713deadc9c748b5317d248133a02f245" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/67c92c66ce8f0cc925a00bca89f7a188bf9183c0", - "reference": "67c92c66ce8f0cc925a00bca89f7a188bf9183c0", + "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", + "reference": "289c4327713deadc9c748b5317d248133a02f245", "shasum": "" }, "require": { + "laravel/pint": "1.2.*", "php": ">=7.4" }, "require-dev": { "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", "vimeo/psalm": "4.0.1" }, "type": "library", @@ -2811,9 +2879,9 @@ ], "support": { "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.4.0" + "source": "https://github.com/utopia-php/system/tree/0.6.0" }, - "time": "2021-02-04T14:14:49+00:00" + "time": "2022-11-07T13:51:59+00:00" }, { "name": "utopia-php/websocket", @@ -3237,16 +3305,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", "shasum": "" }, "require": { @@ -3287,9 +3355,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-11-12T15:38:23+00:00" }, { "name": "phar-io/manifest", @@ -5119,16 +5187,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -5143,7 +5211,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5181,7 +5249,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -5197,20 +5265,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -5225,7 +5293,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5264,7 +5332,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -5280,7 +5348,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "textalk/websocket", From 3f0fcb40d06fe0c06e4fa8a15ee75d0bf12279b2 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 17 Nov 2022 18:00:18 +0200 Subject: [PATCH 29/87] adopt changes from db-pools --- Dockerfile | 2 +- app/controllers/api/edge.php | 12 +- app/init.php | 19 +- app/workers/sync-In.php | 6 +- app/workers/sync-out.php | 5 +- bin/edge-sync | 3 + bin/sync-edge | 3 - bin/worker-sync-in | 2 +- bin/worker-sync-out | 2 +- composer.json | 6 +- composer.lock | 5579 ----------------- docker-compose.yml | 6 +- src/Appwrite/Event/Func.php | 3 - .../Tasks/{sync-edge.php => EdgeSync.php} | 6 +- 14 files changed, 33 insertions(+), 5621 deletions(-) create mode 100644 bin/edge-sync delete mode 100644 bin/sync-edge delete mode 100644 composer.lock rename src/Appwrite/Platform/Tasks/{sync-edge.php => EdgeSync.php} (93%) diff --git a/Dockerfile b/Dockerfile index f8cc68c622..119a103e71 100755 --- a/Dockerfile +++ b/Dockerfile @@ -322,7 +322,7 @@ RUN mkdir -p /storage/uploads && \ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/maintenance && \ chmod +x /usr/local/bin/volume-sync && \ - chmod +x /usr/local/bin/sync-edge && \ + chmod +x /usr/local/bin/edge-sync && \ chmod +x /usr/local/bin/usage && \ chmod +x /usr/local/bin/install && \ chmod +x /usr/local/bin/migrate && \ diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 353befb83e..396f2f29ef 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -2,15 +2,12 @@ use Ahc\Jwt\JWT; use Ahc\Jwt\JWTException; -use Appwrite\DSN\DSN; use Appwrite\Extend\Exception; -use Appwrite\URL\URL as AppwriteURL; use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; use Utopia\Database\Document; -use Utopia\Pools\Group; -use Utopia\Queue\Client as SyncIn; +use Utopia\Queue\Client; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; @@ -37,15 +34,14 @@ ->inject('request') ->inject('response') ->inject('pools') - ->action(function (array $keys, Request $request, Response $response, Group $pools) { + ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncOut) { if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); } - $client = new SyncIn('syncIn', $pools->get('queue')->pop()->getResource()); - - $client->enqueue(['value' => ['keys' => $keys]]); + $queueForCacheSyncOut + ->enqueue(['value' => ['keys' => $keys]]); $response->dynamic(new Document([ 'keys' => $keys diff --git a/app/init.php b/app/init.php index 14be293c21..8c0e979e21 100644 --- a/app/init.php +++ b/app/init.php @@ -40,6 +40,7 @@ use Appwrite\Usage\Stats; use Appwrite\Utopia\View; use Utopia\App; +use Utopia\Queue\Client; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Database\ID; @@ -864,6 +865,12 @@ function (mixed $value) { App::setResource('queueForFunctions', function (Group $pools) { return new Func($pools->get('queue')->pop()->getResource()); }, ['pools']); +App::setResource('queueForCacheSyncOut', function (Group $pools) { + return new Client('v1-sync-out', $pools->get('queue')->pop()->getResource()); +}, ['pools']); +App::setResource('queueForCacheSyncIn', function (Group $pools) { + return new Client('v1-sync-in', $pools->get('queue')->pop()->getResource()); +}, ['pools']); App::setResource('usage', function ($register) { return new Stats($register->get('statsd')); }, ['register']); @@ -1075,7 +1082,7 @@ function (mixed $value) { return $database; }, ['pools', 'cache']); -App::setResource('cache', function (Group $pools) { +App::setResource('cache', function (Group $pools, Client $queueForCacheSyncOut) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -1088,22 +1095,20 @@ function (mixed $value) { } $cache = new Cache(new Sharding($adapters)); - $client = new SyncOut('syncOut', new QueueRedis(App::getEnv('_APP_REDIS_HOST', 'redis'), App::getEnv('_APP_REDIS_PORT', '6379'))); - - $cache->on(cache::EVENT_SAVE, function ($key) use ($client) { + $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForCacheSyncOut) { //Todo fix cache re-invoked if ($key === 'cache-console:_metadata:users') { return; } - $client + $queueForCacheSyncOut ->enqueue(['value' => ['key' => $key]]); }); - $cache->on(cache::EVENT_PURGE, function ($key) use ($client) { + $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { if ($key === 'cache-console:_metadata:users') { return; } - $client + $queueForCacheSyncOut ->enqueue(['value' => ['key' => $key]]); }); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index e359a954e4..60ccea9a23 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -10,10 +10,10 @@ use Utopia\Queue; use Utopia\Queue\Message; -global $client; +global $connection; global $workerNumber; -$adapter = new Queue\Adapter\Swoole($client, $workerNumber, 'syncIn'); +$adapter = new Queue\Adapter\Swoole($connection, $workerNumber, 'syncIn'); $server = new Queue\Server($adapter); $server->job() @@ -23,10 +23,12 @@ $time = DateTime::now(); $payload = $message->getPayload()['value']; $cache->setDisableListeners(true); + foreach ($payload['keys'] ?? [] as $key) { Console::info("[{$time}] Purging {$key}"); $cache->purge($key); } + $cache->setDisableListeners(false); }); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 564e39e0d7..3458ca5b38 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -17,7 +17,7 @@ use Utopia\Queue; use Utopia\Queue\Message; -global $client; +global $connection; global $workerNumber; $regions = array_filter( @@ -103,9 +103,6 @@ function handle($dbForConsole, $regions, $stack): void } } -$adapter = new Queue\Adapter\Swoole($client, $workerNumber, 'syncOut'); -$server = new Queue\Server($adapter); - $server->job() ->inject('message') ->action(function (Message $message) use (&$stack, &$failures) { diff --git a/bin/edge-sync b/bin/edge-sync new file mode 100644 index 0000000000..b1ffc7647a --- /dev/null +++ b/bin/edge-sync @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php edge-sync $@ \ No newline at end of file diff --git a/bin/sync-edge b/bin/sync-edge deleted file mode 100644 index 5ff317eff5..0000000000 --- a/bin/sync-edge +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php /usr/src/code/app/cli.php sync-edge $@ \ No newline at end of file diff --git a/bin/worker-sync-in b/bin/worker-sync-in index 0f38627454..cb688ff7f1 100644 --- a/bin/worker-sync-in +++ b/bin/worker-sync-in @@ -1,3 +1,3 @@ #!/bin/sh -php /usr/src/code/app/workers/sync-in.php $@ \ No newline at end of file +QUEUE=v1-sync-in php /usr/src/code/app/workers/sync-in.php $@ \ No newline at end of file diff --git a/bin/worker-sync-out b/bin/worker-sync-out index 4c076fd25c..2ab76cbfcd 100644 --- a/bin/worker-sync-out +++ b/bin/worker-sync-out @@ -1,3 +1,3 @@ #!/bin/sh -php /usr/src/code/app/workers/sync-out.php $@ \ No newline at end of file +QUEUE=v1-sync-out php /usr/src/code/app/workers/sync-out.php $@ \ No newline at end of file diff --git a/composer.json b/composer.json index e61011b3d4..c52dba0263 100644 --- a/composer.json +++ b/composer.json @@ -46,11 +46,8 @@ "utopia-php/abuse": "0.16.*", "utopia-php/analytics": "0.2.*", "utopia-php/audit": "0.17.*", - "utopia-php/cache": "0.8.*", - "utopia-php/cli": "0.14.*", - "utopia-php/audit": "0.15.*", "utopia-php/cache": "dev-feat-redis-sync as 0.8.1", - "utopia-php/cli": "0.13.*", + "utopia-php/cli": "0.14.*", "utopia-php/config": "0.2.*", "utopia-php/database": "0.28.*", "utopia-php/domains": "1.1.*", @@ -67,6 +64,7 @@ "utopia-php/storage": "0.11.*", "utopia-php/swoole": "0.5.*", "utopia-php/websocket": "0.1.0", + "utopia-php/dsn": "0.1.0", "resque/php-resque": "1.3.6", "matomo/device-detector": "6.0.0", "dragonmantank/cron-expression": "3.3.1", diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 4e25d64165..0000000000 --- a/composer.lock +++ /dev/null @@ -1,5579 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "88fa95b378e538da3ff62fe81bf76bc1", - "packages": [ - { - "name": "adhocore/jwt", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/adhocore/php-jwt.git", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ahc\\Jwt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jitendra Adhikari", - "email": "jiten.adhikary@gmail.com" - } - ], - "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", - "keywords": [ - "auth", - "json-web-token", - "jwt", - "jwt-auth", - "jwt-php", - "token" - ], - "support": { - "issues": "https://github.com/adhocore/php-jwt/issues", - "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" - }, - "funding": [ - { - "url": "https://paypal.me/ji10", - "type": "custom" - } - ], - "time": "2021-02-20T09:56:44+00:00" - }, - { - "name": "appwrite/php-clamav", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/php-clamav.git", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", - "shasum": "" - }, - "require": { - "ext-sockets": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\ClamAV\\": "src/ClamAV" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "ClamAV network and pipe client for PHP", - "keywords": [ - "anti virus", - "appwrite", - "clamav", - "php" - ], - "support": { - "issues": "https://github.com/appwrite/php-clamav/issues", - "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" - }, - "time": "2020-10-02T05:23:46+00:00" - }, - { - "name": "appwrite/php-runtimes", - "version": "0.11.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/runtimes.git", - "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" - }, - "require": { - "php": ">=8.0", - "utopia-php/system": "0.6.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\Runtimes\\": "src/Runtimes" - } - }, - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", - "keywords": [ - "appwrite", - "php", - "runtimes" - ], - "time": "2022-11-07T16:45:52+00:00" - }, - { - "name": "chillerlan/php-qrcode", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", - "shasum": "" - }, - "require": { - "chillerlan/php-settings-container": "^2.1", - "ext-mbstring": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5", - "setasign/fpdf": "^1.8.2" - }, - "suggest": { - "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", - "setasign/fpdf": "Required to use the QR FPDF output." - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\QRCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" - }, - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - }, - { - "name": "Contributors", - "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" - } - ], - "description": "A QR code generator. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-qrcode", - "keywords": [ - "phpqrcode", - "qr", - "qr code", - "qrcode", - "qrcode-generator" - ], - "support": { - "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2021-11-25T22:38:09+00:00" - }, - { - "name": "chillerlan/php-settings-container", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\Settings\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - } - ], - "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-settings-container", - "keywords": [ - "PHP7", - "Settings", - "configuration", - "container", - "helper" - ], - "support": { - "issues": "https://github.com/chillerlan/php-settings-container/issues", - "source": "https://github.com/chillerlan/php-settings-container" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2022-07-05T22:32:14+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "v1.14.0", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "suggest": { - "ext-redis": "Improved performance for communicating with redis" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php", - "Module.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "support": { - "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" - }, - "time": "2022-11-09T01:18:39+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.5", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d", - "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.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": "2022-01-17T14:14:24+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2022-01-18T15:43:28+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", - "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.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "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 - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "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.5.0" - }, - "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": "2022-08-28T15:39:27+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "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/1.5.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2022-08-28T14:55:35+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.4.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "67c26b443f348a51926030c83481b85718457d3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", - "reference": "67c26b443f348a51926030c83481b85718457d3d", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.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.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "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.4.3" - }, - "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": "2022-10-26T14:07:24+00:00" - }, - { - "name": "influxdb/influxdb-php", - "version": "1.15.2", - "source": { - "type": "git", - "url": "https://github.com/influxdata/influxdb-php.git", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0|^7.0", - "php": "^5.5 || ^7.0 || ^8.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.2.1", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "Curl extension, needed for Curl driver", - "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." - }, - "type": "library", - "autoload": { - "psr-4": { - "InfluxDB\\": "src/InfluxDB" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Hoogendijk", - "email": "stephen@tca0.nl" - }, - { - "name": "Daniel Martinez", - "email": "danimartcas@hotmail.com" - }, - { - "name": "Gianluca Arbezzano", - "email": "gianarb92@gmail.com" - } - ], - "description": "InfluxDB client library for PHP", - "keywords": [ - "client", - "influxdata", - "influxdb", - "influxdb class", - "influxdb client", - "influxdb library", - "time series" - ], - "support": { - "issues": "https://github.com/influxdata/influxdb-php/issues", - "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" - }, - "time": "2020-12-26T17:45:17+00:00" - }, - { - "name": "jean85/pretty-package-versions", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303", - "reference": "1e0104b46f045868f11942aea058cd7186d6c303", - "shasum": "" - }, - "require": { - "composer/package-versions-deprecated": "^1.8.0", - "php": "^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0|^8.5|^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A wrapper for ocramius/package-versions to get pretty versions strings", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0" - }, - "time": "2021-02-04T16:20:16+00:00" - }, - { - "name": "laravel/pint", - "version": "v1.2.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.27", - "laravel-zero/framework": "^9.1.3", - "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.2", - "nunomaduro/termwind": "^1.14.0", - "pestphp/pest": "^1.22.1" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", - "keywords": [ - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2022-09-13T15:07:15+00:00" - }, - { - "name": "matomo/device-detector", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/matomo-org/device-detector.git", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", - "shasum": "" - }, - "require": { - "mustangostang/spyc": "*", - "php": "^7.2|^8.0" - }, - "replace": { - "piwik/device-detector": "self.version" - }, - "require-dev": { - "matthiasmullie/scrapbook": "^1.4.7", - "mayflower/mo4-coding-standard": "^v8.0.0", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5.8", - "psr/cache": "^1.0.1", - "psr/simple-cache": "^1.0.1", - "symfony/yaml": "^5.1.7" - }, - "suggest": { - "doctrine/cache": "Can directly be used for caching purpose", - "ext-yaml": "Necessary for using the Pecl YAML parser" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeviceDetector\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "The Matomo Team", - "email": "hello@matomo.org", - "homepage": "https://matomo.org/team/" - } - ], - "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", - "homepage": "https://matomo.org", - "keywords": [ - "devicedetection", - "parser", - "useragent" - ], - "support": { - "forum": "https://forum.matomo.org/", - "issues": "https://github.com/matomo-org/device-detector/issues", - "source": "https://github.com/matomo-org/matomo", - "wiki": "https://dev.matomo.org/" - }, - "time": "2022-04-11T09:58:17+00:00" - }, - { - "name": "mongodb/mongodb", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/mongodb/mongo-php-library.git", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d", - "reference": "953dbc19443aa9314c44b7217a16873347e6840d", - "shasum": "" - }, - "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mongodb": "^1.8.1", - "jean85/pretty-package-versions": "^1.2", - "php": "^7.0 || ^8.0", - "symfony/polyfill-php80": "^1.19" - }, - "require-dev": { - "squizlabs/php_codesniffer": "^3.5, <3.5.5", - "symfony/phpunit-bridge": "5.x-dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "MongoDB\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Andreas Braun", - "email": "andreas.braun@mongodb.com" - }, - { - "name": "Jeremy Mikola", - "email": "jmikola@gmail.com" - } - ], - "description": "MongoDB driver library", - "homepage": "https://jira.mongodb.org/browse/PHPLIB", - "keywords": [ - "database", - "driver", - "mongodb", - "persistence" - ], - "support": { - "issues": "https://github.com/mongodb/mongo-php-library/issues", - "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0" - }, - "time": "2020-11-25T12:26:02+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "git@github.com:mustangostang/spyc.git", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2019-09-10T13:16:29+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.2", - "yoast/phpunit-polyfills": "^1.0.0" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2022-02-28T15:31:21+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20: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": "resque/php-resque", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/resque/php-resque.git", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "~1.7", - "php": ">=5.6.0", - "psr/log": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "suggest": { - "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", - "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", - "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." - }, - "bin": [ - "bin/resque", - "bin/resque-scheduler" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Resque": "lib", - "ResqueScheduler": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dan Hunsaker", - "email": "danhunsaker+resque@gmail.com", - "role": "Maintainer" - }, - { - "name": "Rajib Ahmed", - "homepage": "https://github.com/rajibahmed", - "role": "Maintainer" - }, - { - "name": "Steve Klabnik", - "email": "steve@steveklabnik.com", - "role": "Maintainer" - }, - { - "name": "Chris Boulton", - "email": "chris@bigcommerce.com", - "role": "Creator" - } - ], - "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", - "homepage": "http://www.github.com/resque/php-resque/", - "keywords": [ - "background", - "job", - "redis", - "resque" - ], - "support": { - "issues": "https://github.com/resque/php-resque/issues", - "source": "https://github.com/resque/php-resque/tree/v1.3.6" - }, - "time": "2020-04-16T16:39:50+00:00" - }, - { - "name": "slickdeals/statsd", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/Slickdeals/statsd-php.git", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", - "shasum": "" - }, - "require": { - "php": ">= 7.3 || ^8" - }, - "replace": { - "domnikl/statsd": "self.version" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Domnikl\\Statsd\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dominik Liebler", - "email": "liebler.dominik@gmail.com" - } - ], - "description": "a PHP client for statsd", - "homepage": "https://github.com/Slickdeals/statsd-php", - "keywords": [ - "Metrics", - "monitoring", - "statistics", - "statsd", - "udp" - ], - "support": { - "issues": "https://github.com/Slickdeals/statsd-php/issues", - "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" - }, - "time": "2021-06-04T20:33:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-02-25T11:15:52+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "utopia-php/abuse", - "version": "0.14.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "1a5da248e74c1bfc39bc440fa949de6935acceeb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/1a5da248e74c1bfc39bc440fa949de6935acceeb", - "reference": "1a5da248e74c1bfc39bc440fa949de6935acceeb", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.26.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Abuse\\": "src/Abuse" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple abuse library to manage application usage limits", - "keywords": [ - "Abuse", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.14.0" - }, - "time": "2022-10-14T11:26:39+00:00" - }, - { - "name": "utopia-php/analytics", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/analytics.git", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Analytics\\": "src/Analytics" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library to track events & users.", - "keywords": [ - "analytics", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.2.0" - }, - "time": "2021-03-23T21:33:07+00:00" - }, - { - "name": "utopia-php/audit", - "version": "0.15.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/audit.git", - "reference": "937ffd13e7a5ac9ad220b329247569ef2a4881d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/937ffd13e7a5ac9ad220b329247569ef2a4881d9", - "reference": "937ffd13e7a5ac9ad220b329247569ef2a4881d9", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.26.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Audit\\": "src/Audit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple audit library to manage application users logs", - "keywords": [ - "Audit", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.15.0" - }, - "time": "2022-10-14T11:39:18+00:00" - }, - { - "name": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cache.git", - "reference": "c29179055def7827b27fde979cefe07c3e4858da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/c29179055def7827b27fde979cefe07c3e4858da", - "reference": "c29179055def7827b27fde979cefe07c3e4858da", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-memcached": "*", - "ext-redis": "*", - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Cache\\": "src/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple cache library to manage application cache storing, loading and purging", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" - }, - "time": "2022-10-27T14:35:59+00:00" - }, - { - "name": "utopia-php/cli", - "version": "0.13.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cli.git", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/69e68f8ed525fe162fae950a0507ed28a0f179bc", - "reference": "69e68f8ed525fe162fae950a0507ed28a0f179bc", - "shasum": "" - }, - "require": { - "php": ">=7.4", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\CLI\\": "src/CLI" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple CLI library to manage command line applications", - "keywords": [ - "cli", - "command line", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.13.0" - }, - "time": "2022-04-26T08:41:22+00:00" - }, - { - "name": "utopia-php/config", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/config.git", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Config\\": "src/Config" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Config library to managing application config variables", - "keywords": [ - "config", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/config/issues", - "source": "https://github.com/utopia-php/config/tree/0.2.2" - }, - "time": "2020-10-24T09:49:09+00:00" - }, - { - "name": "utopia-php/database", - "version": "dev-feat-update-cache-lib", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "44ae47dfd49c9c7c0cba29f6867347e25c23b57b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/44ae47dfd49c9c7c0cba29f6867347e25c23b57b", - "reference": "44ae47dfd49c9c7c0cba29f6867347e25c23b57b", - "shasum": "" - }, - "require": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "mongodb/mongodb": "1.8.0", - "php": ">=8.0", - "utopia-php/cache": "0.8.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "fakerphp/faker": "^1.14", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.11.0", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Database\\": "src/Database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library to manage application persistency using multiple database adapters", - "keywords": [ - "database", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/feat-update-cache-lib" - }, - "time": "2022-10-16T17:35:26+00:00" - }, - { - "name": "utopia-php/domains", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Domains\\": "src/Domains" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "domains", - "framework", - "icann", - "php", - "public suffix", - "tld", - "tld extract", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/master" - }, - "time": "2020-02-23T07:40:02+00:00" - }, - { - "name": "utopia-php/framework", - "version": "0.21.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/c81789b87a917da2daf336738170ebe01f50ea18", - "reference": "c81789b87a917da2daf336738170ebe01f50ea18", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.10", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.21.1" - }, - "time": "2022-09-07T09:56:28+00:00" - }, - { - "name": "utopia-php/image", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/image.git", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", - "shasum": "" - }, - "require": { - "ext-imagick": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Image\\": "src/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Image manipulation library", - "keywords": [ - "framework", - "image", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.4" - }, - "time": "2022-05-11T12:30:41+00:00" - }, - { - "name": "utopia-php/locale", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/locale.git", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Locale\\": "src/Locale" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple locale library to manage application translations", - "keywords": [ - "framework", - "locale", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/locale/issues", - "source": "https://github.com/utopia-php/locale/tree/0.4.0" - }, - "time": "2021-07-24T11:35:55+00:00" - }, - { - "name": "utopia-php/logger", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Logger\\": "src/Logger" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], - "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "appsignal", - "errors", - "framework", - "logger", - "logging", - "logs", - "php", - "raygun", - "sentry", - "upf", - "utopia", - "warnings" - ], - "support": { - "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" - }, - "time": "2022-03-18T10:56:57+00:00" - }, - { - "name": "utopia-php/orchestration", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/orchestration.git", - "reference": "94263976413871efb6b16157a7101a81df3b6d78" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/94263976413871efb6b16157a7101a81df3b6d78", - "reference": "94263976413871efb6b16157a7101a81df3b6d78", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.13.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Orchestration\\": "src/Orchestration" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Lite & fast micro PHP abstraction library for container orchestration", - "keywords": [ - "docker", - "framework", - "kubernetes", - "orchestration", - "php", - "swarm", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.6.0" - }, - "time": "2022-07-13T16:47:18+00:00" - }, - { - "name": "utopia-php/pools", - "version": "dev-upgrade-cli", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/pools.git", - "reference": "88a2c1ed2badbfdf2787ce0a12def2c988fc1097" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/88a2c1ed2badbfdf2787ce0a12def2c988fc1097", - "reference": "88a2c1ed2badbfdf2787ce0a12def2c988fc1097", - "shasum": "" - }, - "require": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "php": ">=8.0", - "utopia-php/cli": "0.13.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Pools\\": "src/Pools" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Team Appwrite", - "email": "team@appwrite.io" - } - ], - "description": "A simple library to manage connection pools", - "keywords": [ - "framework", - "php", - "pools", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/upgrade-cli" - }, - "time": "2022-11-04T08:33:04+00:00" - }, - { - "name": "utopia-php/preloader", - "version": "0.2.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/preloader.git", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Preloader\\": "src/Preloader" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", - "keywords": [ - "framework", - "php", - "preload", - "preloader", - "preloading", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/preloader/issues", - "source": "https://github.com/utopia-php/preloader/tree/0.2.4" - }, - "time": "2020-10-24T07:04:59+00:00" - }, - { - "name": "utopia-php/queue", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/queue.git", - "reference": "0cad4cf4231377aa6c67956b51ba1954e0d02166" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/0cad4cf4231377aa6c67956b51ba1954e0d02166", - "reference": "0cad4cf4231377aa6c67956b51ba1954e0d02166", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.13.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "laravel/pint": "^0.2.3", - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.8.8", - "workerman/workerman": "^4.0" - }, - "suggest": { - "ext-swoole": "Needed to support Swoole.", - "workerman/workerman": "Needed to support Workerman." - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Queue\\": "src/Queue" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A powerful task queue.", - "keywords": [ - "Tasks", - "framework", - "php", - "queue", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.4.0" - }, - "time": "2022-10-31T06:23:08+00:00" - }, - { - "name": "utopia-php/registry", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/registry.git", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Registry\\": "src/Registry" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple dependency management library for PHP", - "keywords": [ - "dependency management", - "di", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/registry/issues", - "source": "https://github.com/utopia-php/registry/tree/0.5.0" - }, - "time": "2021-03-10T10:45:22+00:00" - }, - { - "name": "utopia-php/storage", - "version": "0.11.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/storage.git", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-zlib": "*", - "ext-zstd": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Storage\\": "src/Storage" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Storage library to manage application storage", - "keywords": [ - "framework", - "php", - "storage", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.11.0" - }, - "time": "2022-08-31T09:17:31+00:00" - }, - { - "name": "utopia-php/swoole", - "version": "0.3.3", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/swoole.git", - "reference": "8312df69233b5dcd3992de88f131f238002749de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/8312df69233b5dcd3992de88f131f238002749de", - "reference": "8312df69233b5dcd3992de88f131f238002749de", - "shasum": "" - }, - "require": { - "ext-swoole": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "swoole/ide-helper": "4.8.3", - "vimeo/psalm": "4.15.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Swoole\\": "src/Swoole" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", - "keywords": [ - "framework", - "http", - "php", - "server", - "swoole", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.3.3" - }, - "time": "2022-01-20T09:58:43+00:00" - }, - { - "name": "utopia-php/system", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/system.git", - "reference": "289c4327713deadc9c748b5317d248133a02f245" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", - "reference": "289c4327713deadc9c748b5317d248133a02f245", - "shasum": "" - }, - "require": { - "laravel/pint": "1.2.*", - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\System\\": "src/System" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library for obtaining information about the host's system.", - "keywords": [ - "framework", - "php", - "system", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.6.0" - }, - "time": "2022-11-07T13:51:59+00:00" - }, - { - "name": "utopia-php/websocket", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/websocket.git", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.6.6", - "textalk/websocket": "1.5.2", - "vimeo/psalm": "^4.8.1", - "workerman/workerman": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\WebSocket\\": "src/WebSocket" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple abstraction for WebSocket servers.", - "keywords": [ - "framework", - "php", - "upf", - "utopia", - "websocket" - ], - "support": { - "issues": "https://github.com/utopia-php/websocket/issues", - "source": "https://github.com/utopia-php/websocket/tree/0.1.0" - }, - "time": "2021-12-20T10:50:09+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "appwrite/sdk-generator", - "version": "0.28.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "matthiasmullie/minify": "^1.3.68", - "php": ">=7.0.0", - "twig/twig": "^3.4.1" - }, - "require-dev": { - "brianium/paratest": "^6.4", - "phpunit/phpunit": "^9.5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\SDK\\": "src/SDK", - "Appwrite\\Spec\\": "src/Spec" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "support": { - "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" - }, - "time": "2022-09-22T09:15:54+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "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.22" - }, - "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.4.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%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.69", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" - }, - "funding": [ - { - "url": "https://github.com/matthiasmullie", - "type": "github" - } - ], - "time": "2022-08-01T09:00:18+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" - }, - "time": "2022-11-12T15:38:23+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.18", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-10-27T13:35:33+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library 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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "swoole/ide-helper", - "version": "4.8.9", - "source": { - "type": "git", - "url": "https://github.com/swoole/ide-helper.git", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "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/4.8.9" - }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-04-18T20:38:04+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.7", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" - }, - "time": "2022-03-29T09:46:59+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "twig/twig", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "time": "2022-09-28T08:42:51+00:00" - } - ], - "aliases": [ - { - "package": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "alias": "0.8.1", - "alias_normalized": "0.8.1.0" - }, - { - "package": "utopia-php/database", - "version": "dev-feat-update-cache-lib", - "alias": "0.26.1", - "alias_normalized": "0.26.1.0" - }, - { - "package": "utopia-php/pools", - "version": "dev-upgrade-cli", - "alias": "0.2.0", - "alias_normalized": "0.2.0.0" - } - ], - "minimum-stability": "stable", - "stability-flags": { - "utopia-php/cache": 20, - "utopia-php/database": 20, - "utopia-php/pools": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0.0", - "ext-curl": "*", - "ext-imagick": "*", - "ext-mbstring": "*", - "ext-json": "*", - "ext-yaml": "*", - "ext-dom": "*", - "ext-redis": "*", - "ext-swoole": "*", - "ext-pdo": "*", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-sockets": "*" - }, - "platform-dev": { - "ext-fileinfo": "*" - }, - "platform-overrides": { - "php": "8.0" - }, - "plugin-api-version": "2.2.0" -} diff --git a/docker-compose.yml b/docker-compose.yml index 374621dd14..f3dd27de07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -635,10 +635,10 @@ services: # - /nfs/config:/data/src # - /storage/config:/data/dest - appwrite-sync-edge: - entrypoint: sync-edge + appwrite-edge-sync: + entrypoint: edge-sync <<: *x-logging - container_name: appwrite-sync-edge + container_name: appwrite-edge-sync image: appwrite-dev networks: - appwrite diff --git a/src/Appwrite/Event/Func.php b/src/Appwrite/Event/Func.php index 22940ad08e..5f8b4c80c6 100644 --- a/src/Appwrite/Event/Func.php +++ b/src/Appwrite/Event/Func.php @@ -2,9 +2,6 @@ namespace Appwrite\Event; -use DateTime; -use Resque; -use ResqueScheduler; use Utopia\Database\Document; use Utopia\Queue\Client; use Utopia\Queue\Connection; diff --git a/src/Appwrite/Platform/Tasks/sync-edge.php b/src/Appwrite/Platform/Tasks/EdgeSync.php similarity index 93% rename from src/Appwrite/Platform/Tasks/sync-edge.php rename to src/Appwrite/Platform/Tasks/EdgeSync.php index 102d5ca2a2..e5202a27c5 100644 --- a/src/Appwrite/Platform/Tasks/sync-edge.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -13,7 +13,7 @@ use Utopia\Queue\Client as SyncOut; $cli - ->task('sync-edge') + ->task('edge-sync') ->desc('Schedules edge sync tasks') ->action(function () use ($register) { Console::title('Syncs edges V1'); @@ -23,10 +23,6 @@ $client = new SyncOut('syncOut', $pools->get('queue')->pop()->getResource()); $database = getConsoleDB(); - // Todo fix pdo PDOException - // Table 'appwrite.console__metadata' doesn't exist - sleep(4); - $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); Console::loop(function () use ($interval, $database, $register, $client) { From a46e12f9ff728562dee11d573c7a21fe6042e42e Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 17 Nov 2022 18:01:04 +0200 Subject: [PATCH 30/87] adopt changes from db-pools --- composer.lock | 5362 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5362 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..7a4f8a1c43 --- /dev/null +++ b/composer.lock @@ -0,0 +1,5362 @@ +{ + "_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": "6da195b883597666fd5bd448294f1ca3", + "packages": [ + { + "name": "adhocore/jwt", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-jwt.git", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ahc\\Jwt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", + "keywords": [ + "auth", + "json-web-token", + "jwt", + "jwt-auth", + "jwt-php", + "token" + ], + "support": { + "issues": "https://github.com/adhocore/php-jwt/issues", + "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + } + ], + "time": "2021-02-20T09:56:44+00:00" + }, + { + "name": "appwrite/php-clamav", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/appwrite/php-clamav.git", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", + "shasum": "" + }, + "require": { + "ext-sockets": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\ClamAV\\": "src/ClamAV" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "ClamAV network and pipe client for PHP", + "keywords": [ + "anti virus", + "appwrite", + "clamav", + "php" + ], + "support": { + "issues": "https://github.com/appwrite/php-clamav/issues", + "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" + }, + "time": "2020-10-02T05:23:46+00:00" + }, + { + "name": "appwrite/php-runtimes", + "version": "0.11.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/runtimes.git", + "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" + }, + "require": { + "php": ">=8.0", + "utopia-php/system": "0.6.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\Runtimes\\": "src/Runtimes" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", + "keywords": [ + "appwrite", + "php", + "runtimes" + ], + "time": "2022-11-07T16:45:52+00:00" + }, + { + "name": "chillerlan/php-qrcode", + "version": "4.3.3", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-qrcode.git", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", + "shasum": "" + }, + "require": { + "chillerlan/php-settings-container": "^2.1", + "ext-mbstring": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", + "setasign/fpdf": "Required to use the QR FPDF output." + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\QRCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kazuhiko Arase", + "homepage": "https://github.com/kazuhikoarase" + }, + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + }, + { + "name": "Contributors", + "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" + } + ], + "description": "A QR code generator. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-qrcode", + "keywords": [ + "phpqrcode", + "qr", + "qr code", + "qrcode", + "qrcode-generator" + ], + "support": { + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2021-11-25T22:38:09+00:00" + }, + { + "name": "chillerlan/php-settings-container", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-settings-container.git", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\Settings\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + } + ], + "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-settings-container", + "keywords": [ + "PHP7", + "Settings", + "configuration", + "container", + "helper" + ], + "support": { + "issues": "https://github.com/chillerlan/php-settings-container/issues", + "source": "https://github.com/chillerlan/php-settings-container" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2022-07-05T22:32:14+00:00" + }, + { + "name": "colinmollenhour/credis", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "suggest": { + "ext-redis": "Improved performance for communicating with redis" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php", + "Module.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "support": { + "issues": "https://github.com/colinmollenhour/credis/issues", + "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" + }, + "time": "2022-11-09T01:18:39+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "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.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "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 + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "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.5.0" + }, + "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": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "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/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "67c26b443f348a51926030c83481b85718457d3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", + "reference": "67c26b443f348a51926030c83481b85718457d3d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.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.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "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.4.3" + }, + "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": "2022-10-26T14:07:24+00:00" + }, + { + "name": "influxdb/influxdb-php", + "version": "1.15.2", + "source": { + "type": "git", + "url": "https://github.com/influxdata/influxdb-php.git", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "Curl extension, needed for Curl driver", + "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." + }, + "type": "library", + "autoload": { + "psr-4": { + "InfluxDB\\": "src/InfluxDB" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Hoogendijk", + "email": "stephen@tca0.nl" + }, + { + "name": "Daniel Martinez", + "email": "danimartcas@hotmail.com" + }, + { + "name": "Gianluca Arbezzano", + "email": "gianarb92@gmail.com" + } + ], + "description": "InfluxDB client library for PHP", + "keywords": [ + "client", + "influxdata", + "influxdb", + "influxdb class", + "influxdb client", + "influxdb library", + "time series" + ], + "support": { + "issues": "https://github.com/influxdata/influxdb-php/issues", + "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" + }, + "time": "2020-12-26T17:45:17+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", + "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11.0", + "illuminate/view": "^9.27", + "laravel-zero/framework": "^9.1.3", + "mockery/mockery": "^1.5.0", + "nunomaduro/larastan": "^2.2", + "nunomaduro/termwind": "^1.14.0", + "pestphp/pest": "^1.22.1" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2022-09-13T15:07:15+00:00" + }, + { + "name": "matomo/device-detector", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/matomo-org/device-detector.git", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", + "shasum": "" + }, + "require": { + "mustangostang/spyc": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "piwik/device-detector": "self.version" + }, + "require-dev": { + "matthiasmullie/scrapbook": "^1.4.7", + "mayflower/mo4-coding-standard": "^v8.0.0", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8.5.8", + "psr/cache": "^1.0.1", + "psr/simple-cache": "^1.0.1", + "symfony/yaml": "^5.1.7" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeviceDetector\\": "" + }, + "exclude-from-classmap": [ + "Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "homepage": "https://matomo.org", + "keywords": [ + "devicedetection", + "parser", + "useragent" + ], + "support": { + "forum": "https://forum.matomo.org/", + "issues": "https://github.com/matomo-org/device-detector/issues", + "source": "https://github.com/matomo-org/matomo", + "wiki": "https://dev.matomo.org/" + }, + "time": "2022-04-11T09:58:17+00:00" + }, + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2019-09-10T13:16:29+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.6.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.2", + "yoast/phpunit-polyfills": "^1.0.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2022-02-28T15:31:21+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.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": "http://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/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.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": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.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": "http://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/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "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/1.1.4" + }, + "time": "2021-05-03T11:20: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": "resque/php-resque", + "version": "v1.3.6", + "source": { + "type": "git", + "url": "https://github.com/resque/php-resque.git", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "~1.7", + "php": ">=5.6.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", + "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", + "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." + }, + "bin": [ + "bin/resque", + "bin/resque-scheduler" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Resque": "lib", + "ResqueScheduler": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Hunsaker", + "email": "danhunsaker+resque@gmail.com", + "role": "Maintainer" + }, + { + "name": "Rajib Ahmed", + "homepage": "https://github.com/rajibahmed", + "role": "Maintainer" + }, + { + "name": "Steve Klabnik", + "email": "steve@steveklabnik.com", + "role": "Maintainer" + }, + { + "name": "Chris Boulton", + "email": "chris@bigcommerce.com", + "role": "Creator" + } + ], + "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", + "homepage": "http://www.github.com/resque/php-resque/", + "keywords": [ + "background", + "job", + "redis", + "resque" + ], + "support": { + "issues": "https://github.com/resque/php-resque/issues", + "source": "https://github.com/resque/php-resque/tree/v1.3.6" + }, + "time": "2020-04-16T16:39:50+00:00" + }, + { + "name": "slickdeals/statsd", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/Slickdeals/statsd-php.git", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", + "shasum": "" + }, + "require": { + "php": ">= 7.3 || ^8" + }, + "replace": { + "domnikl/statsd": "self.version" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Domnikl\\Statsd\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dominik Liebler", + "email": "liebler.dominik@gmail.com" + } + ], + "description": "a PHP client for statsd", + "homepage": "https://github.com/Slickdeals/statsd-php", + "keywords": [ + "Metrics", + "monitoring", + "statistics", + "statsd", + "udp" + ], + "support": { + "issues": "https://github.com/Slickdeals/statsd-php/issues", + "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" + }, + "time": "2021-06-04T20:33:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "utopia-php/abuse", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/abuse.git", + "reference": "6370d9150425460416583feba0990504ac789e98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6370d9150425460416583feba0990504ac789e98", + "reference": "6370d9150425460416583feba0990504ac789e98", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Abuse\\": "src/Abuse" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple abuse library to manage application usage limits", + "keywords": [ + "Abuse", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/abuse/issues", + "source": "https://github.com/utopia-php/abuse/tree/0.16.0" + }, + "time": "2022-10-31T14:46:41+00:00" + }, + { + "name": "utopia-php/analytics", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/analytics.git", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Analytics\\": "src/Analytics" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library to track events & users.", + "keywords": [ + "analytics", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/analytics/issues", + "source": "https://github.com/utopia-php/analytics/tree/0.2.0" + }, + "time": "2021-03-23T21:33:07+00:00" + }, + { + "name": "utopia-php/audit", + "version": "0.17.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/audit.git", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/455471bd4de8d74026809e843f8c9740eb32922c", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Audit\\": "src/Audit" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple audit library to manage application users logs", + "keywords": [ + "Audit", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/audit/issues", + "source": "https://github.com/utopia-php/audit/tree/0.17.0" + }, + "time": "2022-10-31T14:44:52+00:00" + }, + { + "name": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cache.git", + "reference": "c29179055def7827b27fde979cefe07c3e4858da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/c29179055def7827b27fde979cefe07c3e4858da", + "reference": "c29179055def7827b27fde979cefe07c3e4858da", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-memcached": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Cache\\": "src/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple cache library to manage application cache storing, loading and purging", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cache/issues", + "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" + }, + "time": "2022-10-27T14:35:59+00:00" + }, + { + "name": "utopia-php/cli", + "version": "0.14.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cli.git", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/c30ef985a4e739758a0d95eb0706b357b6d8c086", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\CLI\\": "src/CLI" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple CLI library to manage command line applications", + "keywords": [ + "cli", + "command line", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cli/issues", + "source": "https://github.com/utopia-php/cli/tree/0.14.0" + }, + "time": "2022-10-09T10:19:07+00:00" + }, + { + "name": "utopia-php/config", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/config.git", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Config\\": "src/Config" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Config library to managing application config variables", + "keywords": [ + "config", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/config/issues", + "source": "https://github.com/utopia-php/config/tree/0.2.2" + }, + "time": "2020-10-24T09:49:09+00:00" + }, + { + "name": "utopia-php/database", + "version": "0.28.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cache": "0.8.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "fakerphp/faker": "^1.14", + "mongodb/mongodb": "1.8.0", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "4.8.0", + "utopia-php/cli": "^0.11.0", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Database\\": "src/Database" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library to manage application persistency using multiple database adapters", + "keywords": [ + "database", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/database/issues", + "source": "https://github.com/utopia-php/database/tree/0.28.0" + }, + "time": "2022-10-31T09:58:46+00:00" + }, + { + "name": "utopia-php/domains", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/domains.git", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Domains\\": "src/Domains" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "domains", + "framework", + "icann", + "php", + "public suffix", + "tld", + "tld extract", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/domains/issues", + "source": "https://github.com/utopia-php/domains/tree/master" + }, + "time": "2020-02-23T07:40:02+00:00" + }, + { + "name": "utopia-php/dsn", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/dsn.git", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\DSN\\": "src/DSN" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library for parsing and managing Data Source Names ( DSNs )", + "keywords": [ + "dsn", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/dsn/issues", + "source": "https://github.com/utopia-php/dsn/tree/0.1.0" + }, + "time": "2022-10-26T10:06:20+00:00" + }, + { + "name": "utopia-php/framework", + "version": "0.25.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/framework.git", + "reference": "c524f681254255c8204fbf7919c53bf3b4982636" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/c524f681254255c8204fbf7919c53bf3b4982636", + "reference": "c524f681254255c8204fbf7919c53bf3b4982636", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.25", + "vimeo/psalm": "^4.27.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple, light and advanced PHP framework", + "keywords": [ + "framework", + "php", + "upf" + ], + "support": { + "issues": "https://github.com/utopia-php/framework/issues", + "source": "https://github.com/utopia-php/framework/tree/0.25.0" + }, + "time": "2022-11-02T09:49:57+00:00" + }, + { + "name": "utopia-php/image", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/image.git", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", + "shasum": "" + }, + "require": { + "ext-imagick": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Image\\": "src/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Image manipulation library", + "keywords": [ + "framework", + "image", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/image/issues", + "source": "https://github.com/utopia-php/image/tree/0.5.4" + }, + "time": "2022-05-11T12:30:41+00:00" + }, + { + "name": "utopia-php/locale", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/locale.git", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Locale\\": "src/Locale" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple locale library to manage application translations", + "keywords": [ + "framework", + "locale", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/locale/issues", + "source": "https://github.com/utopia-php/locale/tree/0.4.0" + }, + "time": "2021-07-24T11:35:55+00:00" + }, + { + "name": "utopia-php/logger", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/logger.git", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Logger\\": "src/Logger" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Matej Bačo", + "email": "matej@appwrite.io" + }, + { + "name": "Christy Jacob", + "email": "christy@appwrite.io" + } + ], + "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "appsignal", + "errors", + "framework", + "logger", + "logging", + "logs", + "php", + "raygun", + "sentry", + "upf", + "utopia", + "warnings" + ], + "support": { + "issues": "https://github.com/utopia-php/logger/issues", + "source": "https://github.com/utopia-php/logger/tree/0.3.0" + }, + "time": "2022-03-18T10:56:57+00:00" + }, + { + "name": "utopia-php/orchestration", + "version": "0.9.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/orchestration.git", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/1d4f66684b8c4927f31b695817eae6d84aafd172", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Orchestration\\": "src/Orchestration" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Lite & fast micro PHP abstraction library for container orchestration", + "keywords": [ + "docker", + "framework", + "kubernetes", + "orchestration", + "php", + "swarm", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/orchestration/issues", + "source": "https://github.com/utopia-php/orchestration/tree/0.9.0" + }, + "time": "2022-11-09T17:38:00+00:00" + }, + { + "name": "utopia-php/platform", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/platform.git", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/fe9f64420957dc8fb6201d22b499572f021411e4", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-redis": "*", + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.25.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Platform\\": "src/Platform" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Light and Fast Platform Library", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/platform/issues", + "source": "https://github.com/utopia-php/platform/tree/0.3.1" + }, + "time": "2022-11-10T07:04:24+00:00" + }, + { + "name": "utopia-php/pools", + "version": "0.4.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/pools.git", + "reference": "c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979", + "reference": "c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.8.*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Pools\\": "src/Pools" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Team Appwrite", + "email": "team@appwrite.io" + } + ], + "description": "A simple library to manage connection pools", + "keywords": [ + "framework", + "php", + "pools", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/pools/issues", + "source": "https://github.com/utopia-php/pools/tree/0.4.1" + }, + "time": "2022-11-15T08:55:16+00:00" + }, + { + "name": "utopia-php/preloader", + "version": "0.2.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/preloader.git", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Preloader\\": "src/Preloader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "team@appwrite.io" + } + ], + "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", + "keywords": [ + "framework", + "php", + "preload", + "preloader", + "preloading", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/preloader/issues", + "source": "https://github.com/utopia-php/preloader/tree/0.2.4" + }, + "time": "2020-10-24T07:04:59+00:00" + }, + { + "name": "utopia-php/queue", + "version": "0.4.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/queue.git", + "reference": "0b69ede484a04c567cbb202f592d8e5e3cd2433e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/0b69ede484a04c567cbb202f592d8e5e3cd2433e", + "reference": "0b69ede484a04c567cbb202f592d8e5e3cd2433e", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "^0.2.3", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.8.8", + "workerman/workerman": "^4.0" + }, + "suggest": { + "ext-swoole": "Needed to support Swoole.", + "workerman/workerman": "Needed to support Workerman." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Queue\\": "src/Queue" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A powerful task queue.", + "keywords": [ + "Tasks", + "framework", + "php", + "queue", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/queue/issues", + "source": "https://github.com/utopia-php/queue/tree/0.4.1" + }, + "time": "2022-11-15T16:56:37+00:00" + }, + { + "name": "utopia-php/registry", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/registry.git", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Registry\\": "src/Registry" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple dependency management library for PHP", + "keywords": [ + "dependency management", + "di", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/registry/issues", + "source": "https://github.com/utopia-php/registry/tree/0.5.0" + }, + "time": "2021-03-10T10:45:22+00:00" + }, + { + "name": "utopia-php/storage", + "version": "0.11.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/storage.git", + "reference": "59802cf281d1976560cf6e353f250a9b870efddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", + "reference": "59802cf281d1976560cf6e353f250a9b870efddc", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-zlib": "*", + "ext-zstd": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Storage\\": "src/Storage" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Storage library to manage application storage", + "keywords": [ + "framework", + "php", + "storage", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/storage/issues", + "source": "https://github.com/utopia-php/storage/tree/0.11.0" + }, + "time": "2022-08-31T09:17:31+00:00" + }, + { + "name": "utopia-php/swoole", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/swoole.git", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "shasum": "" + }, + "require": { + "ext-swoole": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "swoole/ide-helper": "4.8.3", + "vimeo/psalm": "4.15.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Swoole\\": "src/Swoole" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", + "keywords": [ + "framework", + "http", + "php", + "server", + "swoole", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/swoole/issues", + "source": "https://github.com/utopia-php/swoole/tree/0.5.0" + }, + "time": "2022-10-19T22:19:07+00:00" + }, + { + "name": "utopia-php/system", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/system.git", + "reference": "289c4327713deadc9c748b5317d248133a02f245" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", + "reference": "289c4327713deadc9c748b5317d248133a02f245", + "shasum": "" + }, + "require": { + "laravel/pint": "1.2.*", + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\System\\": "src/System" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library for obtaining information about the host's system.", + "keywords": [ + "framework", + "php", + "system", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/system/issues", + "source": "https://github.com/utopia-php/system/tree/0.6.0" + }, + "time": "2022-11-07T13:51:59+00:00" + }, + { + "name": "utopia-php/websocket", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/websocket.git", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.6.6", + "textalk/websocket": "1.5.2", + "vimeo/psalm": "^4.8.1", + "workerman/workerman": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\WebSocket\\": "src/WebSocket" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple abstraction for WebSocket servers.", + "keywords": [ + "framework", + "php", + "upf", + "utopia", + "websocket" + ], + "support": { + "issues": "https://github.com/utopia-php/websocket/issues", + "source": "https://github.com/utopia-php/websocket/tree/0.1.0" + }, + "time": "2021-12-20T10:50:09+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "appwrite/sdk-generator", + "version": "0.28.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/sdk-generator.git", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "matthiasmullie/minify": "^1.3.68", + "php": ">=7.0.0", + "twig/twig": "^3.4.1" + }, + "require-dev": { + "brianium/paratest": "^6.4", + "phpunit/phpunit": "^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\SDK\\": "src/SDK", + "Appwrite\\Spec\\": "src/Spec" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", + "support": { + "issues": "https://github.com/appwrite/sdk-generator/issues", + "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" + }, + "time": "2022-09-22T09:15:54+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "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.22" + }, + "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.4.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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.69", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", + "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.0", + "matthiasmullie/scrapbook": "dev-master", + "phpunit/phpunit": ">=4.8" + }, + "suggest": { + "psr/cache-implementation": "Cache implementation to use with Minify::cache" + }, + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", + "homepage": "http://www.minifier.org", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2022-08-01T09:00:18+00:00" + }, + { + "name": "matthiasmullie/path-converter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/path-converter.git", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\PathConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "pathconverter@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Relative path converter", + "homepage": "http://github.com/matthiasmullie/path-converter", + "keywords": [ + "converter", + "path", + "paths", + "relative" + ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, + "time": "2019-02-05T23:41:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + }, + "time": "2022-11-12T15:38:23+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.18", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", + "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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 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", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-10-27T13:35:33+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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 calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "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", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "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/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library 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/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "4.8.9", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "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/4.8.9" + }, + "funding": [ + { + "url": "https://gitee.com/swoole/swoole?donate=true", + "type": "custom" + }, + { + "url": "https://github.com/swoole", + "type": "github" + } + ], + "time": "2022-04-18T20:38:04+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "textalk/websocket", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/Textalk/websocket-php.git", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "shasum": "" + }, + "require": { + "php": "^7.2 | ^8.0", + "psr/log": "^1 | ^2 | ^3" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "soren@abicart.se" + } + ], + "description": "WebSocket client and server", + "support": { + "issues": "https://github.com/Textalk/websocket-php/issues", + "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" + }, + "time": "2022-03-29T09:46:59+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "twig/twig", + "version": "v3.4.3", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2022-09-28T08:42:51+00:00" + } + ], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "alias": "0.8.1", + "alias_normalized": "0.8.1.0" + } + ], + "minimum-stability": "stable", + "stability-flags": { + "utopia-php/cache": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0.0", + "ext-curl": "*", + "ext-imagick": "*", + "ext-mbstring": "*", + "ext-json": "*", + "ext-yaml": "*", + "ext-dom": "*", + "ext-redis": "*", + "ext-swoole": "*", + "ext-pdo": "*", + "ext-openssl": "*", + "ext-zlib": "*", + "ext-sockets": "*" + }, + "platform-dev": { + "ext-fileinfo": "*" + }, + "platform-overrides": { + "php": "8.0" + }, + "plugin-api-version": "2.2.0" +} From 7de0897335e64fd0c7948e86ab305061ac3abd9a Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 17 Nov 2022 19:56:24 +0200 Subject: [PATCH 31/87] adopt changes from db-pools --- app/cli.php | 5 +++ app/controllers/api/edge.php | 2 +- app/init.php | 12 +++--- docker-compose.yml | 2 + src/Appwrite/Platform/Services/Tasks.php | 4 +- src/Appwrite/Platform/Tasks/EdgeSync.php | 53 ++++++++++++++---------- 6 files changed, 49 insertions(+), 29 deletions(-) diff --git a/app/cli.php b/app/cli.php index c7e5b98157..7c83b63a68 100644 --- a/app/cli.php +++ b/app/cli.php @@ -17,6 +17,7 @@ use Utopia\Database\Document; use Utopia\Logger\Log; use Utopia\Pools\Group; +use Utopia\Queue\Client; use Utopia\Registry\Registry; Authorization::disable(); @@ -114,6 +115,10 @@ return new Func($pools->get('queue')->pop()->getResource()); }, ['pools']); +CLI::setResource('queueForCacheSyncOut', function (Group $pools) { + return new Client('v1-sync-out', $pools->get('queue')->pop()->getResource()); +}, ['pools']); + CLI::setResource('logError', function (Registry $register) { return function (Throwable $error, string $namespace, string $action) use ($register) { $logger = $register->get('logger'); diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 396f2f29ef..91b8cf06dc 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -33,7 +33,7 @@ ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') - ->inject('pools') + ->inject('queueForCacheSyncOut') ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncOut) { if (empty($keys)) { diff --git a/app/init.php b/app/init.php index 8c0e979e21..a10086c10e 100644 --- a/app/init.php +++ b/app/init.php @@ -595,7 +595,7 @@ function (mixed $value) { $dsnUser = $dsn->getUser(); $dsnPass = $dsn->getPassword(); $dsnScheme = $dsn->getScheme(); - $dsnDatabase = $dsn->getDatabase(); + $dsnPath = $dsn->getPath(); if (!in_array($dsnScheme, $schemes)) { throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid console database scheme"); @@ -612,9 +612,9 @@ function (mixed $value) { switch ($dsnScheme) { case 'mysql': case 'mariadb': - $resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { - return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { - return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase};charset=utf8mb4", $dsnUser, $dsnPass, array( + $resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnPath) { + return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnPath) { + return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnPath};charset=utf8mb4", $dsnUser, $dsnPass, array( PDO::ATTR_TIMEOUT => 3, // Seconds PDO::ATTR_PERSISTENT => true, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, @@ -655,7 +655,7 @@ function (mixed $value) { default => null }; - $adapter->setDefaultDatabase($dsn->getDatabase()); + $adapter->setDefaultDatabase($dsn->getPath()); break; case 'pubsub': $adapter = $resource(); @@ -1113,7 +1113,7 @@ function (mixed $value) { }); return $cache; -}, ['pools']); +}, ['pools', 'queueForCacheSyncOut']); App::setResource('deviceLocal', function () { return new Local(); diff --git a/docker-compose.yml b/docker-compose.yml index f3dd27de07..8bd0a4d8c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -645,6 +645,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - ./vendor/utopia-php/cli:/usr/src/code/vendor/utopia-php/cli depends_on: - mariadb - redis @@ -665,6 +666,7 @@ services: - _APP_CONNECTIONS_CACHE - _APP_CONNECTIONS_QUEUE - _APP_REGION + - _APP_WORKER_PER_CORE appwrite-usage-timeseries: entrypoint: diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index 2968a66b95..915cc34618 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -15,6 +15,7 @@ use Appwrite\Platform\Tasks\Vars; use Appwrite\Platform\Tasks\Version; use Appwrite\Platform\Tasks\VolumeSync; +use Appwrite\Platform\Tasks\EdgeSync; class Tasks extends Service { @@ -33,6 +34,7 @@ public function __construct() ->addAction(Migrate::getName(), new Migrate()) ->addAction(SDKs::getName(), new SDKs()) ->addAction(VolumeSync::getName(), new VolumeSync()) - ->addAction(Specs::getName(), new Specs()); + ->addAction(Specs::getName(), new Specs()) + ->addAction(EdgeSync::getName(), new EdgeSync()); } } diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index e5202a27c5..086477d803 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -1,30 +1,40 @@ task('edge-sync') - ->desc('Schedules edge sync tasks') - ->action(function () use ($register) { - Console::title('Syncs edges V1'); - Console::success(APP_NAME . ' Sync failed cache purge process v1 has started'); +class EdgeSync extends Action +{ + public static function getName(): string + { + return 'edge-sync'; + } - $pools = $register->get('pools'); - $client = new SyncOut('syncOut', $pools->get('queue')->pop()->getResource()); - $database = getConsoleDB(); + public function __construct() + { + $this + ->desc('Schedules edge sync tasks') + ->inject('pools') + ->inject('dbForConsole') + ->inject('queueForCacheSyncOut') + ->callback(fn (Group $pools, Database $dbForConsole, Client $queueForCacheSyncOut) => $this->action($pools, $dbForConsole, $queueForCacheSyncOut)); + } + + public function action(Group $pools, Database $dbForConsole, Client $queueForCacheSyncOut): void + { + Console::title('Edge-sync V1'); + Console::success(APP_NAME . ' Edge-sync v1 has started'); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $database, $register, $client) { + Console::loop(function () use ($interval, $dbForConsole, $queueForCacheSyncOut) { $time = DateTime::now(); $count = 0; @@ -37,7 +47,7 @@ while ($sum === $limit) { $chunk++; - $results = $database->find('syncs', [ + $results = $dbForConsole->find('syncs', [ Query::equal('region', [App::getEnv('_APP_REGION')]), Query::limit($limit) ]); @@ -46,7 +56,7 @@ if ($sum > 0) { foreach ($results as $document) { Console::info("[{$time}] Enqueueing keys chunk {$count} to {$document->getAttribute('target')}"); - $client + $queueForCacheSyncOut ->enqueue([ 'value' => [ 'region' => $document->getAttribute('target'), @@ -54,12 +64,13 @@ ] ]); - $database->deleteDocument('syncs', $document->getId()); + $dbForConsole->deleteDocument('syncs', $document->getId()); $count++; } } else { Console::info("[{$time}] No cache keys where found."); } } - }, $interval); - }); + }, $interval); + } +} From 770190437659049e9f2b3d7147cae58926a45ae2 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 20 Nov 2022 10:41:17 +0200 Subject: [PATCH 32/87] adopt changes from db-pools --- app/controllers/api/edge.php | 10 +++-- app/init.php | 8 +++- app/worker.php | 2 + app/workers/sync-In.php | 51 ++---------------------- app/workers/sync-out.php | 51 +----------------------- src/Appwrite/Platform/Tasks/EdgeSync.php | 2 - 6 files changed, 19 insertions(+), 105 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 91b8cf06dc..b04c26972e 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -33,15 +33,17 @@ ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') - ->inject('queueForCacheSyncOut') - ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncOut) { + ->inject('queueForCacheSyncIn') + ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncIn) { if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); } - $queueForCacheSyncOut - ->enqueue(['value' => ['keys' => $keys]]); + $queueForCacheSyncIn + ->enqueue([ + 'keys' => $keys + ]); $response->dynamic(new Document([ 'keys' => $keys diff --git a/app/init.php b/app/init.php index a10086c10e..2833130957 100644 --- a/app/init.php +++ b/app/init.php @@ -1101,7 +1101,9 @@ function (mixed $value) { return; } $queueForCacheSyncOut - ->enqueue(['value' => ['key' => $key]]); + ->enqueue([ + 'key' => $key + ]); }); $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { @@ -1109,7 +1111,9 @@ function (mixed $value) { return; } $queueForCacheSyncOut - ->enqueue(['value' => ['key' => $key]]); + ->enqueue([ + 'key' => $key + ]); }); return $cache; diff --git a/app/worker.php b/app/worker.php index 42a5f92439..050d352caa 100644 --- a/app/worker.php +++ b/app/worker.php @@ -101,6 +101,8 @@ throw new Exception('Please configure "QUEUE" environemnt variable.'); } + +$workerNumber =1; $adapter = new Swoole($connection, $workerNumber, App::getEnv('QUEUE')); $server = new Server($adapter); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 60ccea9a23..4eab3be337 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -6,72 +6,27 @@ use Utopia\Cache\Cache; use Utopia\CLI\Console; use Utopia\Database\DateTime; -use Utopia\Logger\Log; -use Utopia\Queue; use Utopia\Queue\Message; global $connection; global $workerNumber; -$adapter = new Queue\Adapter\Swoole($connection, $workerNumber, 'syncIn'); -$server = new Queue\Server($adapter); - $server->job() ->inject('message') ->inject('cache') ->action(function (Message $message, Cache $cache) { $time = DateTime::now(); - $payload = $message->getPayload()['value']; + $cache->setDisableListeners(true); - foreach ($payload['keys'] ?? [] as $key) { - Console::info("[{$time}] Purging {$key}"); + foreach ($message->getPayload()['keys'] ?? [] as $key) { + Console::log("[{$time}] Purging {$key}"); $cache->purge($key); } $cache->setDisableListeners(false); }); -$server - ->error() - ->inject('error') - ->inject('logger') - ->action(function ($error, $logger) { - $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); - - if ($error instanceof PDOException) { - throw $error; - } - - if ($error->getCode() >= 500 || $error->getCode() === 0) { - $log = new Log(); - - $log->setNamespace("appwrite-worker"); - $log->setServer(\gethostname()); - $log->setVersion($version); - $log->setType(Log::TYPE_ERROR); - $log->setMessage($error->getMessage()); - $log->setAction('appwrite-worker-sync-out'); - $log->addTag('verboseType', get_class($error)); - $log->addTag('code', $error->getCode()); - $log->addExtra('file', $error->getFile()); - $log->addExtra('line', $error->getLine()); - $log->addExtra('trace', $error->getTraceAsString()); - $log->addExtra('detailedTrace', $error->getTrace()); - $log->addExtra('roles', \Utopia\Database\Validator\Authorization::$roles); - - $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; - $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); - - $logger->addLog($log); - } - - Console::error('[Error] Type: ' . get_class($error)); - Console::error('[Error] Message: ' . $error->getMessage()); - Console::error('[Error] File: ' . $error->getFile()); - Console::error('[Error] Line: ' . $error->getLine()); - }); - $server ->workerStart() ->action(function () { diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 3458ca5b38..12f8db3aa0 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -13,8 +13,6 @@ use Utopia\Database\Document; use Utopia\Database\Exception\Authorization; use Utopia\Database\Exception\Structure; -use Utopia\Logger\Log; -use Utopia\Queue; use Utopia\Queue\Message; global $connection; @@ -107,7 +105,7 @@ function handle($dbForConsole, $regions, $stack): void ->inject('message') ->action(function (Message $message) use (&$stack, &$failures) { - $payload = $message->getPayload()['value'] ?? []; + $payload = $message->getPayload() ?? []; if (!empty($payload['keys'])) { $regions = array_filter( @@ -129,51 +127,6 @@ function handle($dbForConsole, $regions, $stack): void } }); -$server - ->error() - ->inject('error') - ->inject('logger') - ->inject('register') - ->action(function ($error, $logger, $register) { - - // Todo better job of abstracting the error log - $version = App::getEnv('_APP_VERSION', 'UNKNOWN'); - - if ($error instanceof PDOException) { - throw $error; - } - - if ($error->getCode() >= 500 || $error->getCode() === 0) { - $log = new Log(); - - $log->setNamespace("appwrite-worker"); - $log->setServer(\gethostname()); - $log->setVersion($version); - $log->setType(Log::TYPE_ERROR); - $log->setMessage($error->getMessage()); - $log->setAction('appwrite-worker-sync-out'); - $log->addTag('verboseType', get_class($error)); - $log->addTag('code', $error->getCode()); - $log->addExtra('file', $error->getFile()); - $log->addExtra('line', $error->getLine()); - $log->addExtra('trace', $error->getTraceAsString()); - $log->addExtra('detailedTrace', $error->getTrace()); - $log->addExtra('roles', \Utopia\Database\Validator\Authorization::$roles); - - $isProduction = App::getEnv('_APP_ENV', 'development') === 'production'; - $log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING); - - $logger->addLog($log); - } - - Console::error('[Error] Type: ' . get_class($error)); - Console::error('[Error] Message: ' . $error->getMessage()); - Console::error('[Error] File: ' . $error->getFile()); - Console::error('[Error] Line: ' . $error->getLine()); - - $register->get('pools')->reclaim(); - }); - $server ->workerStart() ->inject('dbForConsole') @@ -200,7 +153,7 @@ function handle($dbForConsole, $regions, $stack): void $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS); array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); - Console::info("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); + Console::log("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); handle($dbForConsole, $stack['regions'], $chunk); $chunk = []; }); diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index 086477d803..db2ba03924 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -58,10 +58,8 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac Console::info("[{$time}] Enqueueing keys chunk {$count} to {$document->getAttribute('target')}"); $queueForCacheSyncOut ->enqueue([ - 'value' => [ 'region' => $document->getAttribute('target'), 'keys' => $document->getAttribute('keys') - ] ]); $dbForConsole->deleteDocument('syncs', $document->getId()); From 0201509c71977e4465a1dc7f44e89327b6e79037 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 20 Nov 2022 11:15:13 +0200 Subject: [PATCH 33/87] adopt changes from db-pools --- app/init.php | 6 +++--- docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/init.php b/app/init.php index bdec7b7174..20f53375fb 100644 --- a/app/init.php +++ b/app/init.php @@ -606,9 +606,9 @@ function (mixed $value) { switch ($dsnScheme) { case 'mysql': case 'mariadb': - $resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnPath) { - return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnPath) { - return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnPath};charset=utf8mb4", $dsnUser, $dsnPass, array( + $resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { + return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) { + return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase};charset=utf8mb4", $dsnUser, $dsnPass, array( PDO::ATTR_TIMEOUT => 3, // Seconds PDO::ATTR_PERSISTENT => true, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, diff --git a/docker-compose.yml b/docker-compose.yml index ec08019703..cbc43ece58 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -655,7 +655,7 @@ services: - _APP_CONNECTIONS_QUEUE - _APP_REGION - _APP_WORKER_PER_CORE - - + appwrite-usage: entrypoint: usage <<: *x-logging From 1e968bda14ad4f49c1f3cfc7c80f1e14b7b953eb Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 20 Nov 2022 13:26:29 +0200 Subject: [PATCH 34/87] adopt changes from db-pools --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index cbc43ece58..3e3b6b3415 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -93,6 +93,7 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev + #- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb - redis @@ -300,6 +301,8 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + #- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache + depends_on: - redis environment: From 8e6961a4ddce3ffece3a3e1ae05d67047d271354 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 19 Dec 2022 11:20:06 +0200 Subject: [PATCH 35/87] benchmarks --- composer.lock | 189 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 123 insertions(+), 66 deletions(-) diff --git a/composer.lock b/composer.lock index 7a4f8a1c43..ffa458e4ac 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6da195b883597666fd5bd448294f1ca3", + "content-hash": "59d0516a8c80ed60993bf0b8d000a16b", "packages": [ { "name": "adhocore/jwt", @@ -801,20 +801,21 @@ "issues": "https://github.com/influxdata/influxdb-php/issues", "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" }, + "abandoned": true, "time": "2020-12-26T17:45:17+00:00" }, { "name": "laravel/pint", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", "shasum": "" }, "require": { @@ -826,10 +827,10 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.27", - "laravel-zero/framework": "^9.1.3", - "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.2", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", "nunomaduro/termwind": "^1.14.0", "pestphp/pest": "^1.22.1" }, @@ -867,7 +868,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2022-09-13T15:07:15+00:00" + "time": "2022-11-29T16:25:20+00:00" }, { "name": "matomo/device-detector", @@ -1461,16 +1462,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", "shasum": "" }, "require": { @@ -1479,7 +1480,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1508,7 +1509,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" }, "funding": [ { @@ -1524,7 +1525,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "utopia-php/abuse", @@ -1992,24 +1993,25 @@ }, { "name": "utopia-php/framework", - "version": "0.25.0", + "version": "0.25.1", "source": { "type": "git", "url": "https://github.com/utopia-php/framework.git", - "reference": "c524f681254255c8204fbf7919c53bf3b4982636" + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/c524f681254255c8204fbf7919c53bf3b4982636", - "reference": "c524f681254255c8204fbf7919c53bf3b4982636", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0", + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0", "shasum": "" }, "require": { "php": ">=8.0.0" }, "require-dev": { + "laravel/pint": "^1.2", "phpunit/phpunit": "^9.5.25", - "vimeo/psalm": "^4.27.0" + "vimeo/psalm": "4.27.0" }, "type": "library", "autoload": { @@ -2029,9 +2031,9 @@ ], "support": { "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.25.0" + "source": "https://github.com/utopia-php/framework/tree/0.25.1" }, - "time": "2022-11-02T09:49:57+00:00" + "time": "2022-11-23T18:22:23+00:00" }, { "name": "utopia-php/image", @@ -2202,6 +2204,60 @@ }, "time": "2022-03-18T10:56:57+00:00" }, + { + "name": "utopia-php/messaging", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/messaging.git", + "reference": "501272fad666f06bec8f130076862e7981a73f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", + "reference": "501272fad666f06bec8f130076862e7981a73f8c", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=8.0.0" + }, + "require-dev": { + "phpmailer/phpmailer": "6.6.*", + "phpunit/phpunit": "9.5.*", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Messaging\\": "src/Utopia/Messaging" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jake Barnby", + "email": "jake@appwrite.io" + } + ], + "description": "A simple, light and advanced PHP messaging library", + "keywords": [ + "library", + "messaging", + "php", + "upf", + "utopia", + "utopia-php" + ], + "support": { + "issues": "https://github.com/utopia-php/messaging/issues", + "source": "https://github.com/utopia-php/messaging/tree/0.1.0" + }, + "time": "2022-09-29T11:22:48+00:00" + }, { "name": "utopia-php/orchestration", "version": "0.9.0", @@ -2302,16 +2358,16 @@ }, { "name": "utopia-php/pools", - "version": "0.4.1", + "version": "0.4.2", "source": { "type": "git", "url": "https://github.com/utopia-php/pools.git", - "reference": "c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979" + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979", - "reference": "c8f96a33e7fbf58c1145eb6cf0f2c00cbe319979", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/d2870ab74b31b7f4027799f082e85122154f8bed", + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed", "shasum": "" }, "require": { @@ -2347,9 +2403,9 @@ ], "support": { "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/0.4.1" + "source": "https://github.com/utopia-php/pools/tree/0.4.2" }, - "time": "2022-11-15T08:55:16+00:00" + "time": "2022-11-22T07:55:45+00:00" }, { "name": "utopia-php/preloader", @@ -2406,16 +2462,16 @@ }, { "name": "utopia-php/queue", - "version": "0.4.1", + "version": "0.5.1", "source": { "type": "git", "url": "https://github.com/utopia-php/queue.git", - "reference": "0b69ede484a04c567cbb202f592d8e5e3cd2433e" + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/0b69ede484a04c567cbb202f592d8e5e3cd2433e", - "reference": "0b69ede484a04c567cbb202f592d8e5e3cd2433e", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/4b39e1f232b2e619b0d7fb4004f2356df334ddc1", + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1", "shasum": "" }, "require": { @@ -2461,9 +2517,9 @@ ], "support": { "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.4.1" + "source": "https://github.com/utopia-php/queue/tree/0.5.1" }, - "time": "2022-11-15T16:56:37+00:00" + "time": "2022-11-16T19:47:26+00:00" }, { "name": "utopia-php/registry", @@ -2519,16 +2575,16 @@ }, { "name": "utopia-php/storage", - "version": "0.11.0", + "version": "0.13.1", "source": { "type": "git", "url": "https://github.com/utopia-php/storage.git", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc" + "reference": "f19a200af5323e3bd933807b8f55a585fc96ce07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc", - "reference": "59802cf281d1976560cf6e353f250a9b870efddc", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/f19a200af5323e3bd933807b8f55a585fc96ce07", + "reference": "f19a200af5323e3bd933807b8f55a585fc96ce07", "shasum": "" }, "require": { @@ -2568,9 +2624,9 @@ ], "support": { "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.11.0" + "source": "https://github.com/utopia-php/storage/tree/0.13.1" }, - "time": "2022-08-31T09:17:31+00:00" + "time": "2022-12-09T09:15:29+00:00" }, { "name": "utopia-php/swoole", @@ -2920,16 +2976,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.69", + "version": "1.3.70", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f" + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a61c949cccd086808063611ef9698eabe42ef22f", - "reference": "a61c949cccd086808063611ef9698eabe42ef22f", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", "shasum": "" }, "require": { @@ -2938,9 +2994,10 @@ "php": ">=5.3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.0", - "matthiasmullie/scrapbook": "dev-master", - "phpunit/phpunit": ">=4.8" + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" }, "suggest": { "psr/cache-implementation": "Cache implementation to use with Minify::cache" @@ -2963,12 +3020,12 @@ { "name": "Matthias Mullie", "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", + "homepage": "https://www.mullie.eu", "role": "Developer" } ], "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "http://www.minifier.org", + "homepage": "https://github.com/matthiasmullie/minify", "keywords": [ "JS", "css", @@ -2978,7 +3035,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.69" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" }, "funding": [ { @@ -2986,7 +3043,7 @@ "type": "github" } ], - "time": "2022-08-01T09:00:18+00:00" + "time": "2022-12-09T12:56:44+00:00" }, { "name": "matthiasmullie/path-converter", @@ -3434,21 +3491,21 @@ }, { "name": "phpspec/prophecy", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" @@ -3495,22 +3552,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2022-11-29T15:06:56+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.18", + "version": "9.2.22", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a" + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/12fddc491826940cf9b7e88ad9664cf51f0f6d0a", - "reference": "12fddc491826940cf9b7e88ad9664cf51f0f6d0a", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df", + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df", "shasum": "" }, "require": { @@ -3566,7 +3623,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.18" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22" }, "funding": [ { @@ -3574,7 +3631,7 @@ "type": "github" } ], - "time": "2022-10-27T13:35:33+00:00" + "time": "2022-12-18T16:40:55+00:00" }, { "name": "phpunit/php-file-iterator", From f0380ef4f27ed00101196dfae58a6e4f4d813b74 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 19 Dec 2022 20:08:41 +0200 Subject: [PATCH 36/87] benchmarks --- app/console | 2 +- app/init.php | 14 +++++++------- app/workers/sync-In.php | 3 --- app/workers/sync-out.php | 5 +---- docker-compose.yml | 6 ++++++ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/console b/app/console index 43891a526e..b1a81a390a 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit 43891a526e061454617cbb13def3c4901d99a7f1 +Subproject commit b1a81a390a05746701651fca49e0d853f430677c diff --git a/app/init.php b/app/init.php index 09a1062d47..86c7ebaa63 100644 --- a/app/init.php +++ b/app/init.php @@ -1093,10 +1093,10 @@ function (mixed $value) { $cache = new Cache(new Sharding($adapters)); $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForCacheSyncOut) { - //Todo fix cache re-invoked - if ($key === 'cache-console:_metadata:users') { - return; - } +// //Todo fix cache re-invoked +// if ($key === 'cache-console:_metadata:users') { +// return; +// } $queueForCacheSyncOut ->enqueue([ 'key' => $key @@ -1104,9 +1104,9 @@ function (mixed $value) { }); $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { - if ($key === 'cache-console:_metadata:users') { - return; - } +// if ($key === 'cache-console:_metadata:users') { +// return; +// } $queueForCacheSyncOut ->enqueue([ 'key' => $key diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 4eab3be337..c5314ef1ed 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -8,9 +8,6 @@ use Utopia\Database\DateTime; use Utopia\Queue\Message; -global $connection; -global $workerNumber; - $server->job() ->inject('message') ->inject('cache') diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 12f8db3aa0..7601dbca2e 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -15,9 +15,6 @@ use Utopia\Database\Exception\Structure; use Utopia\Queue\Message; -global $connection; -global $workerNumber; - $regions = array_filter( Config::getParam('regions', []), fn ($region) => App::getEnv('_APP_REGION') !== $region @@ -76,7 +73,7 @@ function call(string $url, string $token, array $stack): array /** * @throws Authorization * @throws Structure - * @throws Exception + * @throws Exception|\Exception */ function handle($dbForConsole, $regions, $stack): void { diff --git a/docker-compose.yml b/docker-compose.yml index 440fd059bb..43e9f48ad2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -281,6 +281,8 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_CONNECTIONS_MAX + - _APP_POOL_CLIENTS - _APP_CONNECTIONS_DB_PROJECT - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE @@ -311,6 +313,8 @@ services: - _APP_CONNECTIONS_DB_PROJECT - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_MAX + - _APP_POOL_CLIENTS - _APP_CONNECTIONS_QUEUE - _APP_WORKER_PER_CORE - _APP_REGION @@ -667,6 +671,8 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS + - _APP_CONNECTIONS_MAX + - _APP_POOL_CLIENTS - _APP_SYNC_EDGE_INTERVAL - _APP_CONNECTIONS_DB_PROJECT - _APP_CONNECTIONS_DB_CONSOLE From b21937ca3f0704f2d0b7b1e1bbead91bed550568 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 20 Dec 2022 09:55:29 +0200 Subject: [PATCH 37/87] edge group exclude from general.php --- app/controllers/general.php | 1 + app/init.php | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 0c10dd46e9..95bece43fc 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -41,6 +41,7 @@ Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); App::init() + ->groups(['api', 'auth', 'avatars', 'functions', 'account', 'projects', 'storage', 'teams', 'users']) ->inject('utopia') ->inject('request') ->inject('response') diff --git a/app/init.php b/app/init.php index 86c7ebaa63..f57c773861 100644 --- a/app/init.php +++ b/app/init.php @@ -949,7 +949,6 @@ function (mixed $value) { if ($project->isEmpty()) { $user = new Document(['$id' => ID::custom(''), '$collection' => 'users']); } else { - //Todo fix cache save re-invoked $user = $dbForProject->getDocument('users', Auth::$unique); } } else { @@ -1093,10 +1092,6 @@ function (mixed $value) { $cache = new Cache(new Sharding($adapters)); $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForCacheSyncOut) { -// //Todo fix cache re-invoked -// if ($key === 'cache-console:_metadata:users') { -// return; -// } $queueForCacheSyncOut ->enqueue([ 'key' => $key @@ -1104,9 +1099,6 @@ function (mixed $value) { }); $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { -// if ($key === 'cache-console:_metadata:users') { -// return; -// } $queueForCacheSyncOut ->enqueue([ 'key' => $key From 1592135fabd75c6c12087644576d2b7fa714b159 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 26 Dec 2022 14:04:36 +0200 Subject: [PATCH 38/87] benchmarks --- app/workers/sync-out.php | 2 +- bin/benchmark | 3 + composer.json | 24 +- composer.lock | 5419 ----------------- phpbench.json | 17 + tests/benchmarks/Scopes/Scope.php | 14 + tests/benchmarks/Services/Databases/Base.php | 151 + .../Databases/DatabasesCustomClientBench.php | 10 + .../Databases/DatabasesCustomServerBench.php | 10 + tests/benchmarks/Services/Functions/Base.php | 113 + .../Functions/FunctionsCustomClientBench.php | 10 + .../Functions/FunctionsCustomServerBench.php | 21 + tests/benchmarks/Services/Storage/Base.php | 117 + .../Storage/StorageCustomClientBench.php | 10 + .../Storage/StorageCustomServerBench.php | 10 + .../Services/Users/UserCustomServerBench.php | 94 + tests/benchmarks/http.js | 34 - tests/benchmarks/ws.js | 59 - tests/e2e/Scopes/Scope.php | 4 +- 19 files changed, 605 insertions(+), 5517 deletions(-) create mode 100644 bin/benchmark delete mode 100644 composer.lock create mode 100644 phpbench.json create mode 100644 tests/benchmarks/Scopes/Scope.php create mode 100644 tests/benchmarks/Services/Databases/Base.php create mode 100644 tests/benchmarks/Services/Databases/DatabasesCustomClientBench.php create mode 100644 tests/benchmarks/Services/Databases/DatabasesCustomServerBench.php create mode 100644 tests/benchmarks/Services/Functions/Base.php create mode 100644 tests/benchmarks/Services/Functions/FunctionsCustomClientBench.php create mode 100644 tests/benchmarks/Services/Functions/FunctionsCustomServerBench.php create mode 100644 tests/benchmarks/Services/Storage/Base.php create mode 100644 tests/benchmarks/Services/Storage/StorageCustomClientBench.php create mode 100644 tests/benchmarks/Services/Storage/StorageCustomServerBench.php create mode 100644 tests/benchmarks/Services/Users/UserCustomServerBench.php delete mode 100644 tests/benchmarks/http.js delete mode 100644 tests/benchmarks/ws.js diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 7601dbca2e..88d9b54ab1 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -28,7 +28,7 @@ ]; $failures = []; -const CHUNK_MAX_KEYS = 2; +const CHUNK_MAX_KEYS = 500; const MAX_CURL_SEND_ATTEMPTS = 4; /** diff --git a/bin/benchmark b/bin/benchmark new file mode 100644 index 0000000000..de9bee100c --- /dev/null +++ b/bin/benchmark @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +/usr/src/code/vendor/bin/phpbench run --config /usr/src/code/phpbench.json --report appwrite $@ \ No newline at end of file diff --git a/composer.json b/composer.json index f494bb4ff5..ea2c75ef06 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,19 @@ "scripts": { "test": "vendor/bin/phpunit", "lint": "vendor/bin/phpcs", - "format": "vendor/bin/phpcbf" + "format": "vendor/bin/phpcbf", + "benchmark": [ + "Composer\\Config::disableProcessTimeout", + "vendor/bin/phpbench run --report=appwrite --" + ], + "benchmark-tag": [ + "Composer\\Config::disableProcessTimeout", + "vendor/bin/phpbench run --report=appwrite --tag=baseline --" + ], + "benchmark-compare": [ + "Composer\\Config::disableProcessTimeout", + "vendor/bin/phpbench run --report=appwrite --ref=baseline --" + ] }, "autoload": { "psr-4": { @@ -24,6 +36,7 @@ "psr-4": { "Tests\\E2E\\": "tests/e2e", "Tests\\Unit\\": "tests/unit", + "Tests\\Benchmarks\\": "tests/benchmarks", "Appwrite\\Tests\\": "tests/extensions" } }, @@ -88,7 +101,14 @@ "phpunit/phpunit": "9.5.20", "squizlabs/php_codesniffer": "^3.6", "swoole/ide-helper": "4.8.9", - "textalk/websocket": "1.5.7" + "textalk/websocket": "1.5.7", + "phpbench/phpbench": "^1.2", + + "symfony/console": "^5.0", + "symfony/filesystem": "^5.0", + "symfony/finder": "^5.0", + "symfony/options-resolver": "^5.0", + "symfony/process": "^5.0" }, "provide": { "ext-phpiredis": "*" diff --git a/composer.lock b/composer.lock deleted file mode 100644 index ffa458e4ac..0000000000 --- a/composer.lock +++ /dev/null @@ -1,5419 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "59d0516a8c80ed60993bf0b8d000a16b", - "packages": [ - { - "name": "adhocore/jwt", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/adhocore/php-jwt.git", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ahc\\Jwt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jitendra Adhikari", - "email": "jiten.adhikary@gmail.com" - } - ], - "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", - "keywords": [ - "auth", - "json-web-token", - "jwt", - "jwt-auth", - "jwt-php", - "token" - ], - "support": { - "issues": "https://github.com/adhocore/php-jwt/issues", - "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" - }, - "funding": [ - { - "url": "https://paypal.me/ji10", - "type": "custom" - } - ], - "time": "2021-02-20T09:56:44+00:00" - }, - { - "name": "appwrite/php-clamav", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/php-clamav.git", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", - "shasum": "" - }, - "require": { - "ext-sockets": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\ClamAV\\": "src/ClamAV" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "ClamAV network and pipe client for PHP", - "keywords": [ - "anti virus", - "appwrite", - "clamav", - "php" - ], - "support": { - "issues": "https://github.com/appwrite/php-clamav/issues", - "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" - }, - "time": "2020-10-02T05:23:46+00:00" - }, - { - "name": "appwrite/php-runtimes", - "version": "0.11.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/runtimes.git", - "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" - }, - "require": { - "php": ">=8.0", - "utopia-php/system": "0.6.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\Runtimes\\": "src/Runtimes" - } - }, - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", - "keywords": [ - "appwrite", - "php", - "runtimes" - ], - "time": "2022-11-07T16:45:52+00:00" - }, - { - "name": "chillerlan/php-qrcode", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", - "shasum": "" - }, - "require": { - "chillerlan/php-settings-container": "^2.1", - "ext-mbstring": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5", - "setasign/fpdf": "^1.8.2" - }, - "suggest": { - "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", - "setasign/fpdf": "Required to use the QR FPDF output." - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\QRCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" - }, - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - }, - { - "name": "Contributors", - "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" - } - ], - "description": "A QR code generator. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-qrcode", - "keywords": [ - "phpqrcode", - "qr", - "qr code", - "qrcode", - "qrcode-generator" - ], - "support": { - "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2021-11-25T22:38:09+00:00" - }, - { - "name": "chillerlan/php-settings-container", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\Settings\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - } - ], - "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-settings-container", - "keywords": [ - "PHP7", - "Settings", - "configuration", - "container", - "helper" - ], - "support": { - "issues": "https://github.com/chillerlan/php-settings-container/issues", - "source": "https://github.com/chillerlan/php-settings-container" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2022-07-05T22:32:14+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "v1.14.0", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "suggest": { - "ext-redis": "Improved performance for communicating with redis" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php", - "Module.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "support": { - "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" - }, - "time": "2022-11-09T01:18:39+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2022-01-18T15:43:28+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", - "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.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "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 - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "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.5.0" - }, - "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": "2022-08-28T15:39:27+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "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/1.5.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2022-08-28T14:55:35+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.4.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "67c26b443f348a51926030c83481b85718457d3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", - "reference": "67c26b443f348a51926030c83481b85718457d3d", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.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.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "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.4.3" - }, - "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": "2022-10-26T14:07:24+00:00" - }, - { - "name": "influxdb/influxdb-php", - "version": "1.15.2", - "source": { - "type": "git", - "url": "https://github.com/influxdata/influxdb-php.git", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0|^7.0", - "php": "^5.5 || ^7.0 || ^8.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.2.1", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "Curl extension, needed for Curl driver", - "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." - }, - "type": "library", - "autoload": { - "psr-4": { - "InfluxDB\\": "src/InfluxDB" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Hoogendijk", - "email": "stephen@tca0.nl" - }, - { - "name": "Daniel Martinez", - "email": "danimartcas@hotmail.com" - }, - { - "name": "Gianluca Arbezzano", - "email": "gianarb92@gmail.com" - } - ], - "description": "InfluxDB client library for PHP", - "keywords": [ - "client", - "influxdata", - "influxdb", - "influxdb class", - "influxdb client", - "influxdb library", - "time series" - ], - "support": { - "issues": "https://github.com/influxdata/influxdb-php/issues", - "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" - }, - "abandoned": true, - "time": "2020-12-26T17:45:17+00:00" - }, - { - "name": "laravel/pint", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.32.0", - "laravel-zero/framework": "^9.2.0", - "mockery/mockery": "^1.5.1", - "nunomaduro/larastan": "^2.2.0", - "nunomaduro/termwind": "^1.14.0", - "pestphp/pest": "^1.22.1" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", - "keywords": [ - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2022-11-29T16:25:20+00:00" - }, - { - "name": "matomo/device-detector", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/matomo-org/device-detector.git", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", - "shasum": "" - }, - "require": { - "mustangostang/spyc": "*", - "php": "^7.2|^8.0" - }, - "replace": { - "piwik/device-detector": "self.version" - }, - "require-dev": { - "matthiasmullie/scrapbook": "^1.4.7", - "mayflower/mo4-coding-standard": "^v8.0.0", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5.8", - "psr/cache": "^1.0.1", - "psr/simple-cache": "^1.0.1", - "symfony/yaml": "^5.1.7" - }, - "suggest": { - "doctrine/cache": "Can directly be used for caching purpose", - "ext-yaml": "Necessary for using the Pecl YAML parser" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeviceDetector\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "The Matomo Team", - "email": "hello@matomo.org", - "homepage": "https://matomo.org/team/" - } - ], - "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", - "homepage": "https://matomo.org", - "keywords": [ - "devicedetection", - "parser", - "useragent" - ], - "support": { - "forum": "https://forum.matomo.org/", - "issues": "https://github.com/matomo-org/device-detector/issues", - "source": "https://github.com/matomo-org/matomo", - "wiki": "https://dev.matomo.org/" - }, - "time": "2022-04-11T09:58:17+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "git@github.com:mustangostang/spyc.git", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2019-09-10T13:16:29+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.2", - "yoast/phpunit-polyfills": "^1.0.0" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2022-02-28T15:31:21+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20: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": "resque/php-resque", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/resque/php-resque.git", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "~1.7", - "php": ">=5.6.0", - "psr/log": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "suggest": { - "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", - "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", - "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." - }, - "bin": [ - "bin/resque", - "bin/resque-scheduler" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Resque": "lib", - "ResqueScheduler": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dan Hunsaker", - "email": "danhunsaker+resque@gmail.com", - "role": "Maintainer" - }, - { - "name": "Rajib Ahmed", - "homepage": "https://github.com/rajibahmed", - "role": "Maintainer" - }, - { - "name": "Steve Klabnik", - "email": "steve@steveklabnik.com", - "role": "Maintainer" - }, - { - "name": "Chris Boulton", - "email": "chris@bigcommerce.com", - "role": "Creator" - } - ], - "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", - "homepage": "http://www.github.com/resque/php-resque/", - "keywords": [ - "background", - "job", - "redis", - "resque" - ], - "support": { - "issues": "https://github.com/resque/php-resque/issues", - "source": "https://github.com/resque/php-resque/tree/v1.3.6" - }, - "time": "2020-04-16T16:39:50+00:00" - }, - { - "name": "slickdeals/statsd", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/Slickdeals/statsd-php.git", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", - "shasum": "" - }, - "require": { - "php": ">= 7.3 || ^8" - }, - "replace": { - "domnikl/statsd": "self.version" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Domnikl\\Statsd\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dominik Liebler", - "email": "liebler.dominik@gmail.com" - } - ], - "description": "a PHP client for statsd", - "homepage": "https://github.com/Slickdeals/statsd-php", - "keywords": [ - "Metrics", - "monitoring", - "statistics", - "statsd", - "udp" - ], - "support": { - "issues": "https://github.com/Slickdeals/statsd-php/issues", - "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" - }, - "time": "2021-06-04T20:33:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.3-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-25T10:21:52+00:00" - }, - { - "name": "utopia-php/abuse", - "version": "0.16.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "6370d9150425460416583feba0990504ac789e98" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6370d9150425460416583feba0990504ac789e98", - "reference": "6370d9150425460416583feba0990504ac789e98", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.28.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Abuse\\": "src/Abuse" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple abuse library to manage application usage limits", - "keywords": [ - "Abuse", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.16.0" - }, - "time": "2022-10-31T14:46:41+00:00" - }, - { - "name": "utopia-php/analytics", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/analytics.git", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Analytics\\": "src/Analytics" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library to track events & users.", - "keywords": [ - "analytics", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.2.0" - }, - "time": "2021-03-23T21:33:07+00:00" - }, - { - "name": "utopia-php/audit", - "version": "0.17.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/audit.git", - "reference": "455471bd4de8d74026809e843f8c9740eb32922c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/455471bd4de8d74026809e843f8c9740eb32922c", - "reference": "455471bd4de8d74026809e843f8c9740eb32922c", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.28.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Audit\\": "src/Audit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple audit library to manage application users logs", - "keywords": [ - "Audit", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.17.0" - }, - "time": "2022-10-31T14:44:52+00:00" - }, - { - "name": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cache.git", - "reference": "c29179055def7827b27fde979cefe07c3e4858da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/c29179055def7827b27fde979cefe07c3e4858da", - "reference": "c29179055def7827b27fde979cefe07c3e4858da", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-memcached": "*", - "ext-redis": "*", - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Cache\\": "src/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple cache library to manage application cache storing, loading and purging", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" - }, - "time": "2022-10-27T14:35:59+00:00" - }, - { - "name": "utopia-php/cli", - "version": "0.14.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cli.git", - "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/c30ef985a4e739758a0d95eb0706b357b6d8c086", - "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086", - "shasum": "" - }, - "require": { - "php": ">=7.4", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\CLI\\": "src/CLI" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple CLI library to manage command line applications", - "keywords": [ - "cli", - "command line", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.14.0" - }, - "time": "2022-10-09T10:19:07+00:00" - }, - { - "name": "utopia-php/config", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/config.git", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Config\\": "src/Config" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Config library to managing application config variables", - "keywords": [ - "config", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/config/issues", - "source": "https://github.com/utopia-php/config/tree/0.2.2" - }, - "time": "2020-10-24T09:49:09+00:00" - }, - { - "name": "utopia-php/database", - "version": "0.28.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ef6506af1c09c22f5dc1e7859159d323f7fafa94", - "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cache": "0.8.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "fakerphp/faker": "^1.14", - "mongodb/mongodb": "1.8.0", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.11.0", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Database\\": "src/Database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library to manage application persistency using multiple database adapters", - "keywords": [ - "database", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.28.0" - }, - "time": "2022-10-31T09:58:46+00:00" - }, - { - "name": "utopia-php/domains", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Domains\\": "src/Domains" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "domains", - "framework", - "icann", - "php", - "public suffix", - "tld", - "tld extract", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/master" - }, - "time": "2020-02-23T07:40:02+00:00" - }, - { - "name": "utopia-php/dsn", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/dsn.git", - "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea", - "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\DSN\\": "src/DSN" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library for parsing and managing Data Source Names ( DSNs )", - "keywords": [ - "dsn", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/dsn/issues", - "source": "https://github.com/utopia-php/dsn/tree/0.1.0" - }, - "time": "2022-10-26T10:06:20+00:00" - }, - { - "name": "utopia-php/framework", - "version": "0.25.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "2391b397135586b2100d39e338827bef8d2f4ad0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0", - "reference": "2391b397135586b2100d39e338827bef8d2f4ad0", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "require-dev": { - "laravel/pint": "^1.2", - "phpunit/phpunit": "^9.5.25", - "vimeo/psalm": "4.27.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.25.1" - }, - "time": "2022-11-23T18:22:23+00:00" - }, - { - "name": "utopia-php/image", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/image.git", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", - "shasum": "" - }, - "require": { - "ext-imagick": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Image\\": "src/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Image manipulation library", - "keywords": [ - "framework", - "image", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.4" - }, - "time": "2022-05-11T12:30:41+00:00" - }, - { - "name": "utopia-php/locale", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/locale.git", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Locale\\": "src/Locale" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple locale library to manage application translations", - "keywords": [ - "framework", - "locale", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/locale/issues", - "source": "https://github.com/utopia-php/locale/tree/0.4.0" - }, - "time": "2021-07-24T11:35:55+00:00" - }, - { - "name": "utopia-php/logger", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Logger\\": "src/Logger" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], - "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "appsignal", - "errors", - "framework", - "logger", - "logging", - "logs", - "php", - "raygun", - "sentry", - "upf", - "utopia", - "warnings" - ], - "support": { - "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" - }, - "time": "2022-03-18T10:56:57+00:00" - }, - { - "name": "utopia-php/messaging", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/messaging.git", - "reference": "501272fad666f06bec8f130076862e7981a73f8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", - "reference": "501272fad666f06bec8f130076862e7981a73f8c", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=8.0.0" - }, - "require-dev": { - "phpmailer/phpmailer": "6.6.*", - "phpunit/phpunit": "9.5.*", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Messaging\\": "src/Utopia/Messaging" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jake Barnby", - "email": "jake@appwrite.io" - } - ], - "description": "A simple, light and advanced PHP messaging library", - "keywords": [ - "library", - "messaging", - "php", - "upf", - "utopia", - "utopia-php" - ], - "support": { - "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.1.0" - }, - "time": "2022-09-29T11:22:48+00:00" - }, - { - "name": "utopia-php/orchestration", - "version": "0.9.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/orchestration.git", - "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/1d4f66684b8c4927f31b695817eae6d84aafd172", - "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.14.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Orchestration\\": "src/Orchestration" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Lite & fast micro PHP abstraction library for container orchestration", - "keywords": [ - "docker", - "framework", - "kubernetes", - "orchestration", - "php", - "swarm", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.9.0" - }, - "time": "2022-11-09T17:38:00+00:00" - }, - { - "name": "utopia-php/platform", - "version": "0.3.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/platform.git", - "reference": "fe9f64420957dc8fb6201d22b499572f021411e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/fe9f64420957dc8fb6201d22b499572f021411e4", - "reference": "fe9f64420957dc8fb6201d22b499572f021411e4", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-redis": "*", - "php": ">=8.0", - "utopia-php/cli": "0.14.*", - "utopia-php/framework": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Platform\\": "src/Platform" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Light and Fast Platform Library", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.3.1" - }, - "time": "2022-11-10T07:04:24+00:00" - }, - { - "name": "utopia-php/pools", - "version": "0.4.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/pools.git", - "reference": "d2870ab74b31b7f4027799f082e85122154f8bed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/d2870ab74b31b7f4027799f082e85122154f8bed", - "reference": "d2870ab74b31b7f4027799f082e85122154f8bed", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpstan/phpstan": "1.8.*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Pools\\": "src/Pools" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Team Appwrite", - "email": "team@appwrite.io" - } - ], - "description": "A simple library to manage connection pools", - "keywords": [ - "framework", - "php", - "pools", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/0.4.2" - }, - "time": "2022-11-22T07:55:45+00:00" - }, - { - "name": "utopia-php/preloader", - "version": "0.2.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/preloader.git", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Preloader\\": "src/Preloader" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", - "keywords": [ - "framework", - "php", - "preload", - "preloader", - "preloading", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/preloader/issues", - "source": "https://github.com/utopia-php/preloader/tree/0.2.4" - }, - "time": "2020-10-24T07:04:59+00:00" - }, - { - "name": "utopia-php/queue", - "version": "0.5.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/queue.git", - "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/4b39e1f232b2e619b0d7fb4004f2356df334ddc1", - "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.14.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "laravel/pint": "^0.2.3", - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.8.8", - "workerman/workerman": "^4.0" - }, - "suggest": { - "ext-swoole": "Needed to support Swoole.", - "workerman/workerman": "Needed to support Workerman." - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Queue\\": "src/Queue" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A powerful task queue.", - "keywords": [ - "Tasks", - "framework", - "php", - "queue", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.5.1" - }, - "time": "2022-11-16T19:47:26+00:00" - }, - { - "name": "utopia-php/registry", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/registry.git", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Registry\\": "src/Registry" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple dependency management library for PHP", - "keywords": [ - "dependency management", - "di", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/registry/issues", - "source": "https://github.com/utopia-php/registry/tree/0.5.0" - }, - "time": "2021-03-10T10:45:22+00:00" - }, - { - "name": "utopia-php/storage", - "version": "0.13.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/storage.git", - "reference": "f19a200af5323e3bd933807b8f55a585fc96ce07" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/f19a200af5323e3bd933807b8f55a585fc96ce07", - "reference": "f19a200af5323e3bd933807b8f55a585fc96ce07", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-zlib": "*", - "ext-zstd": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Storage\\": "src/Storage" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Storage library to manage application storage", - "keywords": [ - "framework", - "php", - "storage", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.13.1" - }, - "time": "2022-12-09T09:15:29+00:00" - }, - { - "name": "utopia-php/swoole", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/swoole.git", - "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", - "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", - "shasum": "" - }, - "require": { - "ext-swoole": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "swoole/ide-helper": "4.8.3", - "vimeo/psalm": "4.15.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Swoole\\": "src/Swoole" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", - "keywords": [ - "framework", - "http", - "php", - "server", - "swoole", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.5.0" - }, - "time": "2022-10-19T22:19:07+00:00" - }, - { - "name": "utopia-php/system", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/system.git", - "reference": "289c4327713deadc9c748b5317d248133a02f245" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", - "reference": "289c4327713deadc9c748b5317d248133a02f245", - "shasum": "" - }, - "require": { - "laravel/pint": "1.2.*", - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\System\\": "src/System" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library for obtaining information about the host's system.", - "keywords": [ - "framework", - "php", - "system", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.6.0" - }, - "time": "2022-11-07T13:51:59+00:00" - }, - { - "name": "utopia-php/websocket", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/websocket.git", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.6.6", - "textalk/websocket": "1.5.2", - "vimeo/psalm": "^4.8.1", - "workerman/workerman": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\WebSocket\\": "src/WebSocket" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple abstraction for WebSocket servers.", - "keywords": [ - "framework", - "php", - "upf", - "utopia", - "websocket" - ], - "support": { - "issues": "https://github.com/utopia-php/websocket/issues", - "source": "https://github.com/utopia-php/websocket/tree/0.1.0" - }, - "time": "2021-12-20T10:50:09+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "appwrite/sdk-generator", - "version": "0.28.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "matthiasmullie/minify": "^1.3.68", - "php": ">=7.0.0", - "twig/twig": "^3.4.1" - }, - "require-dev": { - "brianium/paratest": "^6.4", - "phpunit/phpunit": "^9.5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\SDK\\": "src/SDK", - "Appwrite\\Spec\\": "src/Spec" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "support": { - "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" - }, - "time": "2022-09-22T09:15:54+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "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.22" - }, - "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.4.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%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.70", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": ">=2.0", - "matthiasmullie/scrapbook": ">=1.3", - "phpunit/phpunit": ">=4.8", - "squizlabs/php_codesniffer": ">=3.0" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "https://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "https://github.com/matthiasmullie/minify", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" - }, - "funding": [ - { - "url": "https://github.com/matthiasmullie", - "type": "github" - } - ], - "time": "2022-12-09T12:56:44+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" - }, - "time": "2022-11-12T15:38:23+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.16.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" - }, - "time": "2022-11-29T15:06:56+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.22", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df", - "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-12-18T16:40:55+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library 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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "swoole/ide-helper", - "version": "4.8.9", - "source": { - "type": "git", - "url": "https://github.com/swoole/ide-helper.git", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "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/4.8.9" - }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-04-18T20:38:04+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.7", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" - }, - "time": "2022-03-29T09:46:59+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "twig/twig", - "version": "v3.4.3", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, - "autoload": { - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "time": "2022-09-28T08:42:51+00:00" - } - ], - "aliases": [ - { - "package": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "alias": "0.8.1", - "alias_normalized": "0.8.1.0" - } - ], - "minimum-stability": "stable", - "stability-flags": { - "utopia-php/cache": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0.0", - "ext-curl": "*", - "ext-imagick": "*", - "ext-mbstring": "*", - "ext-json": "*", - "ext-yaml": "*", - "ext-dom": "*", - "ext-redis": "*", - "ext-swoole": "*", - "ext-pdo": "*", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-sockets": "*" - }, - "platform-dev": { - "ext-fileinfo": "*" - }, - "platform-overrides": { - "php": "8.0" - }, - "plugin-api-version": "2.2.0" -} diff --git a/phpbench.json b/phpbench.json new file mode 100644 index 0000000000..4ebdc080b4 --- /dev/null +++ b/phpbench.json @@ -0,0 +1,17 @@ +{ + "$schema": "./vendor/phpbench/phpbench/phpbench.schema.json", + "runner.path": "tests/benchmarks", + "runner.file_pattern": "*Bench.php", + "runner.bootstrap": "app/init.php", + "runner.revs": 1000, + "runner.iterations": 3, + "runner.retry_threshold": 5, + "runner.warmup": 1, + "report.generators": { + "appwrite": { + "extends": "aggregate", + "cols": ["benchmark", "subject", "set" ,"revs", "its", "worst", "best", "mean", "mode", "rstdev"], + "break": ["benchmark"] + } + } +} \ No newline at end of file diff --git a/tests/benchmarks/Scopes/Scope.php b/tests/benchmarks/Scopes/Scope.php new file mode 100644 index 0000000000..03b2d7f1ef --- /dev/null +++ b/tests/benchmarks/Scopes/Scope.php @@ -0,0 +1,14 @@ +client->call(Client::METHOD_POST, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/documents', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'documentId' => ID::unique(), + 'data' => [ + 'title' => 'The Matrix', + ], + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + Permission::write(Role::user($this->getUser()['$id'])), + ], + ]); + } + + #[ParamProviders(['provideCounts'])] + #[BeforeMethods(['createDatabase', 'createCollection', 'createDocuments'])] + public function benchDocumentReadList(array $params) + { + $this->client->call(Client::METHOD_GET, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/documents', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => ['limit(' . $params['documents'] . ')'], + ]); + } + + #[BeforeMethods(['createDatabase', 'createCollection', 'createDocuments'])] + public function benchDocumentRead() + { + $this->client->call(Client::METHOD_GET, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/documents/' . static::$documentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + } + + #[BeforeMethods(['createDatabase', 'createCollection', 'createDocuments'])] + public function benchDocumentUpdate() + { + $this->client->call(Client::METHOD_PATCH, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/documents/' . static::$documentId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'data' => [ + 'title' => 'The Matrix Reloaded', + ], + ]); + } + + public function provideCounts(): array + { + return [ + '1 Document' => ['documents' => 1], + '10 Documents' => ['documents' => 10], + '100 Documents' => ['documents' => 100], + ]; + } + + public function createDatabase(array $params = []) + { + $database = $this->client->call(Client::METHOD_POST, '/databases', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'databaseId' => ID::unique(), + 'name' => 'Test Database' + ]); + static::$databaseId = $database['body']['$id']; + } + + public function createCollection(array $params = []) + { + $collection = $this->client->call(Client::METHOD_POST, '/databases/' . static::$databaseId . '/collections', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'collectionId' => ID::unique(), + 'name' => 'Movies', + 'documentSecurity' => true, + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + Permission::write(Role::user($this->getUser()['$id'])), + ], + ]); + static::$collectionId = $collection['body']['$id']; + + // Create attribute + $this->client->call(Client::METHOD_POST, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/attributes/string', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'key' => 'title', + 'size' => 256, + 'required' => true, + ]); + + // Wait for attribute to be ready + sleep(2); + } + + public function createDocuments(array $params = []) + { + $count = $params['documents'] ?? 1; + + for ($i = 0; $i < $count; $i++) { + $response = $this->client->call(Client::METHOD_POST, '/databases/' . static::$databaseId . '/collections/' . static::$collectionId . '/documents', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'documentId' => ID::unique(), + 'data' => [ + 'title' => 'Captain America' . $i, + ], + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + Permission::write(Role::user($this->getUser()['$id'])), + ] + ]); + + static::$documentId = $response['body']['$id']; + } + } +} diff --git a/tests/benchmarks/Services/Databases/DatabasesCustomClientBench.php b/tests/benchmarks/Services/Databases/DatabasesCustomClientBench.php new file mode 100644 index 0000000000..658ddfd98c --- /dev/null +++ b/tests/benchmarks/Services/Databases/DatabasesCustomClientBench.php @@ -0,0 +1,10 @@ +client->call(Client::METHOD_POST, '/functions/' . static::$functionId . '/executions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + } + + public function createFunction() + { + $response = $this->client->call(Client::METHOD_POST, '/functions', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'functionId' => ID::unique(), + 'name' => 'Test', + 'runtime' => 'php-8.0', + 'timeout' => 10, + 'execute' => [Role::users()->toString()] + ]); + static::$functionId = $response['body']['$id']; + } + + public function prepareDeployment() + { + $stdout = ''; + $stderr = ''; + + Console::execute( + 'cd ' . realpath(__DIR__ . "/../../../resources/functions/php") . " && \ + tar --exclude code.tar.gz -czf code.tar.gz .", + '', + $stdout, + $stderr + ); + } + + public function createDeployment() + { + $code = realpath(__DIR__ . '/../../../resources/functions/php/code.tar.gz'); + + $response = $this->client->call(Client::METHOD_POST, '/functions/' . static::$functionId . '/deployments', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'entrypoint' => 'index.php', + 'code' => new CURLFile( + $code, + 'application/x-gzip', + \basename($code) + ), + ]); + + static::$deploymentId = $response['body']['$id']; + + while (true) { + $response = $this->client->call(Client::METHOD_GET, '/functions/' . static::$functionId . '/deployments/' . static::$deploymentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ]); + + $status = $response['body']['status'] ?? ''; + + switch ($status) { + case '': + case 'processing': + case 'building': + usleep(200); + break; + case 'ready': + break 2; + case 'failed': + throw new \Exception('Failed to build function'); + } + } + + sleep(1); + } + + public function patchDeployment() + { + $this->client->call(Client::METHOD_PATCH, '/functions/' . static::$functionId . '/deployments/' . static::$deploymentId, [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'], + ], []); + } +} diff --git a/tests/benchmarks/Services/Functions/FunctionsCustomClientBench.php b/tests/benchmarks/Services/Functions/FunctionsCustomClientBench.php new file mode 100644 index 0000000000..ec5e0b8f29 --- /dev/null +++ b/tests/benchmarks/Services/Functions/FunctionsCustomClientBench.php @@ -0,0 +1,10 @@ +createDeployment(); + } +} diff --git a/tests/benchmarks/Services/Storage/Base.php b/tests/benchmarks/Services/Storage/Base.php new file mode 100644 index 0000000000..6496490a6f --- /dev/null +++ b/tests/benchmarks/Services/Storage/Base.php @@ -0,0 +1,117 @@ +client->call(Client::METHOD_POST, '/storage/buckets/' . static::$bucketId . '/files', array_merge([ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'fileId' => ID::unique(), + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + Permission::write(Role::user($this->getUser()['$id'])), + ], + + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), + ]); + } + + #[ParamProviders(['provideCounts'])] + #[BeforeMethods(['createBucket', 'createFiles'])] + public function benchFileReadList(array $params) + { + $this->client->call(Client::METHOD_GET, '/storage/buckets/' . static::$bucketId . '/files', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => ['limit(' . $params['files'] . ')'], + ]); + } + + #[BeforeMethods(['createBucket', 'createFiles'])] + public function benchFileRead() + { + $this->client->call(Client::METHOD_GET, '/storage/buckets/' . static::$bucketId . '/files/' . static::$fileId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + } + + #[BeforeMethods(['createBucket', 'createFiles'])] + public function benchFileUpdate() + { + $this->client->call(Client::METHOD_PUT, '/storage/buckets/' . static::$bucketId . '/files/' . static::$fileId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'Updated name', + 'permissions' => [], + ]); + } + + public function provideCounts(): array + { + return [ + '10 Files' => ['files' => 10], + '100 Files' => ['files' => 100], + ]; + } + + public function createBucket(array $params = []) + { + // Create bucket + $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'bucketId' => ID::unique(), + 'name' => 'Test Bucket', + 'permissions' => [ + Permission::read(Role::user($this->getUser()['$id'])), + Permission::write(Role::user($this->getUser()['$id'])), + ], + 'fileSecurity' => true + ]); + static::$bucketId = $bucket['body']['$id']; + } + + public function createFiles(array $params = []) + { + $count = $params['files'] ?? 1; + + // Create files + for ($i = 0; $i < $count; $i++) { + $response = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . static::$bucketId . '/files', [ + 'content-type' => 'multipart/form-data', + 'x-appwrite-project' => $this->getProject()['$id'], + 'x-appwrite-key' => $this->getProject()['apiKey'] + ], [ + 'fileId' => ID::unique(), + 'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'), + ]); + + static::$fileId = $response['body']['$id']; + } + } +} diff --git a/tests/benchmarks/Services/Storage/StorageCustomClientBench.php b/tests/benchmarks/Services/Storage/StorageCustomClientBench.php new file mode 100644 index 0000000000..585182c1da --- /dev/null +++ b/tests/benchmarks/Services/Storage/StorageCustomClientBench.php @@ -0,0 +1,10 @@ +client->call(Client::METHOD_POST, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => $id, + 'email' => 'test' . $id . '@example.com', + 'password' => 'password', + ]); + } + + #[ParamProviders(['provideCounts'])] + #[BeforeMethods(['createUsers'])] + public function benchUserReadList(array $params) + { + $this->client->call(Client::METHOD_GET, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'queries' => ['limit(' . $params['users'] . ')'], + ]); + } + + #[BeforeMethods(['createUsers'])] + public function benchUserRead() + { + $this->client->call(Client::METHOD_GET, '/users/' . static::$userId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders())); + } + + #[BeforeMethods(['createUsers'])] + public function benchUserUpdate() + { + $this->client->call(Client::METHOD_PUT, '/users/' . static::$userId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'name' => 'New Name', + ]); + } + + public function createUsers(array $params = []) + { + $count = $params['documents'] ?? 1; + + for ($i = 0; $i < $count; $i++) { + $id = ID::unique(); + + $response = $this->client->call(Client::METHOD_POST, '/users', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'userId' => $id, + 'email' => 'test' . $id . '@example.com', + 'password' => 'password', + ]); + + static::$userId = $response['body']['$id']; + } + } + + public function provideCounts(): array + { + return [ + '1 User' => ['users' => 1], + '10 Users' => ['users' => 10], + '100 Users' => ['users' => 100], + ]; + } +} diff --git a/tests/benchmarks/http.js b/tests/benchmarks/http.js deleted file mode 100644 index 799c8fb23c..0000000000 --- a/tests/benchmarks/http.js +++ /dev/null @@ -1,34 +0,0 @@ -import http from 'k6/http'; -import { check } from 'k6'; -import { Counter } from 'k6/metrics'; - -// A simple counter for http requests -export const requests = new Counter('http_reqs'); - -// you can specify stages of your test (ramp up/down patterns) through the options object -// target is the number of VUs you are aiming for - -export const options = { - stages: [ - { target: 50, duration: '1m' }, - // { target: 15, duration: '1m' }, - // { target: 0, duration: '1m' }, - ], - thresholds: { - requests: ['count < 100'], - }, -}; - -export default function () { - const config = { - headers: { - 'X-Appwrite-Key': '24356eb021863f81eb7dd77c7750304d0464e141cad6e9a8befa1f7d2b066fde190df3dab1e8d2639dbb82ee848da30501424923f4cd80d887ee40ad77ded62763ee489448523f6e39667f290f9a54b2ab8fad131a0bc985e6c0f760015f7f3411e40626c75646bb19d2bb2f7bf2f63130918220a206758cbc48845fd725a695', - 'X-Appwrite-Project': '60479fe35d95d' - }} - - const resDb = http.get('http://localhost:9501/', config); - - check(resDb, { - 'status is 200': (r) => r.status === 200, - }); -} \ No newline at end of file diff --git a/tests/benchmarks/ws.js b/tests/benchmarks/ws.js deleted file mode 100644 index 916458856f..0000000000 --- a/tests/benchmarks/ws.js +++ /dev/null @@ -1,59 +0,0 @@ -// k6 run tests/benchmarks/ws.js - -import { URL } from 'https://jslib.k6.io/url/1.0.0/index.js'; -import ws from 'k6/ws'; -import { check } from 'k6'; - -export let options = { - stages: [ - { - duration: '10s', - target: 500 - }, - { - duration: '1m', - target: 500 - }, - ], -} - -export default function () { - // const url = new URL('wss://appwrite-realtime.monitor-api.com/v1/realtime'); - // url.searchParams.append('project', '604249e6b1a9f'); - const url = new URL('ws://localhost/v1/realtime'); - url.searchParams.append('project', 'console'); - url.searchParams.append('channels[]', 'files'); - - const res = ws.connect(url.toString(), function (socket) { - let connection = false; - let checked = false; - let payload = null; - socket.on('open', () => { - connection = true; - }); - - socket.on('message', (data) => { - payload = data; - checked = true; - }); - - socket.setTimeout(function () { - check(payload, { - 'connection opened': (r) => connection, - 'message received': (r) => checked, - 'channels are right': (r) => r === JSON.stringify({ - "type": "connected", - "data": { - "channels": [ - "files" - ], - "user": null - } - }) - }) - socket.close(); - }, 5000); - }); - - check(res, { 'status is 101': (r) => r && r.status === 101 }); -} \ No newline at end of file diff --git a/tests/e2e/Scopes/Scope.php b/tests/e2e/Scopes/Scope.php index 2a9f205272..1858e41b8e 100644 --- a/tests/e2e/Scopes/Scope.php +++ b/tests/e2e/Scopes/Scope.php @@ -21,7 +21,7 @@ abstract class Scope extends TestCase */ protected $endpoint = 'http://localhost/v1'; - protected function setUp(): void + public function setUp(): void { $this->client = new Client(); @@ -30,7 +30,7 @@ protected function setUp(): void ; } - protected function tearDown(): void + public function tearDown(): void { $this->client = null; } From 8fee018c181996b3d8bd8e3db465b1ed9b198ec1 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 27 Dec 2022 09:53:07 +0200 Subject: [PATCH 39/87] benchmarks --- app/workers/sync-In.php | 4 ++-- phpbench.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index c5314ef1ed..e11daa38e8 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -14,14 +14,14 @@ ->action(function (Message $message, Cache $cache) { $time = DateTime::now(); - $cache->setDisableListeners(true); + $cache->setListenersStatus(false); foreach ($message->getPayload()['keys'] ?? [] as $key) { Console::log("[{$time}] Purging {$key}"); $cache->purge($key); } - $cache->setDisableListeners(false); + $cache->setListenersStatus(true); }); $server diff --git a/phpbench.json b/phpbench.json index 4ebdc080b4..217a122706 100644 --- a/phpbench.json +++ b/phpbench.json @@ -3,14 +3,14 @@ "runner.path": "tests/benchmarks", "runner.file_pattern": "*Bench.php", "runner.bootstrap": "app/init.php", - "runner.revs": 1000, + "runner.revs": 2000, "runner.iterations": 3, "runner.retry_threshold": 5, "runner.warmup": 1, "report.generators": { "appwrite": { "extends": "aggregate", - "cols": ["benchmark", "subject", "set" ,"revs", "its", "worst", "best", "mean", "mode", "rstdev"], + "cols": ["benchmark", "subject", "set" ,"revs", "its", "worst", "best", "mean"], "break": ["benchmark"] } } From 5924a7bd02fcc4c372910bd67edf94394cb2c979 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 27 Dec 2022 09:54:34 +0200 Subject: [PATCH 40/87] benchmarks --- composer.lock | 6885 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6885 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..7adb8c2109 --- /dev/null +++ b/composer.lock @@ -0,0 +1,6885 @@ +{ + "_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": "4d3e2a569d5f848f135a5fc854924af4", + "packages": [ + { + "name": "adhocore/jwt", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-jwt.git", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ahc\\Jwt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", + "keywords": [ + "auth", + "json-web-token", + "jwt", + "jwt-auth", + "jwt-php", + "token" + ], + "support": { + "issues": "https://github.com/adhocore/php-jwt/issues", + "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + } + ], + "time": "2021-02-20T09:56:44+00:00" + }, + { + "name": "appwrite/php-clamav", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/appwrite/php-clamav.git", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", + "shasum": "" + }, + "require": { + "ext-sockets": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\ClamAV\\": "src/ClamAV" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "ClamAV network and pipe client for PHP", + "keywords": [ + "anti virus", + "appwrite", + "clamav", + "php" + ], + "support": { + "issues": "https://github.com/appwrite/php-clamav/issues", + "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" + }, + "time": "2020-10-02T05:23:46+00:00" + }, + { + "name": "appwrite/php-runtimes", + "version": "0.11.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/runtimes.git", + "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" + }, + "require": { + "php": ">=8.0", + "utopia-php/system": "0.6.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\Runtimes\\": "src/Runtimes" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", + "keywords": [ + "appwrite", + "php", + "runtimes" + ], + "time": "2022-11-07T16:45:52+00:00" + }, + { + "name": "chillerlan/php-qrcode", + "version": "4.3.3", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-qrcode.git", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", + "shasum": "" + }, + "require": { + "chillerlan/php-settings-container": "^2.1", + "ext-mbstring": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", + "setasign/fpdf": "Required to use the QR FPDF output." + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\QRCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kazuhiko Arase", + "homepage": "https://github.com/kazuhikoarase" + }, + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + }, + { + "name": "Contributors", + "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" + } + ], + "description": "A QR code generator. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-qrcode", + "keywords": [ + "phpqrcode", + "qr", + "qr code", + "qrcode", + "qrcode-generator" + ], + "support": { + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2021-11-25T22:38:09+00:00" + }, + { + "name": "chillerlan/php-settings-container", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-settings-container.git", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\Settings\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + } + ], + "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-settings-container", + "keywords": [ + "PHP7", + "Settings", + "configuration", + "container", + "helper" + ], + "support": { + "issues": "https://github.com/chillerlan/php-settings-container/issues", + "source": "https://github.com/chillerlan/php-settings-container" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2022-07-05T22:32:14+00:00" + }, + { + "name": "colinmollenhour/credis", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "suggest": { + "ext-redis": "Improved performance for communicating with redis" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php", + "Module.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "support": { + "issues": "https://github.com/colinmollenhour/credis/issues", + "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" + }, + "time": "2022-11-09T01:18:39+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "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.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "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 + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "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.5.0" + }, + "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": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "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/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "67c26b443f348a51926030c83481b85718457d3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", + "reference": "67c26b443f348a51926030c83481b85718457d3d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.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.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "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.4.3" + }, + "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": "2022-10-26T14:07:24+00:00" + }, + { + "name": "influxdb/influxdb-php", + "version": "1.15.2", + "source": { + "type": "git", + "url": "https://github.com/influxdata/influxdb-php.git", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "Curl extension, needed for Curl driver", + "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." + }, + "type": "library", + "autoload": { + "psr-4": { + "InfluxDB\\": "src/InfluxDB" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Hoogendijk", + "email": "stephen@tca0.nl" + }, + { + "name": "Daniel Martinez", + "email": "danimartcas@hotmail.com" + }, + { + "name": "Gianluca Arbezzano", + "email": "gianarb92@gmail.com" + } + ], + "description": "InfluxDB client library for PHP", + "keywords": [ + "client", + "influxdata", + "influxdb", + "influxdb class", + "influxdb client", + "influxdb library", + "time series" + ], + "support": { + "issues": "https://github.com/influxdata/influxdb-php/issues", + "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" + }, + "abandoned": true, + "time": "2020-12-26T17:45:17+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11.0", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", + "nunomaduro/termwind": "^1.14.0", + "pestphp/pest": "^1.22.1" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2022-11-29T16:25:20+00:00" + }, + { + "name": "matomo/device-detector", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/matomo-org/device-detector.git", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", + "shasum": "" + }, + "require": { + "mustangostang/spyc": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "piwik/device-detector": "self.version" + }, + "require-dev": { + "matthiasmullie/scrapbook": "^1.4.7", + "mayflower/mo4-coding-standard": "^v8.0.0", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8.5.8", + "psr/cache": "^1.0.1", + "psr/simple-cache": "^1.0.1", + "symfony/yaml": "^5.1.7" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeviceDetector\\": "" + }, + "exclude-from-classmap": [ + "Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "homepage": "https://matomo.org", + "keywords": [ + "devicedetection", + "parser", + "useragent" + ], + "support": { + "forum": "https://forum.matomo.org/", + "issues": "https://github.com/matomo-org/device-detector/issues", + "source": "https://github.com/matomo-org/matomo", + "wiki": "https://dev.matomo.org/" + }, + "time": "2022-04-11T09:58:17+00:00" + }, + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2019-09-10T13:16:29+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.6.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.2", + "yoast/phpunit-polyfills": "^1.0.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2022-02-28T15:31:21+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.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": "http://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/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.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": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.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": "http://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/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "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/1.1.4" + }, + "time": "2021-05-03T11:20: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": "resque/php-resque", + "version": "v1.3.6", + "source": { + "type": "git", + "url": "https://github.com/resque/php-resque.git", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "~1.7", + "php": ">=5.6.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", + "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", + "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." + }, + "bin": [ + "bin/resque", + "bin/resque-scheduler" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Resque": "lib", + "ResqueScheduler": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Hunsaker", + "email": "danhunsaker+resque@gmail.com", + "role": "Maintainer" + }, + { + "name": "Rajib Ahmed", + "homepage": "https://github.com/rajibahmed", + "role": "Maintainer" + }, + { + "name": "Steve Klabnik", + "email": "steve@steveklabnik.com", + "role": "Maintainer" + }, + { + "name": "Chris Boulton", + "email": "chris@bigcommerce.com", + "role": "Creator" + } + ], + "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", + "homepage": "http://www.github.com/resque/php-resque/", + "keywords": [ + "background", + "job", + "redis", + "resque" + ], + "support": { + "issues": "https://github.com/resque/php-resque/issues", + "source": "https://github.com/resque/php-resque/tree/v1.3.6" + }, + "time": "2020-04-16T16:39:50+00:00" + }, + { + "name": "slickdeals/statsd", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/Slickdeals/statsd-php.git", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", + "shasum": "" + }, + "require": { + "php": ">= 7.3 || ^8" + }, + "replace": { + "domnikl/statsd": "self.version" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Domnikl\\Statsd\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dominik Liebler", + "email": "liebler.dominik@gmail.com" + } + ], + "description": "a PHP client for statsd", + "homepage": "https://github.com/Slickdeals/statsd-php", + "keywords": [ + "Metrics", + "monitoring", + "statistics", + "statsd", + "udp" + ], + "support": { + "issues": "https://github.com/Slickdeals/statsd-php/issues", + "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" + }, + "time": "2021-06-04T20:33:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-25T10:21:52+00:00" + }, + { + "name": "utopia-php/abuse", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/abuse.git", + "reference": "6370d9150425460416583feba0990504ac789e98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6370d9150425460416583feba0990504ac789e98", + "reference": "6370d9150425460416583feba0990504ac789e98", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Abuse\\": "src/Abuse" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple abuse library to manage application usage limits", + "keywords": [ + "Abuse", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/abuse/issues", + "source": "https://github.com/utopia-php/abuse/tree/0.16.0" + }, + "time": "2022-10-31T14:46:41+00:00" + }, + { + "name": "utopia-php/analytics", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/analytics.git", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Analytics\\": "src/Analytics" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library to track events & users.", + "keywords": [ + "analytics", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/analytics/issues", + "source": "https://github.com/utopia-php/analytics/tree/0.2.0" + }, + "time": "2021-03-23T21:33:07+00:00" + }, + { + "name": "utopia-php/audit", + "version": "0.17.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/audit.git", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/455471bd4de8d74026809e843f8c9740eb32922c", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Audit\\": "src/Audit" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple audit library to manage application users logs", + "keywords": [ + "Audit", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/audit/issues", + "source": "https://github.com/utopia-php/audit/tree/0.17.0" + }, + "time": "2022-10-31T14:44:52+00:00" + }, + { + "name": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cache.git", + "reference": "8fe6270a9f9aebd24c77167d6d507edc2dd47eb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/8fe6270a9f9aebd24c77167d6d507edc2dd47eb0", + "reference": "8fe6270a9f9aebd24c77167d6d507edc2dd47eb0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-memcached": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.9.x-dev", + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Cache\\": "src/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple cache library to manage application cache storing, loading and purging", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cache/issues", + "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" + }, + "time": "2022-12-26T17:56:21+00:00" + }, + { + "name": "utopia-php/cli", + "version": "0.14.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cli.git", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/c30ef985a4e739758a0d95eb0706b357b6d8c086", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\CLI\\": "src/CLI" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple CLI library to manage command line applications", + "keywords": [ + "cli", + "command line", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cli/issues", + "source": "https://github.com/utopia-php/cli/tree/0.14.0" + }, + "time": "2022-10-09T10:19:07+00:00" + }, + { + "name": "utopia-php/config", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/config.git", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Config\\": "src/Config" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Config library to managing application config variables", + "keywords": [ + "config", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/config/issues", + "source": "https://github.com/utopia-php/config/tree/0.2.2" + }, + "time": "2020-10-24T09:49:09+00:00" + }, + { + "name": "utopia-php/database", + "version": "0.28.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cache": "0.8.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "fakerphp/faker": "^1.14", + "mongodb/mongodb": "1.8.0", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "4.8.0", + "utopia-php/cli": "^0.11.0", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Database\\": "src/Database" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library to manage application persistency using multiple database adapters", + "keywords": [ + "database", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/database/issues", + "source": "https://github.com/utopia-php/database/tree/0.28.0" + }, + "time": "2022-10-31T09:58:46+00:00" + }, + { + "name": "utopia-php/domains", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/domains.git", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Domains\\": "src/Domains" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "domains", + "framework", + "icann", + "php", + "public suffix", + "tld", + "tld extract", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/domains/issues", + "source": "https://github.com/utopia-php/domains/tree/master" + }, + "time": "2020-02-23T07:40:02+00:00" + }, + { + "name": "utopia-php/dsn", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/dsn.git", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\DSN\\": "src/DSN" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library for parsing and managing Data Source Names ( DSNs )", + "keywords": [ + "dsn", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/dsn/issues", + "source": "https://github.com/utopia-php/dsn/tree/0.1.0" + }, + "time": "2022-10-26T10:06:20+00:00" + }, + { + "name": "utopia-php/framework", + "version": "0.25.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/framework.git", + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0", + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "require-dev": { + "laravel/pint": "^1.2", + "phpunit/phpunit": "^9.5.25", + "vimeo/psalm": "4.27.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple, light and advanced PHP framework", + "keywords": [ + "framework", + "php", + "upf" + ], + "support": { + "issues": "https://github.com/utopia-php/framework/issues", + "source": "https://github.com/utopia-php/framework/tree/0.25.1" + }, + "time": "2022-11-23T18:22:23+00:00" + }, + { + "name": "utopia-php/image", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/image.git", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", + "shasum": "" + }, + "require": { + "ext-imagick": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Image\\": "src/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Image manipulation library", + "keywords": [ + "framework", + "image", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/image/issues", + "source": "https://github.com/utopia-php/image/tree/0.5.4" + }, + "time": "2022-05-11T12:30:41+00:00" + }, + { + "name": "utopia-php/locale", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/locale.git", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Locale\\": "src/Locale" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple locale library to manage application translations", + "keywords": [ + "framework", + "locale", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/locale/issues", + "source": "https://github.com/utopia-php/locale/tree/0.4.0" + }, + "time": "2021-07-24T11:35:55+00:00" + }, + { + "name": "utopia-php/logger", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/logger.git", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Logger\\": "src/Logger" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Matej Bačo", + "email": "matej@appwrite.io" + }, + { + "name": "Christy Jacob", + "email": "christy@appwrite.io" + } + ], + "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "appsignal", + "errors", + "framework", + "logger", + "logging", + "logs", + "php", + "raygun", + "sentry", + "upf", + "utopia", + "warnings" + ], + "support": { + "issues": "https://github.com/utopia-php/logger/issues", + "source": "https://github.com/utopia-php/logger/tree/0.3.0" + }, + "time": "2022-03-18T10:56:57+00:00" + }, + { + "name": "utopia-php/messaging", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/messaging.git", + "reference": "501272fad666f06bec8f130076862e7981a73f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", + "reference": "501272fad666f06bec8f130076862e7981a73f8c", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=8.0.0" + }, + "require-dev": { + "phpmailer/phpmailer": "6.6.*", + "phpunit/phpunit": "9.5.*", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Messaging\\": "src/Utopia/Messaging" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jake Barnby", + "email": "jake@appwrite.io" + } + ], + "description": "A simple, light and advanced PHP messaging library", + "keywords": [ + "library", + "messaging", + "php", + "upf", + "utopia", + "utopia-php" + ], + "support": { + "issues": "https://github.com/utopia-php/messaging/issues", + "source": "https://github.com/utopia-php/messaging/tree/0.1.0" + }, + "time": "2022-09-29T11:22:48+00:00" + }, + { + "name": "utopia-php/orchestration", + "version": "0.9.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/orchestration.git", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/1d4f66684b8c4927f31b695817eae6d84aafd172", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Orchestration\\": "src/Orchestration" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Lite & fast micro PHP abstraction library for container orchestration", + "keywords": [ + "docker", + "framework", + "kubernetes", + "orchestration", + "php", + "swarm", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/orchestration/issues", + "source": "https://github.com/utopia-php/orchestration/tree/0.9.0" + }, + "time": "2022-11-09T17:38:00+00:00" + }, + { + "name": "utopia-php/platform", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/platform.git", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/fe9f64420957dc8fb6201d22b499572f021411e4", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-redis": "*", + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.25.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Platform\\": "src/Platform" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Light and Fast Platform Library", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/platform/issues", + "source": "https://github.com/utopia-php/platform/tree/0.3.1" + }, + "time": "2022-11-10T07:04:24+00:00" + }, + { + "name": "utopia-php/pools", + "version": "0.4.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/pools.git", + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/d2870ab74b31b7f4027799f082e85122154f8bed", + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.8.*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Pools\\": "src/Pools" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Team Appwrite", + "email": "team@appwrite.io" + } + ], + "description": "A simple library to manage connection pools", + "keywords": [ + "framework", + "php", + "pools", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/pools/issues", + "source": "https://github.com/utopia-php/pools/tree/0.4.2" + }, + "time": "2022-11-22T07:55:45+00:00" + }, + { + "name": "utopia-php/preloader", + "version": "0.2.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/preloader.git", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Preloader\\": "src/Preloader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "team@appwrite.io" + } + ], + "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", + "keywords": [ + "framework", + "php", + "preload", + "preloader", + "preloading", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/preloader/issues", + "source": "https://github.com/utopia-php/preloader/tree/0.2.4" + }, + "time": "2020-10-24T07:04:59+00:00" + }, + { + "name": "utopia-php/queue", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/queue.git", + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/4b39e1f232b2e619b0d7fb4004f2356df334ddc1", + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "^0.2.3", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.8.8", + "workerman/workerman": "^4.0" + }, + "suggest": { + "ext-swoole": "Needed to support Swoole.", + "workerman/workerman": "Needed to support Workerman." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Queue\\": "src/Queue" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A powerful task queue.", + "keywords": [ + "Tasks", + "framework", + "php", + "queue", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/queue/issues", + "source": "https://github.com/utopia-php/queue/tree/0.5.1" + }, + "time": "2022-11-16T19:47:26+00:00" + }, + { + "name": "utopia-php/registry", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/registry.git", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Registry\\": "src/Registry" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple dependency management library for PHP", + "keywords": [ + "dependency management", + "di", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/registry/issues", + "source": "https://github.com/utopia-php/registry/tree/0.5.0" + }, + "time": "2021-03-10T10:45:22+00:00" + }, + { + "name": "utopia-php/storage", + "version": "0.13.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/storage.git", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/ad1c00f24ca56e73888acc2af3deee4919b1194b", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-zlib": "*", + "ext-zstd": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Storage\\": "src/Storage" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Storage library to manage application storage", + "keywords": [ + "framework", + "php", + "storage", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/storage/issues", + "source": "https://github.com/utopia-php/storage/tree/0.13.2" + }, + "time": "2022-12-20T11:11:35+00:00" + }, + { + "name": "utopia-php/swoole", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/swoole.git", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "shasum": "" + }, + "require": { + "ext-swoole": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "swoole/ide-helper": "4.8.3", + "vimeo/psalm": "4.15.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Swoole\\": "src/Swoole" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", + "keywords": [ + "framework", + "http", + "php", + "server", + "swoole", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/swoole/issues", + "source": "https://github.com/utopia-php/swoole/tree/0.5.0" + }, + "time": "2022-10-19T22:19:07+00:00" + }, + { + "name": "utopia-php/system", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/system.git", + "reference": "289c4327713deadc9c748b5317d248133a02f245" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", + "reference": "289c4327713deadc9c748b5317d248133a02f245", + "shasum": "" + }, + "require": { + "laravel/pint": "1.2.*", + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\System\\": "src/System" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library for obtaining information about the host's system.", + "keywords": [ + "framework", + "php", + "system", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/system/issues", + "source": "https://github.com/utopia-php/system/tree/0.6.0" + }, + "time": "2022-11-07T13:51:59+00:00" + }, + { + "name": "utopia-php/websocket", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/websocket.git", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.6.6", + "textalk/websocket": "1.5.2", + "vimeo/psalm": "^4.8.1", + "workerman/workerman": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\WebSocket\\": "src/WebSocket" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple abstraction for WebSocket servers.", + "keywords": [ + "framework", + "php", + "upf", + "utopia", + "websocket" + ], + "support": { + "issues": "https://github.com/utopia-php/websocket/issues", + "source": "https://github.com/utopia-php/websocket/tree/0.1.0" + }, + "time": "2021-12-20T10:50:09+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "appwrite/sdk-generator", + "version": "0.28.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/sdk-generator.git", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "matthiasmullie/minify": "^1.3.68", + "php": ">=7.0.0", + "twig/twig": "^3.4.1" + }, + "require-dev": { + "brianium/paratest": "^6.4", + "phpunit/phpunit": "^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\SDK\\": "src/SDK", + "Appwrite\\Spec\\": "src/Spec" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", + "support": { + "issues": "https://github.com/appwrite/sdk-generator/issues", + "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" + }, + "time": "2022-09-22T09:15:54+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.14.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "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": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.14.2" + }, + "time": "2022-12-15T06:48:22+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "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/v1.0.0" + }, + "time": "2022-05-02T15:47:09+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "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.22" + }, + "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.4.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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "doctrine/lexer", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "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.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%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-14T08:49:07+00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.70", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" + }, + "suggest": { + "psr/cache-implementation": "Cache implementation to use with Minify::cache" + }, + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "https://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", + "homepage": "https://github.com/matthiasmullie/minify", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2022-12-09T12:56:44+00:00" + }, + { + "name": "matthiasmullie/path-converter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/path-converter.git", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\PathConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "pathconverter@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Relative path converter", + "homepage": "http://github.com/matthiasmullie/path-converter", + "keywords": [ + "converter", + "path", + "paths", + "relative" + ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, + "time": "2019-02-05T23:41:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + }, + "time": "2022-11-12T15:38:23+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpbench/container", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpbench/container.git", + "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/container/zipball/6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", + "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", + "shasum": "" + }, + "require": { + "psr/container": "^1.0|^2.0", + "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpBench\\DependencyInjection\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "Simple, configurable, service container.", + "support": { + "issues": "https://github.com/phpbench/container/issues", + "source": "https://github.com/phpbench/container/tree/2.2.1" + }, + "time": "2022-01-25T10:17:35+00:00" + }, + { + "name": "phpbench/dom", + "version": "0.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpbench/dom.git", + "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/dom/zipball/b013b717832ddbaadf2a40984b04bc66af9a7110", + "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^7.2||^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.18", + "phpstan/phpstan": "^0.12.83", + "phpunit/phpunit": "^8.0||^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpBench\\Dom\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "DOM wrapper to simplify working with the PHP DOM implementation", + "support": { + "issues": "https://github.com/phpbench/dom/issues", + "source": "https://github.com/phpbench/dom/tree/0.3.2" + }, + "time": "2021-09-24T15:26:07+00:00" + }, + { + "name": "phpbench/phpbench", + "version": "1.2.7", + "source": { + "type": "git", + "url": "https://github.com/phpbench/phpbench.git", + "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/phpbench/zipball/dce145304abbb16c8d9af69c19d96f47e9d0e670", + "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.13", + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "ext-tokenizer": "*", + "php": "^7.3 || ^8.0", + "phpbench/container": "^2.1", + "phpbench/dom": "~0.3.1", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "seld/jsonlint": "^1.1", + "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/filesystem": "^4.2 || ^5.0 || ^6.0", + "symfony/finder": "^4.2 || ^5.0 || ^6.0", + "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0", + "symfony/process": "^4.2 || ^5.0 || ^6.0", + "webmozart/glob": "^4.6" + }, + "require-dev": { + "dantleech/invoke": "^2.0", + "friendsofphp/php-cs-fixer": "^3.0", + "jangregor/phpstan-prophecy": "^1.0", + "phpspec/prophecy": "^1.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5.8 || ^9.0", + "symfony/error-handler": "^5.2 || ^6.0", + "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0" + }, + "suggest": { + "ext-xdebug": "For Xdebug profiling extension." + }, + "bin": [ + "bin/phpbench" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "files": [ + "lib/Report/Func/functions.php" + ], + "psr-4": { + "PhpBench\\": "lib/", + "PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "PHP Benchmarking Framework", + "support": { + "issues": "https://github.com/phpbench/phpbench/issues", + "source": "https://github.com/phpbench/phpbench/tree/1.2.7" + }, + "funding": [ + { + "url": "https://github.com/dantleech", + "type": "github" + } + ], + "time": "2022-10-15T09:57:51+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" + }, + "time": "2022-11-29T15:06:56+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.22", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df", + "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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 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", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-12-18T16:40:55+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+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": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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 calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "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", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "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/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library 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/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "4211420d25eba80712bff236a98960ef68b866b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", + "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2022-04-01T13:37:23+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "4.8.9", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "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/4.8.9" + }, + "funding": [ + { + "url": "https://gitee.com/swoole/swoole?donate=true", + "type": "custom" + }, + { + "url": "https://github.com/swoole", + "type": "github" + } + ], + "time": "2022-04-18T20:38:04+00:00" + }, + { + "name": "symfony/console", + "version": "v5.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", + "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "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/v5.4.16" + }, + "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": "2022-11-25T14:09:27+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.13" + }, + "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": "2022-09-21T19:53:16+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.11" + }, + "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": "2022-07-29T07:37:50+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.11" + }, + "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": "2022-07-20T13:00:38+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.11" + }, + "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": "2022-06-27T16:58:25+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-25T10:21:52+00:00" + }, + { + "name": "symfony/string", + "version": "v6.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "863219fd713fa41cbcd285a79723f94672faff4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", + "reference": "863219fd713fa41cbcd285a79723f94672faff4d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "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.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.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/v6.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T16:11:27+00:00" + }, + { + "name": "textalk/websocket", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/Textalk/websocket-php.git", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "shasum": "" + }, + "require": { + "php": "^7.2 | ^8.0", + "psr/log": "^1 | ^2 | ^3" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "soren@abicart.se" + } + ], + "description": "WebSocket client and server", + "support": { + "issues": "https://github.com/Textalk/websocket-php/issues", + "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" + }, + "time": "2022-03-29T09:46:59+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "twig/twig", + "version": "v3.4.3", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2022-09-28T08:42:51+00:00" + }, + { + "name": "webmozart/glob", + "version": "4.6.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/glob.git", + "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655", + "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/filesystem": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Glob\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A PHP implementation of Ant's glob.", + "support": { + "issues": "https://github.com/webmozarts/glob/issues", + "source": "https://github.com/webmozarts/glob/tree/4.6.0" + }, + "time": "2022-05-24T19:45:58+00:00" + } + ], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "alias": "0.8.1", + "alias_normalized": "0.8.1.0" + } + ], + "minimum-stability": "stable", + "stability-flags": { + "utopia-php/cache": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0.0", + "ext-curl": "*", + "ext-imagick": "*", + "ext-mbstring": "*", + "ext-json": "*", + "ext-yaml": "*", + "ext-dom": "*", + "ext-redis": "*", + "ext-swoole": "*", + "ext-pdo": "*", + "ext-openssl": "*", + "ext-zlib": "*", + "ext-sockets": "*" + }, + "platform-dev": { + "ext-fileinfo": "*" + }, + "platform-overrides": { + "php": "8.0" + }, + "plugin-api-version": "2.2.0" +} From 8066aecc1e6d5ab7474e60adfba3f3505de37e52 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 14:07:27 +0200 Subject: [PATCH 41/87] adding realtime region sync --- composer.lock | 64 +++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/composer.lock b/composer.lock index 7adb8c2109..f35a9b4408 100644 --- a/composer.lock +++ b/composer.lock @@ -1689,12 +1689,12 @@ "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "8fe6270a9f9aebd24c77167d6d507edc2dd47eb0" + "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/8fe6270a9f9aebd24c77167d6d507edc2dd47eb0", - "reference": "8fe6270a9f9aebd24c77167d6d507edc2dd47eb0", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", + "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", "shasum": "" }, "require": { @@ -1719,12 +1719,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], "description": "A simple cache library to manage application cache storing, loading and purging", "keywords": [ "cache", @@ -1737,7 +1731,7 @@ "issues": "https://github.com/utopia-php/cache/issues", "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" }, - "time": "2022-12-26T17:56:21+00:00" + "time": "2022-12-27T10:47:29+00:00" }, { "name": "utopia-php/cli", @@ -3954,16 +3948,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.22", + "version": "9.2.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df" + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e4bf60d2220b4baaa0572986b5d69870226b06df", - "reference": "e4bf60d2220b4baaa0572986b5d69870226b06df", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", "shasum": "" }, "require": { @@ -4019,7 +4013,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.22" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" }, "funding": [ { @@ -4027,7 +4021,7 @@ "type": "github" } ], - "time": "2022-12-18T16:40:55+00:00" + "time": "2022-12-28T12:41:10+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5603,16 +5597,16 @@ }, { "name": "symfony/console", - "version": "v5.4.16", + "version": "v5.4.17", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef" + "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", - "reference": "8e9b9c8dfb33af6057c94e1b44846bee700dc5ef", + "url": "https://api.github.com/repos/symfony/console/zipball/58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", + "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", "shasum": "" }, "require": { @@ -5682,7 +5676,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.16" + "source": "https://github.com/symfony/console/tree/v5.4.17" }, "funding": [ { @@ -5698,7 +5692,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T14:09:27+00:00" + "time": "2022-12-28T14:15:31+00:00" }, { "name": "symfony/filesystem", @@ -5766,16 +5760,16 @@ }, { "name": "symfony/finder", - "version": "v5.4.11", + "version": "v5.4.17", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + "reference": "40c08632019838dfb3350f18cf5563b8080055fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/40c08632019838dfb3350f18cf5563b8080055fc", + "reference": "40c08632019838dfb3350f18cf5563b8080055fc", "shasum": "" }, "require": { @@ -5809,7 +5803,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.11" + "source": "https://github.com/symfony/finder/tree/v5.4.17" }, "funding": [ { @@ -5825,7 +5819,7 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:37:50+00:00" + "time": "2022-12-22T10:31:03+00:00" }, { "name": "symfony/options-resolver", @@ -6722,16 +6716,16 @@ }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", "shasum": "" }, "require": { @@ -6746,7 +6740,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -6782,7 +6776,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.5.0" }, "funding": [ { @@ -6794,7 +6788,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2022-12-27T12:28:18+00:00" }, { "name": "webmozart/glob", From f2b6d72511fc704451dbeffed23d347239a1ac2e Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 14:07:50 +0200 Subject: [PATCH 42/87] adding realtime region sync --- app/config/collections.php | 26 ++++++++++++-------------- app/controllers/api/edge.php | 20 +++++++++++++------- app/controllers/shared/api.php | 20 +++++++++++++++++++- docker-compose.yml | 2 +- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index 63703d62f1..ea5a2835f0 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -23,6 +23,15 @@ '$id' => ID::custom('syncs'), 'name' => 'Syncs', 'attributes' => [ + [ + '$id' => ID::custom('type'), + 'type' => Database::VAR_STRING, + 'size' => 256, + 'required' => true, + 'signed' => true, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('region'), 'type' => Database::VAR_STRING, @@ -42,7 +51,7 @@ 'filters' => [], ], [ - '$id' => ID::custom('keys'), + '$id' => ID::custom('key'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => 16384, @@ -61,23 +70,12 @@ 'array' => false, 'filters' => [], ], - [ - '$id' => ID::custom('payload'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => true, - 'default' => [], - 'array' => false, - 'filters' => ['json'], - ], ], 'indexes' => [ [ - '$id' => ID::custom('_key_status'), + '$id' => ID::custom('_key_type_status'), 'type' => Database::INDEX_KEY, - 'attributes' => ['status'], + 'attributes' => ['type', 'status'], 'lengths' => [], 'orders' => [], ], diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index b04c26972e..1450e54aaa 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -6,10 +6,13 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; +use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Queue\Client; use Utopia\Validator\ArrayList; +use Utopia\Validator\Assoc; use Utopia\Validator\Text; +use Utopia\Validator\WhiteList; App::init() ->groups(['edge']) @@ -30,20 +33,23 @@ ->desc('Purge cache keys') ->groups(['edge']) ->label('scope', 'public') - ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys. an array containing alphanumerical cache keys') + ->param('keys', '', new ArrayList(new Assoc(), 500), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') ->inject('queueForCacheSyncIn') ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncIn) { - if (empty($keys)) { + //if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - } + //} - $queueForCacheSyncIn - ->enqueue([ - 'keys' => $keys - ]); + foreach ($keys as $sync) { + $queueForCacheSyncIn + ->enqueue([ + 'type' => $sync['type'], + 'key' => $sync['key'] + ]); + } $response->dynamic(new Document([ 'keys' => $keys diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index db35cebc65..48055073d1 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -22,6 +22,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; +use Utopia\Queue\Client; $parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) { preg_match_all('/{(.*?)}/', $label, $matches); @@ -333,7 +334,8 @@ ->inject('mode') ->inject('dbForProject') ->inject('queueForFunctions') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions) use ($parseLabel) { + ->inject('queueForCacheSyncOut') + ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions, Client $queueForCacheSyncOut) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -388,6 +390,21 @@ 'userId' => $events->getParam('userId') ] ); + + $queueForCacheSyncOut->enqueue([ + 'type' => 'realtime', + 'key' => [ + 'projectId' => $target['projectId'] ?? $project->getId(), + 'payload' => $events->getPayload(), + 'events' => $allEvents, + 'channels' => $target['channels'], + 'roles' => $target['roles'], + 'options' => [ + 'permissionsChanged' => $target['permissionsChanged'], + 'userId' => $events->getParam('userId') + ] + ] + ]); } } @@ -511,6 +528,7 @@ $fileSize = 0; $file = $request->getFiles('file'); + if (!empty($file)) { $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; } diff --git a/docker-compose.yml b/docker-compose.yml index 43e9f48ad2..d983a834d2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -85,7 +85,7 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev - + - ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework #- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb From 49f52c8efec945b353b78032505114ff5a4f150d Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 14:08:30 +0200 Subject: [PATCH 43/87] adding realtime region sync --- app/workers/sync-In.php | 31 ++++++++++++++++----- app/workers/sync-out.php | 59 ++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index e11daa38e8..08f98c55ae 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -2,6 +2,7 @@ require_once __DIR__ . '/../worker.php'; +use Appwrite\Messaging\Adapter\Realtime; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -12,16 +13,32 @@ ->inject('message') ->inject('cache') ->action(function (Message $message, Cache $cache) { + $payload = $message->getPayload(); + $type = $payload['type']; + $key = $payload['key']; $time = DateTime::now(); - $cache->setListenersStatus(false); - - foreach ($message->getPayload()['keys'] ?? [] as $key) { - Console::log("[{$time}] Purging {$key}"); - $cache->purge($key); + switch ($type) { + case 'cache': + $cache->setListenersStatus(false); + Console::log("[{$time}] Purging cache key {$key}"); + $cache->purge($key); + $cache->setListenersStatus(true); + break; + case 'realtime': + Console::log("[{$time}] Sending realtime message"); + Realtime::send( + projectId: $key['projectId'], + payload: $key['payload'], + events: $key['events'], + channels: $key['channels'], + roles: $key['roles'], + options: $key['options'] + ); + break; + default: + break; } - - $cache->setListenersStatus(true); }); $server diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 88d9b54ab1..9dc3092e19 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -34,12 +34,12 @@ /** * @param string $url * @param string $token - * @param array $stack + * @param array $payload * @return array */ -function call(string $url, string $token, array $stack): array +function call(string $url, string $token, array $payload): array { - $payload = []; + $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, @@ -48,18 +48,14 @@ function call(string $url, string $token, array $stack): array curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($stack)); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { $response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $payload = [ - 'status' => $status, - 'payload' => json_decode($response, true) - ]; if ($status === 200) { - return $payload; + return $status; } sleep(1); @@ -67,7 +63,7 @@ function call(string $url, string $token, array $stack): array curl_close($ch); - return $payload; + return $status; } /** @@ -75,7 +71,7 @@ function call(string $url, string $token, array $stack): array * @throws Structure * @throws Exception|\Exception */ -function handle($dbForConsole, $regions, $stack): void +function handle($dbForConsole, $regions, $payload): void { $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); @@ -83,17 +79,18 @@ function handle($dbForConsole, $regions, $stack): void foreach ($regions as $code => $region) { $time = DateTime::now(); - $response = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $stack]); - if ($response['status'] !== Response::STATUS_CODE_OK) { - Console::error("[{$time}] Request to {$code} has failed"); - - $dbForConsole->createDocument('sync', new Document([ + $status = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $payload]); + if ($status !== Response::STATUS_CODE_OK) { + Console::error("[{$time}] Request to {$code} has failed"); + foreach ($payload as $sync) { + $dbForConsole->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION'), 'target' => $code, - 'keys' => $stack, - 'status' => $response['status'], - 'payload' => $response['payload'], + 'type' => $sync['type'], + 'key' => $sync['key'], + 'status' => $status, ])); + } } } } @@ -103,8 +100,14 @@ function handle($dbForConsole, $regions, $stack): void ->action(function (Message $message) use (&$stack, &$failures) { $payload = $message->getPayload() ?? []; + $type = $payload['type'] ?? null; - if (!empty($payload['keys'])) { + if (empty($type)) { + return; + } + + //Get failed requests + if (!empty($payload['region']) && !empty($payload['keys'])) { $regions = array_filter( Config::getParam('regions', []), fn ($region) => $payload['region'] === $region, @@ -115,12 +118,15 @@ function handle($dbForConsole, $regions, $stack): void 'regions' => $regions, 'keys' => $payload['keys'] ]; + + return; } if (!empty($payload['key'])) { - if (!in_array($payload['key'], $stack['keys'] ?? [])) { - $stack['keys'][] = $payload['key']; - } + $stack['keys'][] = [ + 'type' => $payload['type'], + 'key' => $payload['key'], + ]; } }); @@ -137,6 +143,7 @@ function handle($dbForConsole, $regions, $stack): void return; } + //Send failed requests if (count($failures) > 0) { $i = 0; while ($i < count($failures)) { @@ -147,12 +154,12 @@ function handle($dbForConsole, $regions, $stack): void } return; } - - $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS); + //var_dump($stack['keys']); + $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS, true); + //var_dump($chunk); array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); Console::log("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); handle($dbForConsole, $stack['regions'], $chunk); - $chunk = []; }); Console::success("Out [" . App::getEnv('_APP_REGION') . "] edge cache purging worker Started"); }); From 3e155cbe3ffb87bc2a29a9a614ddc69284ec731c Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 14:08:53 +0200 Subject: [PATCH 44/87] adding realtime region sync --- src/Appwrite/Platform/Tasks/EdgeSync.php | 67 +++++++++++++++--------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index db2ba03924..cdc99136b1 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Tasks; use Utopia\App; +use Utopia\Config\Config; use Utopia\Platform\Action; use Utopia\CLI\Console; use Utopia\Database\DateTime; @@ -33,40 +34,56 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); - $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $dbForConsole, $queueForCacheSyncOut) { + $regions = array_filter( + Config::getParam('regions', []), + fn ($region) => App::getEnv('_APP_REGION') !== $region + && $region !== 'default', + ARRAY_FILTER_USE_KEY + ); + $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); + Console::loop(function () use ($interval, $dbForConsole, $queueForCacheSyncOut, $regions) { $time = DateTime::now(); - $count = 0; - $chunk = 0; - $limit = 50; - $sum = $limit; Console::success("[{$time}] New task every {$interval} seconds"); - while ($sum === $limit) { - $chunk++; - - $results = $dbForConsole->find('syncs', [ - Query::equal('region', [App::getEnv('_APP_REGION')]), - Query::limit($limit) - ]); + foreach ($regions as $target) { + $count = 0; + $chunk = 0; + $limit = 50; + $sum = $limit; + $keys = []; + while ($sum === $limit) { + $chunk++; - $sum = count($results); - if ($sum > 0) { - foreach ($results as $document) { - Console::info("[{$time}] Enqueueing keys chunk {$count} to {$document->getAttribute('target')}"); - $queueForCacheSyncOut - ->enqueue([ - 'region' => $document->getAttribute('target'), - 'keys' => $document->getAttribute('keys') - ]); + $results = $dbForConsole->find('syncs', [ + Query::equal('region', [App::getEnv('_APP_REGION')]), + Query::equal('target', [$target]), + Query::limit($limit) + ]); - $dbForConsole->deleteDocument('syncs', $document->getId()); - $count++; + $sum = count($results); + if ($sum > 0) { + foreach ($results as $document) { + $keys[] = [ + 'type' => $document->getAttribute('type'), + 'key' => $document->getAttribute('key') + ]; + $dbForConsole->deleteDocument('syncs', $document->getId()); + $count++; + } } + } + + if (!empty($keys)) { + Console::info("[{$time}] Enqueueing keys chunk {$count} to {$target}"); + $queueForCacheSyncOut + ->enqueue([ + 'region' => $target, + 'keys' => $keys + ]); } else { - Console::info("[{$time}] No cache keys where found."); + Console::info("[{$time}] No cache keys where found."); } } }, $interval); From a5b0b8016aafb96568f4fa8987396f4ae8ed2012 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 14:09:23 +0200 Subject: [PATCH 45/87] adding realtime region sync --- phpbench.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpbench.json b/phpbench.json index 217a122706..e386851984 100644 --- a/phpbench.json +++ b/phpbench.json @@ -3,7 +3,7 @@ "runner.path": "tests/benchmarks", "runner.file_pattern": "*Bench.php", "runner.bootstrap": "app/init.php", - "runner.revs": 2000, + "runner.revs": 1000, "runner.iterations": 3, "runner.retry_threshold": 5, "runner.warmup": 1, From dc62d7ff87d22ec24712ad7814d2d43c2d8f1448 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 17:47:26 +0200 Subject: [PATCH 46/87] adding realtime region sync --- app/console | 2 +- app/controllers/api/edge.php | 4 ++-- app/workers/sync-out.php | 19 +++++++++---------- src/Appwrite/Platform/Tasks/EdgeSync.php | 13 +++++++------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/console b/app/console index b1a81a390a..af3d741ae8 160000 --- a/app/console +++ b/app/console @@ -1 +1 @@ -Subproject commit b1a81a390a05746701651fca49e0d853f430677c +Subproject commit af3d741ae8f02c2e16b8b4ea4664a3f8970290fd diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 1450e54aaa..d7ef222b1e 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -39,9 +39,9 @@ ->inject('queueForCacheSyncIn') ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncIn) { - //if (empty($keys)) { + if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); - //} + } foreach ($keys as $sync) { $queueForCacheSyncIn diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 9dc3092e19..39e76a5d77 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -35,9 +35,9 @@ * @param string $url * @param string $token * @param array $payload - * @return array + * @return int */ -function call(string $url, string $token, array $payload): array +function call(string $url, string $token, array $payload): int { $ch = curl_init($url); @@ -82,12 +82,13 @@ function handle($dbForConsole, $regions, $payload): void $status = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $payload]); if ($status !== Response::STATUS_CODE_OK) { Console::error("[{$time}] Request to {$code} has failed"); + foreach ($payload as $sync) { $dbForConsole->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION'), 'target' => $code, 'type' => $sync['type'], - 'key' => $sync['key'], + 'key' => ['key' => $sync['key']], 'status' => $status, ])); } @@ -100,11 +101,6 @@ function handle($dbForConsole, $regions, $payload): void ->action(function (Message $message) use (&$stack, &$failures) { $payload = $message->getPayload() ?? []; - $type = $payload['type'] ?? null; - - if (empty($type)) { - return; - } //Get failed requests if (!empty($payload['region']) && !empty($payload['keys'])) { @@ -122,6 +118,10 @@ function handle($dbForConsole, $regions, $payload): void return; } + if (empty($payload['type'])) { + return; + } + if (!empty($payload['key'])) { $stack['keys'][] = [ 'type' => $payload['type'], @@ -154,9 +154,8 @@ function handle($dbForConsole, $regions, $payload): void } return; } - //var_dump($stack['keys']); + $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS, true); - //var_dump($chunk); array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); Console::log("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); handle($dbForConsole, $stack['regions'], $chunk); diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index cdc99136b1..7ffd8e24f2 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -47,7 +47,7 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac Console::success("[{$time}] New task every {$interval} seconds"); - foreach ($regions as $target) { + foreach ($regions as $code => $region) { $count = 0; $chunk = 0; $limit = 50; @@ -58,16 +58,17 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac $results = $dbForConsole->find('syncs', [ Query::equal('region', [App::getEnv('_APP_REGION')]), - Query::equal('target', [$target]), + Query::equal('target', [$code]), Query::limit($limit) ]); $sum = count($results); if ($sum > 0) { foreach ($results as $document) { + $key = $document->getAttribute('key'); $keys[] = [ 'type' => $document->getAttribute('type'), - 'key' => $document->getAttribute('key') + 'key' => $key['key'] ]; $dbForConsole->deleteDocument('syncs', $document->getId()); $count++; @@ -76,14 +77,14 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac } if (!empty($keys)) { - Console::info("[{$time}] Enqueueing keys chunk {$count} to {$target}"); + Console::info("[{$time}] Enqueueing keys chunk {$count} to region {$code}"); $queueForCacheSyncOut ->enqueue([ - 'region' => $target, + 'region' => $code, 'keys' => $keys ]); } else { - Console::info("[{$time}] No cache keys where found."); + Console::info("[{$time}] No keys where found for region {$code}."); } } }, $interval); From 0ce6c3d87651e0ab8a3059063715827644dcc395 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 17:49:27 +0200 Subject: [PATCH 47/87] adding realtime region sync --- .gitignore | 1 + ...48d223adf3eb006578a2d9d7e198f57d319de2.xml | 343 ++++++++++++++++++ ...48d228df2540513764244ed3ea7fa12c830e3b.xml | 225 ++++++++++++ ...48d2295de88eca5673e917696c25275adbb32f.xml | 343 ++++++++++++++++++ ...48d22a83131f30f97b0995a9f7850121897173.xml | 2 + 5 files changed, 914 insertions(+) create mode 100644 .phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml create mode 100644 .phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml create mode 100644 .phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml create mode 100644 .phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml diff --git a/.gitignore b/.gitignore index a0e910f79b..94980ebcd2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ debug/ app/sdks dev/yasd_init.php .phpunit.result.cache +/.phpbench/ diff --git a/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml b/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml new file mode 100644 index 0000000000..fb91dd425a --- /dev/null +++ b/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml @@ -0,0 +1,343 @@ + +Darwinshimons-MBP.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.0131130218505860.164985656738282.3658275604248Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4 on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4 on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5 on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5 on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4 on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4 on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1 on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1 on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2 on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2 on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG:41 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG on line 41 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG:41 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG on line 41 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ on line 45 + diff --git a/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml b/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml new file mode 100644 index 0000000000..f2144da500 --- /dev/null +++ b/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml @@ -0,0 +1,225 @@ + +Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.00882148742675780.157833099365232.0849704742432Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchdo6hr1(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchdo6hr1(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiAPK8b(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiAPK8b(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqtgupF(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqtgupF(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXyJcOh(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXyJcOh(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ9COCU(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ9COCU(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchALZsb9(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchALZsb9(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4hWAKX(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4hWAKX(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmKACZB(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmKACZB(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqT7puk(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqT7puk(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4zFK3b(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4zFK3b(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchT3w9P2(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchT3w9P2(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/FunctionsCustomServerBench.php(19): Tests\Benchmarks\Services\Functions\Base->createDeployment() +#3 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2a2bMx(49): Tests\Benchmarks\Services\Functions\FunctionsCustomServerBench->benchDeploymentCreate(Array) +#4 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/FunctionsCustomServerBench.php(19): Tests\Benchmarks\Services\Functions\Base->createDeployment() +#3 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2a2bMx(49): Tests\Benchmarks\Services\Functions\FunctionsCustomServerBench->benchDeploymentCreate(Array) +#4 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchs1V82s(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + +Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 +Stack trace: +#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) +#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) +#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchs1V82s(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) +#3 {main} + thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 + diff --git a/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml b/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml new file mode 100644 index 0000000000..145c662162 --- /dev/null +++ b/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml @@ -0,0 +1,343 @@ + +Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.0100135803222660.15306472778322.2110939025879Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675 on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675 on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5 on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5 on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1 on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1 on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9 on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9 on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9 on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9 on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S on line 44 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S:44 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S on line 44 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc:41 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc on line 41 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc:41 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc on line 41 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv on line 42 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv:42 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv on line 42 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl on line 45 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU on line 43 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU:43 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU on line 43 +Benchmarking script exited with code 255 + +PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw on line 45 + +Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw:45 +Stack trace: +#0 {main} + thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw on line 45 + diff --git a/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml b/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml new file mode 100644 index 0000000000..099532582b --- /dev/null +++ b/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml @@ -0,0 +1,2 @@ + +Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.00905990600585940.159025192260742.3550987243652 From 345230e251c1d5fa47bb76329733605ca38f141e Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 2 Jan 2023 17:51:23 +0200 Subject: [PATCH 48/87] adding realtime region sync --- app/init.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/init.php b/app/init.php index f57c773861..e95e71fe51 100644 --- a/app/init.php +++ b/app/init.php @@ -1094,6 +1094,7 @@ function (mixed $value) { $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForCacheSyncOut) { $queueForCacheSyncOut ->enqueue([ + 'type' => 'cache', 'key' => $key ]); }); @@ -1101,6 +1102,7 @@ function (mixed $value) { $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { $queueForCacheSyncOut ->enqueue([ + 'type' => 'cache', 'key' => $key ]); }); From 4288261c2570dfc520c74f810d41b5df8bd3544e Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 3 Jan 2023 10:08:39 +0200 Subject: [PATCH 49/87] adding realtime region sync --- ...48d223adf3eb006578a2d9d7e198f57d319de2.xml | 343 ------------------ ...48d228df2540513764244ed3ea7fa12c830e3b.xml | 225 ------------ ...48d2295de88eca5673e917696c25275adbb32f.xml | 343 ------------------ ...48d22a83131f30f97b0995a9f7850121897173.xml | 2 - app/controllers/shared/api.php | 2 +- app/worker.php | 2 - 6 files changed, 1 insertion(+), 916 deletions(-) delete mode 100644 .phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml delete mode 100644 .phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml delete mode 100644 .phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml delete mode 100644 .phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml diff --git a/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml b/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml deleted file mode 100644 index fb91dd425a..0000000000 --- a/.phpbench/storage/7e6/c/12/1348d223adf3eb006578a2d9d7e198f57d319de2.xml +++ /dev/null @@ -1,343 +0,0 @@ - -Darwinshimons-MBP.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.0131130218505860.164985656738282.3658275604248Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheQBGuc on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchry8tcK on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFkkueC on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4 on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchjOX0k4 on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbAYw1V on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchJc2UVG on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3bcLiZ on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchS11CsZ on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwB1a7p on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchum6bLU on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5 on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRqq7a5 on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchlSePFX on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4 on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchONgvy4 on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp5ny4V on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1 on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchVybVP1 on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYZxhup on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchcMwCdc on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchGFNSfZ on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchSH648y on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgYYRYt on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2NHjrk on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2 on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchm7gCN2 on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG:41 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG on line 41 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG:41 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench6cmRFG on line 41 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv8mDbs on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchl239bh on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchvHefoZ on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9YrUiF on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAj9ZeN on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnXBGgm on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4Ap42h on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench3cH9rJ on line 45 - diff --git a/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml b/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml deleted file mode 100644 index f2144da500..0000000000 --- a/.phpbench/storage/7e6/c/12/1348d228df2540513764244ed3ea7fa12c830e3b.xml +++ /dev/null @@ -1,225 +0,0 @@ - -Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.00882148742675780.157833099365232.0849704742432Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchdo6hr1(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchdo6hr1(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiAPK8b(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiAPK8b(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqtgupF(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqtgupF(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXyJcOh(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXyJcOh(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ9COCU(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ9COCU(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchALZsb9(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(34): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchALZsb9(48): Tests\Benchmarks\Services\Storage\Base->benchFileCreate(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4hWAKX(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4hWAKX(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmKACZB(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmKACZB(44): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqT7puk(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqT7puk(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4zFK3b(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Storage/Base.php(110): Tests\E2E\Client->call('POST', '/storage/bucket...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4zFK3b(43): Tests\Benchmarks\Services\Storage\Base->createFiles(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchT3w9P2(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchT3w9P2(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/FunctionsCustomServerBench.php(19): Tests\Benchmarks\Services\Functions\Base->createDeployment() -#3 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2a2bMx(49): Tests\Benchmarks\Services\Functions\FunctionsCustomServerBench->benchDeploymentCreate(Array) -#4 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/FunctionsCustomServerBench.php(19): Tests\Benchmarks\Services\Functions\Base->createDeployment() -#3 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench2a2bMx(49): Tests\Benchmarks\Services\Functions\FunctionsCustomServerBench->benchDeploymentCreate(Array) -#4 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchs1V82s(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - -Fatal error: Uncaught ValueError: Path cannot be empty in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php:216 -Stack trace: -#0 /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php(216): curl_setopt(Object(CurlHandle), 10015, Array) -#1 /Users/shimon/PhpstormProjects/appwrite/tests/benchmarks/Services/Functions/Base.php(74): Tests\E2E\Client->call('POST', '/functions/639e...', Array, Array) -#2 /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchs1V82s(45): Tests\Benchmarks\Services\Functions\Base->createDeployment(Array) -#3 {main} - thrown in /Users/shimon/PhpstormProjects/appwrite/tests/e2e/Client.php on line 216 - diff --git a/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml b/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml deleted file mode 100644 index 145c662162..0000000000 --- a/.phpbench/storage/7e6/c/12/1348d2295de88eca5673e917696c25275adbb32f.xml +++ /dev/null @@ -1,343 +0,0 @@ - -Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.0100135803222660.15306472778322.2110939025879Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675 on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchZ5b675 on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5 on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench4u3IB5 on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1 on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchsZgeq1 on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchqE0JdC on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9 on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBencheZLAa9 on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchIlFsCM on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchYtJuTT on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchxxY5DD on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchwDArkF on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchtNBFNs on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchWJVbfc on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchbR0JkD on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchujmIJP on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchp3OR3E on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchXn1h5d on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchFvo8gu on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchmgD6QC on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9 on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchAp5Aw9 on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchyGH9er on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S on line 44 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S:44 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchMjWI1S on line 44 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench0s2VEn on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench5KF7Db on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc:41 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc on line 41 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc:41 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnMr4Nc on line 41 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchv0mHEM on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchgkNz6Z on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchU91UlE on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBench9TJdLy on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv on line 42 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv:42 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchnxOSJv on line 42 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchiFrJDl on line 45 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU on line 43 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU:43 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchQXarZU on line 43 -Benchmarking script exited with code 255 - -PHP Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw on line 45 - -Fatal error: Uncaught Error: Call to protected method Tests\E2E\Scopes\Scope::setUp() from global scope in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw:45 -Stack trace: -#0 {main} - thrown in /private/var/folders/rb/_mcfgdss43337_gvkgz360d40000gn/T/PhpBenchRAObyw on line 45 - diff --git a/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml b/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml deleted file mode 100644 index 099532582b..0000000000 --- a/.phpbench/storage/7e6/c/12/1348d22a83131f30f97b0995a9f7850121897173.xml +++ /dev/null @@ -1,2 +0,0 @@ - -Darwinshimons-MBP-2.lan21.2.0Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000arm648.1.4/opt/homebrew/etc/php/8.1/php.iniCore, date, libxml, openssl, pcre, sqlite3, zlib, bcmath, bz2, calendar, ctype, curl, dba, dom, hash, FFI, fileinfo, filter, ftp, gd, gettext, gmp, json, iconv, intl, SPL, ldap, mbstring, session, standard, odbc, pcntl, exif, mysqlnd, PDO, pdo_dblib, pdo_mysql, PDO_ODBC, pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, pspell, readline, Reflection, mysqli, shmop, SimpleXML, soap, sockets, sodium, sysvmsg, sysvsem, sysvshm, tidy, tokenizer, xml, xmlreader, xmlwriter, xsl, zip, Zend OPcache1gitfeat-new-usage-statse748bb20e4fbabeb599c70a609eabc0df9aad8580.00905990600585940.159025192260742.3550987243652 diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 48055073d1..f9b91e588d 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -390,7 +390,7 @@ 'userId' => $events->getParam('userId') ] ); - + //Sync with other regions $queueForCacheSyncOut->enqueue([ 'type' => 'realtime', 'key' => [ diff --git a/app/worker.php b/app/worker.php index 8705882845..8151381d4a 100644 --- a/app/worker.php +++ b/app/worker.php @@ -105,8 +105,6 @@ throw new Exception('Please configure "QUEUE" environemnt variable.'); } - -$workerNumber =1; $adapter = new Swoole($connection, $workerNumber, App::getEnv('QUEUE')); $server = new Server($adapter); From 8f230071c7975eb6270a5305582d1bac2b846616 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 3 Jan 2023 10:16:53 +0200 Subject: [PATCH 50/87] collection index update --- app/config/collections.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index f7be839c3c..052d8d1a48 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -73,9 +73,9 @@ ], 'indexes' => [ [ - '$id' => ID::custom('_key_type_status'), + '$id' => ID::custom('_key_region_target'), 'type' => Database::INDEX_KEY, - 'attributes' => ['type', 'status'], + 'attributes' => ['region', 'target'], 'lengths' => [], 'orders' => [], ], From 4f5f98356424c25e246655cc5eacef38f50d6fda Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 15:05:38 +0200 Subject: [PATCH 51/87] cert addition --- app/controllers/api/edge.php | 9 +- app/controllers/shared/api.php | 8 + app/worker.php | 29 +- app/workers/certificates.php | 585 +++++++++++++++-------------- app/workers/sync-In.php | 24 +- app/workers/sync-out.php | 43 ++- bin/worker-certificates | 9 +- docker-compose.yml | 2 + src/Appwrite/Event/Certificate.php | 10 +- 9 files changed, 399 insertions(+), 320 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index d7ef222b1e..18772fa7a1 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -33,7 +33,7 @@ ->desc('Purge cache keys') ->groups(['edge']) ->label('scope', 'public') - ->param('keys', '', new ArrayList(new Assoc(), 500), 'Cache keys. an array containing alphanumerical cache keys') + ->param('keys', '', new ArrayList(new Text(4056), 600), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') ->inject('queueForCacheSyncIn') @@ -43,11 +43,12 @@ throw new Exception(Exception::KEY_NOT_FOUND); } - foreach ($keys as $sync) { + foreach ($keys as $parts) { + $key = json_decode($parts); $queueForCacheSyncIn ->enqueue([ - 'type' => $sync['type'], - 'key' => $sync['key'] + 'type' => $key->type, + 'key' => $key->key ]); } diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index f9b91e588d..be9f01705e 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -408,6 +408,14 @@ } } +// $queueForCacheSyncOut->enqueue([ +// 'type' => 'certificate', +// 'key' => [ +// 'domain' => 'appwrite.io', +// 'contents' => base64_encode(file_get_contents(APP_STORAGE_CERTIFICATES . '/appwrite.io.tar.gz')), +// ] +// ]); + $route = $utopia->match($request); $requestParams = $route->getParamsValues(); $user = $audits->getUser(); diff --git a/app/worker.php b/app/worker.php index 8151381d4a..adf0745026 100644 --- a/app/worker.php +++ b/app/worker.php @@ -2,6 +2,7 @@ require_once __DIR__ . '/init.php'; +use Appwrite\Event\Certificate; use Appwrite\Event\Func; use Swoole\Runtime; use Utopia\App; @@ -11,7 +12,9 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; +use Utopia\Pools\Connection; use Utopia\Queue\Adapter\Swoole; +use Utopia\Queue\Client; use Utopia\Queue\Message; use Utopia\Queue\Server; use Utopia\Registry\Registry; @@ -75,15 +78,21 @@ return new Cache(new Sharding($adapters)); }, ['register']); -Server::setResource('queueForFunctions', function (Registry $register) { - $pools = $register->get('pools'); - return new Func( - $pools - ->get('queue') - ->pop() - ->getResource() - ); -}, ['register']); +Server::setResource('queue', function (Group $pools) { + return $pools->get('queue')->pop()->getResource(); +}, ['pools']); + +Server::setResource('queueForFunctions', function (Connection $queue) { + return new Func($queue); +}, ['queue']); + +Server::setResource('queueForCertificates', function (Connection $queue) { + return new Certificate($queue); +}, ['queue']); + +Server::setResource('queueForCacheSyncOut', function (Connection $queue) { + return new Client('v1-sync-out', $queue); +}, ['queue']); Server::setResource('logger', function ($register) { return $register->get('logger'); @@ -100,7 +109,7 @@ $pools = $register->get('pools'); $connection = $pools->get('queue')->pop()->getResource(); $workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); - +$workerNumber =1; if (empty(App::getEnv('QUEUE'))) { throw new Exception('Please configure "QUEUE" environemnt variable.'); } diff --git a/app/workers/certificates.php b/app/workers/certificates.php index b4f0701c46..631a87a969 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -1,42 +1,36 @@ dbForConsole = $this->getConsoleDB(); - - $skipCheck = $this->args['skipRenewCheck'] ?? false; // If true, we won't double-check expiry from cert file - $document = new Document($this->args['domain'] ?? []); - $domain = new Domain($document->getAttribute('domain', '')); - // Get current certificate - $certificate = $this->dbForConsole->findOne('certificates', [Query::equal('domain', [$domain->get()])]); + $certificate = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain->get()])]); // If we don't have certificate for domain yet, let's create new document. At the end we save it if (!$certificate) { @@ -90,14 +78,14 @@ public function run(): void } // Validate domain and DNS records. Skip if job is forced - if (!$skipCheck) { - $mainDomain = $this->getMainDomain(); + if (!$skipRenewCheck) { + $mainDomain = getMainDomain($dbForConsole); $isMainDomain = !isset($mainDomain) || $domain->get() === $mainDomain; - $this->validateDomain($domain, $isMainDomain); + validateDomain($domain, $isMainDomain); } // If certificate exists already, double-check expiry date. Skip if job is forced - if (!$skipCheck && !$this->isRenewRequired($domain->get())) { + if (!$skipRenewCheck && !isRenewRequired($domain->get())) { throw new Exception('Renew isn\'t required.'); } @@ -105,7 +93,7 @@ public function run(): void $folder = ID::unique(); // Generate certificate files using Let's Encrypt - $letsEncryptData = $this->issueCertificate($folder, $domain->get(), $email); + $letsEncryptData = issueCertificate($folder, $domain->get(), $email); // Command succeeded, store all data into document // We store stderr too, because it may include warnings @@ -115,12 +103,20 @@ public function run(): void ])); // Give certificates to Traefik - $this->applyCertificateFiles($folder, $domain->get(), $letsEncryptData); + applyCertificateFiles($folder, $domain->get(), $letsEncryptData); // Update certificate info stored in database - $certificate->setAttribute('renewDate', $this->getRenewDate($domain->get())); + $certificate->setAttribute('renewDate', getRenewDate($domain->get())); $certificate->setAttribute('attempts', 0); $certificate->setAttribute('issueDate', DateTime::now()); + + $queueForCacheSyncOut->enqueue([ + 'type' => 'certificate', + 'key' => [ + 'domain' => $domain, + 'contents' => base64_encode(file_get_contents(APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz')), + ] + ]); } catch (Throwable $e) { // Set exception as log in certificate document $certificate->setAttribute('log', $e->getMessage()); @@ -133,290 +129,319 @@ public function run(): void $certificate->setAttribute('renewDate', DateTime::now()); // Send email to security email - $this->notifyError($domain->get(), $e->getMessage(), $attempts); + notifyError($domain->get(), $e->getMessage(), $attempts); } finally { // All actions result in new updatedAt date $certificate->setAttribute('updated', DateTime::now()); // Save all changes we made to certificate document into database - $this->saveCertificateDocument($domain->get(), $certificate); + saveCertificateDocument($domain->get(), $certificate, $dbForConsole); } + }; +}); + + +/** + * Save certificate data into database. + * + * @param string $domain Domain name that certificate is for + * @param Document $certificate Certificate document that we need to save + * @param Database $dbForConsole Database connection for console + * + * @return void + */ +function saveCertificateDocument(string $domain, Document $certificate, Database $dbForConsole): void +{ + // Check if update or insert required + $certificateDocument = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]); + if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) { + // Merge new data with current data + $certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy())); + + $certificate = $dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); + } else { + $certificate = $dbForConsole->createDocument('certificates', $certificate); } - public function shutdown(): void - { - } + $certificateId = $certificate->getId(); + updateDomainDocuments($certificateId, $domain, $dbForConsole); +} - /** - * Save certificate data into database. - * - * @param string $domain Domain name that certificate is for - * @param Document $certificate Certificate document that we need to save - * - * @return void - */ - private function saveCertificateDocument(string $domain, Document $certificate): void - { - // Check if update or insert required - $certificateDocument = $this->dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]); - if (!empty($certificateDocument) && !$certificateDocument->isEmpty()) { - // Merge new data with current data - $certificate = new Document(\array_merge($certificateDocument->getArrayCopy(), $certificate->getArrayCopy())); - - $certificate = $this->dbForConsole->updateDocument('certificates', $certificate->getId(), $certificate); - } else { - $certificate = $this->dbForConsole->createDocument('certificates', $certificate); +/** + * Get main domain. Needed as we do different checks for main and non-main domains. + * + * @return null|string Returns main domain. If null, there is no main domain yet. + */ +function getMainDomain($dbForConsole): ?string +{ + $envDomain = App::getEnv('_APP_DOMAIN', ''); + if (!empty($envDomain) && $envDomain !== 'localhost') { + return $envDomain; + } else { + $domainDocument = $dbForConsole->findOne('domains', [Query::orderAsc('_id')]); + if ($domainDocument) { + return $domainDocument->getAttribute('domain'); } - - $certificateId = $certificate->getId(); - $this->updateDomainDocuments($certificateId, $domain); } - /** - * Get main domain. Needed as we do different checks for main and non-main domains. - * - * @return null|string Returns main domain. If null, there is no main domain yet. - */ - private function getMainDomain(): ?string - { - $envDomain = App::getEnv('_APP_DOMAIN', ''); - if (!empty($envDomain) && $envDomain !== 'localhost') { - return $envDomain; - } else { - $domainDocument = $this->dbForConsole->findOne('domains', [Query::orderAsc('_id')]); - if ($domainDocument) { - return $domainDocument->getAttribute('domain'); - } - } + return null; +} + +/** + * Internal domain validation functionality to prevent unnecessary attempts failed from Let's Encrypt side. We check: + * - Domain needs to be public and valid (prevents NFT domains that are not supported by Let's Encrypt) + * - Domain must have proper DNS record + * + * @param Domain $domain Domain which we validate + * @param bool $isMainDomain In case of master domain, we look for different DNS configurations + * + * @return void + */ +function validateDomain(Domain $domain, bool $isMainDomain): void +{ + if (empty($domain->get())) { + throw new Exception('Missing certificate domain.'); + } - return null; + if (!$domain->isKnown() || $domain->isTest()) { + throw new Exception('Unknown public suffix for domain.'); } - /** - * Internal domain validation functionality to prevent unnecessary attempts failed from Let's Encrypt side. We check: - * - Domain needs to be public and valid (prevents NFT domains that are not supported by Let's Encrypt) - * - Domain must have proper DNS record - * - * @param Domain $domain Domain which we validate - * @param bool $isMainDomain In case of master domain, we look for different DNS configurations - * - * @return void - */ - private function validateDomain(Domain $domain, bool $isMainDomain): void - { - if (empty($domain->get())) { - throw new Exception('Missing certificate domain.'); + if (!$isMainDomain) { + // TODO: Would be awesome to also support A/AAAA records here. Maybe dry run? + // Validate if domain target is properly configured + $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); + + if (!$target->isKnown() || $target->isTest()) { + throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.'); } - if (!$domain->isKnown() || $domain->isTest()) { - throw new Exception('Unknown public suffix for domain.'); + // Verify domain with DNS records + $validator = new CNAME($target->get()); + if (!$validator->isValid($domain->get())) { + throw new Exception('Failed to verify domain DNS records.'); } + } else { + // Main domain validation + // TODO: Would be awesome to check A/AAAA record here. Maybe dry run? + } +} - if (!$isMainDomain) { - // TODO: Would be awesome to also support A/AAAA records here. Maybe dry run? +/** + * Reads expiry date of certificate from file and decides if renewal is required or not. + * + * @param string $domain Domain for which we check certificate file + * + * @return bool True, if certificate needs to be renewed + */ +function isRenewRequired(string $domain): bool +{ + $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; + if (\file_exists($certPath)) { + $validTo = null; - // Validate if domain target is properly configured - $target = new Domain(App::getEnv('_APP_DOMAIN_TARGET', '')); + $certData = openssl_x509_parse(file_get_contents($certPath)); + $validTo = $certData['validTo_time_t'] ?? 0; - if (!$target->isKnown() || $target->isTest()) { - throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.'); - } + if (empty($validTo)) { + throw new Exception('Unable to read certificate file (cert.pem).'); + } - // Verify domain with DNS records - $validator = new CNAME($target->get()); - if (!$validator->isValid($domain->get())) { - throw new Exception('Failed to verify domain DNS records.'); - } - } else { - // Main domain validation - // TODO: Would be awesome to check A/AAAA record here. Maybe dry run? + // LetsEncrypt allows renewal 30 days before expiry + $expiryInAdvance = (60 * 60 * 24 * 30); + if ($validTo - $expiryInAdvance > \time()) { + return false; } } - /** - * Reads expiry date of certificate from file and decides if renewal is required or not. - * - * @param string $domain Domain for which we check certificate file - * - * @return bool True, if certificate needs to be renewed - */ - private function isRenewRequired(string $domain): bool - { - $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; - if (\file_exists($certPath)) { - $validTo = null; - - $certData = openssl_x509_parse(file_get_contents($certPath)); - $validTo = $certData['validTo_time_t'] ?? 0; - - if (empty($validTo)) { - throw new Exception('Unable to read certificate file (cert.pem).'); - } + return true; +} - // LetsEncrypt allows renewal 30 days before expiry - $expiryInAdvance = (60 * 60 * 24 * 30); - if ($validTo - $expiryInAdvance > \time()) { - return false; - } +/** + * LetsEncrypt communication to issue certificate (using certbot CLI) + * + * @param string $folder Folder into which certificates should be generated + * @param string $domain Domain to generate certificate for + * + * @return array Named array with keys 'stdout' and 'stderr', both string + */ +function issueCertificate(string $folder, string $domain, string $email): array +{ + $stdout = ''; + $stderr = ''; + + $staging = (App::isProduction()) ? '' : ' --dry-run'; + $exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}" + . " --email " . $email + . " --cert-name " . $folder + . " -w " . APP_STORAGE_CERTIFICATES + . " -d {$domain}", '', $stdout, $stderr); + + // Unexpected error, usually 5XX, API limits, ... + if ($exit !== 0) { + throw new Exception('Failed to issue a certificate with message: ' . $stderr); + } + + return [ + 'stdout' => $stdout, + 'stderr' => $stderr + ]; +} + +/** + * Read new renew date from certificate file generated by Let's Encrypt + * + * @param string $domain Domain which certificate was generated for + * + * @return string + */ +function getRenewDate(string $domain): string +{ + $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; + $certData = openssl_x509_parse(file_get_contents($certPath)); + $validTo = $certData['validTo_time_t'] ?? null; + $dt = (new \DateTime())->setTimestamp($validTo); + return DateTime::addSeconds($dt, -60 * 60 * 24 * 30); // -30 days +} + +/** + * Method to take files from Let's Encrypt, and put it into Traefik. + * + * @param string $domain Domain which certificate was generated for + * @param string $folder Folder in which certificates were generated + * @param array $letsEncryptData Let's Encrypt logs to use for additional info when throwing error + * + * @return void + */ +function applyCertificateFiles(string $folder, string $domain, array $letsEncryptData): void +{ + // Prepare folder in storage for domain + $path = APP_STORAGE_CERTIFICATES . '/' . $domain; + if (!\is_readable($path)) { + if (!\mkdir($path, 0755, true)) { + throw new Exception('Failed to create path for certificate.'); } + } - return true; + // Move generated files + if (!@\rename('/etc/letsencrypt/live/' . $folder . '/cert.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem')) { + throw new Exception('Failed to rename certificate cert.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); } - /** - * LetsEncrypt communication to issue certificate (using certbot CLI) - * - * @param string $folder Folder into which certificates should be generated - * @param string $domain Domain to generate certificate for - * - * @return array Named array with keys 'stdout' and 'stderr', both string - */ - private function issueCertificate(string $folder, string $domain, string $email): array - { - $stdout = ''; - $stderr = ''; - - $staging = (App::isProduction()) ? '' : ' --dry-run'; - $exit = Console::execute("certbot certonly --webroot --noninteractive --agree-tos{$staging}" - . " --email " . $email - . " --cert-name " . $folder - . " -w " . APP_STORAGE_CERTIFICATES - . " -d {$domain}", '', $stdout, $stderr); - - // Unexpected error, usually 5XX, API limits, ... - if ($exit !== 0) { - throw new Exception('Failed to issue a certificate with message: ' . $stderr); - } + if (!@\rename('/etc/letsencrypt/live/' . $folder . '/chain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/chain.pem')) { + throw new Exception('Failed to rename certificate chain.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); + } - return [ - 'stdout' => $stdout, - 'stderr' => $stderr - ]; + if (!@\rename('/etc/letsencrypt/live/' . $folder . '/fullchain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/fullchain.pem')) { + throw new Exception('Failed to rename certificate fullchain.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); } - /** - * Read new renew date from certificate file generated by Let's Encrypt - * - * @param string $domain Domain which certificate was generated for - * - * @return string - */ - private function getRenewDate(string $domain): string - { - $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; - $certData = openssl_x509_parse(file_get_contents($certPath)); - $validTo = $certData['validTo_time_t'] ?? null; - $dt = (new \DateTime())->setTimestamp($validTo); - return DateTime::addSeconds($dt, -60 * 60 * 24 * 30); // -30 days + if (!@\rename('/etc/letsencrypt/live/' . $folder . '/privkey.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/privkey.pem')) { + throw new Exception('Failed to rename certificate privkey.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); } - /** - * Method to take files from Let's Encrypt, and put it into Traefik. - * - * @param string $domain Domain which certificate was generated for - * @param string $folder Folder in which certificates were generated - * @param array $letsEncryptData Let's Encrypt logs to use for additional info when throwing error - * - * @return void - */ - private function applyCertificateFiles(string $folder, string $domain, array $letsEncryptData): void - { - // Prepare folder in storage for domain - $path = APP_STORAGE_CERTIFICATES . '/' . $domain; - if (!\is_readable($path)) { - if (!\mkdir($path, 0755, true)) { - throw new Exception('Failed to create path for certificate.'); - } - } + $config = \implode(PHP_EOL, [ + "tls:", + " certificates:", + " - certFile: /storage/certificates/{$domain}/fullchain.pem", + " keyFile: /storage/certificates/{$domain}/privkey.pem" + ]); - // Move generated files - if (!@\rename('/etc/letsencrypt/live/' . $folder . '/cert.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem')) { - throw new Exception('Failed to rename certificate cert.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); - } + // Save configuration into Traefik using our new cert files + if (!\file_put_contents(APP_STORAGE_CONFIG . '/' . $domain . '.yml', $config)) { + throw new Exception('Failed to save Traefik configuration.'); + } - if (!@\rename('/etc/letsencrypt/live/' . $folder . '/chain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/chain.pem')) { - throw new Exception('Failed to rename certificate chain.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); - } + $stdout = ''; + $stderr = ''; + Console::execute('cd ' . APP_STORAGE_CERTIFICATES . " && tar --exclude $domain.tar.gz -czf $domain.tar.gz .", '', $stdout, $stderr); +} - if (!@\rename('/etc/letsencrypt/live/' . $folder . '/fullchain.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/fullchain.pem')) { - throw new Exception('Failed to rename certificate fullchain.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); - } +/** + * Method to make sure information about error is delivered to admnistrator. + * + * @param string $domain Domain that caused the error + * @param string $errorMessage Verbose error message + * @param int $attempt How many times it failed already + * + * @return void + */ +function notifyError(string $domain, string $errorMessage, int $attempt): void +{ + // Log error into console + Console::warning('Cannot renew domain (' . $domain . ') on attempt no. ' . $attempt . ' certificate: ' . $errorMessage); + + // Send mail to administratore mail + $mail = new Mail(); + $mail + ->setType(MAIL_TYPE_CERTIFICATE) + ->setRecipient(App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')) + ->setUrl('https://' . $domain) + ->setLocale(App::getEnv('_APP_LOCALE', 'en')) + ->setName('Appwrite Administrator') + ->setPayload([ + 'domain' => $domain, + 'error' => $errorMessage, + 'attempt' => $attempt + ]) + ->trigger(); +} - if (!@\rename('/etc/letsencrypt/live/' . $folder . '/privkey.pem', APP_STORAGE_CERTIFICATES . '/' . $domain . '/privkey.pem')) { - throw new Exception('Failed to rename certificate privkey.pem. Let\'s Encrypt log: ' . $letsEncryptData['stderr'] . ' ; ' . $letsEncryptData['stdout']); - } +/** + * Update all existing domain documents so they have relation to correct certificate document. + * This solved issues: + * - when adding a domain for which there is already a certificate + * - when renew creates new document? It might? + * - overall makes it more reliable + * + * @param string $certificateId ID of a new or updated certificate document + * @param string $domain Domain that is affected by new certificate + * @param Database $dbForConsole Database instance for console + * + * @return void + */ +function updateDomainDocuments(string $certificateId, string $domain, Database $dbForConsole): void +{ + $domains = $dbForConsole->find('domains', [ + Query::equal('domain', [$domain]), + Query::limit(1000), + ]); - $config = \implode(PHP_EOL, [ - "tls:", - " certificates:", - " - certFile: /storage/certificates/{$domain}/fullchain.pem", - " keyFile: /storage/certificates/{$domain}/privkey.pem" - ]); + foreach ($domains as $domainDocument) { + $domainDocument->setAttribute('updated', DateTime::now()); + $domainDocument->setAttribute('certificateId', $certificateId); - // Save configuration into Traefik using our new cert files - if (!\file_put_contents(APP_STORAGE_CONFIG . '/' . $domain . '.yml', $config)) { - throw new Exception('Failed to save Traefik configuration.'); + $dbForConsole->updateDocument('domains', $domainDocument->getId(), $domainDocument); + + if ($domainDocument->getAttribute('projectId')) { + $dbForConsole->deleteCachedDocument('projects', $domainDocument->getAttribute('projectId')); } } +} - /** - * Method to make sure information about error is delivered to admnistrator. - * - * @param string $domain Domain that caused the error - * @param string $errorMessage Verbose error message - * @param int $attempt How many times it failed already - * - * @return void - */ - private function notifyError(string $domain, string $errorMessage, int $attempt): void - { - // Log error into console - Console::warning('Cannot renew domain (' . $domain . ') on attempt no. ' . $attempt . ' certificate: ' . $errorMessage); - - // Send mail to administratore mail - $mail = new Mail(); - $mail - ->setType(MAIL_TYPE_CERTIFICATE) - ->setRecipient(App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')) - ->setUrl('https://' . $domain) - ->setLocale(App::getEnv('_APP_LOCALE', 'en')) - ->setName('Appwrite Administrator') - ->setPayload([ - 'domain' => $domain, - 'error' => $errorMessage, - 'attempt' => $attempt - ]) - ->trigger(); - } +$server->job() + ->inject('message') + ->inject('dbForConsole') + ->inject('execute') + ->action(function ($message, $dbForConsole, $execute, Client $queueForCacheSyncOut) use ($server) { + $payload = $message->getPayload() ?? []; - /** - * Update all existing domain documents so they have relation to correct certificate document. - * This solved issues: - * - when adding a domain for which there is already a certificate - * - when renew creates new document? It might? - * - overall makes it more reliable - * - * @param string $certificateId ID of a new or updated certificate document - * @param string $domain Domain that is affected by new certificate - * - * @return void - */ - private function updateDomainDocuments(string $certificateId, string $domain): void - { - $domains = $this->dbForConsole->find('domains', [ - Query::equal('domain', [$domain]), - Query::limit(1000), - ]); - - foreach ($domains as $domainDocument) { - $domainDocument->setAttribute('updated', DateTime::now()); - $domainDocument->setAttribute('certificateId', $certificateId); - - $this->dbForConsole->updateDocument('domains', $domainDocument->getId(), $domainDocument); - - if ($domainDocument->getAttribute('projectId')) { - $this->dbForConsole->deleteCachedDocument('projects', $domainDocument->getAttribute('projectId')); - } + if (empty($payload)) { + throw new Exception('Missing payload'); } - } -} + + $document = new Document($payload['domain'] ?? []); + $domain = new Domain($document->getAttribute('domain', '')); + $skipRenewCheck = $payload['skipRenewCheck'] ?? false; + + $execute( + dbForConsole: $dbForConsole, + document: $document, + domain: $domain, + queueForCacheSyncOut: $queueForCacheSyncOut, + skipRenewCheck: $skipRenewCheck, + ); + }); + +$server->workerStart(); +$server->start(); diff --git a/app/workers/sync-In.php b/app/workers/sync-In.php index 08f98c55ae..385d2da147 100644 --- a/app/workers/sync-In.php +++ b/app/workers/sync-In.php @@ -36,6 +36,28 @@ options: $key['options'] ); break; + case 'certificate': + Console::log("[{$time}] Writing certificate for domain [{$key['domain']}]"); + + $path = APP_STORAGE_CERTIFICATES . '/__' . $key['domain']; + $filename = $key['domain'] . 'tar.gz'; + if (!file_exists($path)) { + mkdir($path, 0755, true); + } + + $result = file_put_contents($path . '/' . $filename, base64_decode($key['contents'])); + if (empty($result)) { + Console::error('Can not write ' . $key['filename']); + break; + } + + $stdout = ''; + $stderr = ''; + $result = Console::execute('cd ' . $path . ' && tar xvzf ' . $filename, '', $stdout, $stderr); + if ($result === 1) { + Console::error('Can not open ' . $filename); + } + break; default: break; } @@ -44,7 +66,7 @@ $server ->workerStart() ->action(function () { - Console::success("In [" . App::getEnv('_APP_REGION', 'nyc1') . "] edge cache purging worker Started"); + Console::success("[" . App::getEnv('_APP_REGION', 'nyc1') . "] edge sync-in worker Started"); }); $server->start(); diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 39e76a5d77..4607e77b38 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -34,24 +34,40 @@ /** * @param string $url * @param string $token - * @param array $payload + * @param array data * @return int */ -function call(string $url, string $token, array $payload): int +function call(string $url, string $token, array $data): int { + $boundary = uniqid(); + $delimiter = '-------------' . $boundary; + $payload = ''; + $eol = "\r\n"; + foreach ($data as $keys) { + $payload .= "--" . $delimiter . $eol + . 'Content-Disposition: form-data; name="keys[]"' . $eol . $eol + . json_encode($keys) . $eol; + } + $payload .= "--" . $delimiter . "--" . $eol; + var_dump($payload); + $status = 404; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, - 'Content-Type: application/json' + 'Content-type: multipart/form-data; boundary=' . $delimiter, + 'Content-Length: ' . strlen($payload) ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); + curl_setopt($ch, CURLOPT_VERBOSE, true); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { - $response = curl_exec($ch); + curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($status === 200) { @@ -66,29 +82,30 @@ function call(string $url, string $token, array $payload): int return $status; } + /** * @throws Authorization * @throws Structure * @throws Exception|\Exception */ -function handle($dbForConsole, $regions, $payload): void +function handle($dbForConsole, $regions, $data): void { $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode([]); foreach ($regions as $code => $region) { + var_dump($region); $time = DateTime::now(); - $status = call($region['domain'] . '/v1/edge/sync', $token, ['keys' => $payload]); + $status = call($region['domain'] . '/v1/edge/sync', $token, $data); if ($status !== Response::STATUS_CODE_OK) { Console::error("[{$time}] Request to {$code} has failed"); - - foreach ($payload as $sync) { + foreach ($data as $keys) { $dbForConsole->createDocument('syncs', new Document([ 'region' => App::getEnv('_APP_REGION'), 'target' => $code, - 'type' => $sync['type'], - 'key' => ['key' => $sync['key']], + 'type' => $keys['type'], + 'key' => ['key' => $keys['key']], 'status' => $status, ])); } @@ -160,7 +177,7 @@ function handle($dbForConsole, $regions, $payload): void Console::log("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); handle($dbForConsole, $stack['regions'], $chunk); }); - Console::success("Out [" . App::getEnv('_APP_REGION') . "] edge cache purging worker Started"); + Console::success("[" . App::getEnv('_APP_REGION') . "] edge sync-out worker Started"); }); $server->start(); diff --git a/bin/worker-certificates b/bin/worker-certificates index 679885fa46..84935878e3 100755 --- a/bin/worker-certificates +++ b/bin/worker-certificates @@ -1,10 +1,3 @@ #!/bin/sh -if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] -then - REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -else - REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -fi - -INTERVAL=1 QUEUE='v1-certificates' APP_INCLUDE='/usr/src/code/app/workers/certificates.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file +QUEUE=v1-certificates php /usr/src/code/app/workers/certificates.php $@ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index dd1bf04f7d..813a785a7d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -266,6 +266,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - appwrite-certificates:/storage/certificates:rw - ./vendor/utopia-php/pools:/usr/src/code/vendor/utopia-php/pools depends_on: - mariadb @@ -300,6 +301,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - appwrite-certificates:/storage/certificates:rw #- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: diff --git a/src/Appwrite/Event/Certificate.php b/src/Appwrite/Event/Certificate.php index d3d9091804..e56b922ee5 100644 --- a/src/Appwrite/Event/Certificate.php +++ b/src/Appwrite/Event/Certificate.php @@ -2,17 +2,18 @@ namespace Appwrite\Event; -use Resque; use Utopia\Database\Document; +use Utopia\Queue\Client; +use Utopia\Queue\Connection; class Certificate extends Event { protected bool $skipRenewCheck = false; protected ?Document $domain = null; - public function __construct() + public function __construct(protected Connection $connection) { - parent::__construct(Event::CERTIFICATES_QUEUE_NAME, Event::CERTIFICATES_CLASS_NAME); + parent::__construct(Event::FUNCTIONS_QUEUE_NAME, Event::FUNCTIONS_CLASS_NAME); } /** @@ -69,7 +70,8 @@ public function getSkipRenewCheck(): bool */ public function trigger(): string|bool { - return Resque::enqueue($this->queue, $this->class, [ + $client = new Client($this->queue, $this->connection); + return $client->enqueue([ 'project' => $this->project, 'domain' => $this->domain, 'skipRenewCheck' => $this->skipRenewCheck From 02a9265a76de32e9c69f9de926c99c7c5224c976 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 16:25:35 +0200 Subject: [PATCH 52/87] tidy up --- app/cli.php | 19 +++++++++---- app/controllers/api/edge.php | 6 ++-- app/controllers/shared/api.php | 8 +++--- app/init.php | 36 +++++++++++++++--------- app/worker.php | 2 +- app/workers/certificates.php | 10 +++---- src/Appwrite/Platform/Tasks/EdgeSync.php | 10 +++---- 7 files changed, 53 insertions(+), 38 deletions(-) diff --git a/app/cli.php b/app/cli.php index 0a28659ad9..907aa8853e 100644 --- a/app/cli.php +++ b/app/cli.php @@ -18,11 +18,14 @@ use Utopia\Logger\Log; use Utopia\Pools\Group; use Utopia\Queue\Client; +use Utopia\Queue\Server; use Utopia\Registry\Registry; Authorization::disable(); -CLI::setResource('register', fn()=>$register); +global $register; + +CLI::setResource('register', fn() => $register); CLI::setResource('cache', function ($pools) { $list = Config::getParam('pools-cache', []); @@ -141,13 +144,17 @@ return $database; }, ['register']); -CLI::setResource('queueForFunctions', function (Group $pools) { - return new Func($pools->get('queue')->pop()->getResource()); +App::setResource('queue', function (Group $pools) { + return $pools->get('queue')->pop()->getResource(); }, ['pools']); -CLI::setResource('queueForCacheSyncOut', function (Group $pools) { - return new Client('v1-sync-out', $pools->get('queue')->pop()->getResource()); -}, ['pools']); +CLI::setResource('queueForFunctions', function (Client $queue) { + return new Func($queue); +}, ['queue']); + +CLI::setResource('queueForEdgeSyncOut', function (Client $queue) { + return new Client('v1-sync-out', $queue); +}, ['queue']); CLI::setResource('logError', function (Registry $register) { return function (Throwable $error, string $namespace, string $action) use ($register) { diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 18772fa7a1..9d35515255 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -36,8 +36,8 @@ ->param('keys', '', new ArrayList(new Text(4056), 600), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') - ->inject('queueForCacheSyncIn') - ->action(function (array $keys, Request $request, Response $response, Client $queueForCacheSyncIn) { + ->inject('queueForEdgeSyncIn') + ->action(function (array $keys, Request $request, Response $response, Client $queueForEdgeSyncIn) { if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); @@ -45,7 +45,7 @@ foreach ($keys as $parts) { $key = json_decode($parts); - $queueForCacheSyncIn + $queueForEdgeSyncIn ->enqueue([ 'type' => $key->type, 'key' => $key->key diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index be9f01705e..c61a4f6f91 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -334,8 +334,8 @@ ->inject('mode') ->inject('dbForProject') ->inject('queueForFunctions') - ->inject('queueForCacheSyncOut') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions, Client $queueForCacheSyncOut) use ($parseLabel) { + ->inject('queueForEdgeSyncOut') + ->action(function (App $utopia, Request $request, Response $response, Document $project, Event $events, Audit $audits, Stats $usage, Delete $deletes, EventDatabase $database, string $mode, Database $dbForProject, Func $queueForFunctions, Client $queueForEdgeSyncOut) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -391,7 +391,7 @@ ] ); //Sync with other regions - $queueForCacheSyncOut->enqueue([ + $queueForEdgeSyncOut->enqueue([ 'type' => 'realtime', 'key' => [ 'projectId' => $target['projectId'] ?? $project->getId(), @@ -408,7 +408,7 @@ } } -// $queueForCacheSyncOut->enqueue([ +// $queueForEdgeSyncOut->enqueue([ // 'type' => 'certificate', // 'key' => [ // 'domain' => 'appwrite.io', diff --git a/app/init.php b/app/init.php index e95e71fe51..acfc16ffeb 100644 --- a/app/init.php +++ b/app/init.php @@ -18,6 +18,7 @@ ini_set('default_socket_timeout', -1); error_reporting(E_ALL); +use Appwrite\Event\Certificate; use Appwrite\Extend\Exception; use Appwrite\Auth\Auth; use Appwrite\SMS\Adapter\Mock; @@ -40,6 +41,7 @@ use Appwrite\Usage\Stats; use Utopia\App; use Utopia\Queue\Client; +use Utopia\Queue\Server; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Database\ID; @@ -855,15 +857,21 @@ function (mixed $value) { App::setResource('deletes', fn() => new Delete()); App::setResource('database', fn() => new EventDatabase()); App::setResource('messaging', fn() => new Phone()); -App::setResource('queueForFunctions', function (Group $pools) { - return new Func($pools->get('queue')->pop()->getResource()); -}, ['pools']); -App::setResource('queueForCacheSyncOut', function (Group $pools) { - return new Client('v1-sync-out', $pools->get('queue')->pop()->getResource()); -}, ['pools']); -App::setResource('queueForCacheSyncIn', function (Group $pools) { - return new Client('v1-sync-in', $pools->get('queue')->pop()->getResource()); +App::setResource('queue', function (Group $pools) { + return $pools->get('queue')->pop()->getResource(); }, ['pools']); +App::setResource('queueForFunctions', function (Connection $queue) { + return new Func($queue); +}, ['queue']); +App::setResource('queueForCertificates', function (Connection $queue) { + return new Certificate($queue); +}, ['queue']); +App::setResource('queueForEdgeSyncOut', function (Connection $queue) { + return new Client('v1-sync-out', $queue); +}, ['queue']); +App::setResource('queueForEdgeSyncIn', function (Connection $queue) { + return new Client('v1-sync-in', $queue); +}, ['queue']); App::setResource('usage', function ($register) { return new Stats($register->get('statsd')); }, ['register']); @@ -1078,7 +1086,7 @@ function (mixed $value) { return $database; }, ['pools', 'cache']); -App::setResource('cache', function (Group $pools, Client $queueForCacheSyncOut) { +App::setResource('cache', function (Group $pools, Client $queueForEdgeSyncOut) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -1091,16 +1099,16 @@ function (mixed $value) { } $cache = new Cache(new Sharding($adapters)); - $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForCacheSyncOut) { - $queueForCacheSyncOut + $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForEdgeSyncOut) { + $queueForEdgeSyncOut ->enqueue([ 'type' => 'cache', 'key' => $key ]); }); - $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForCacheSyncOut) { - $queueForCacheSyncOut + $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForEdgeSyncOut) { + $queueForEdgeSyncOut ->enqueue([ 'type' => 'cache', 'key' => $key @@ -1108,7 +1116,7 @@ function (mixed $value) { }); return $cache; -}, ['pools', 'queueForCacheSyncOut']); +}, ['pools', 'queueForEdgeSyncOut']); App::setResource('deviceLocal', function () { return new Local(); diff --git a/app/worker.php b/app/worker.php index adf0745026..0c966a13f1 100644 --- a/app/worker.php +++ b/app/worker.php @@ -90,7 +90,7 @@ return new Certificate($queue); }, ['queue']); -Server::setResource('queueForCacheSyncOut', function (Connection $queue) { +Server::setResource('queueForSyncOut', function (Connection $queue) { return new Client('v1-sync-out', $queue); }, ['queue']); diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 631a87a969..af99e1d6ef 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -12,7 +12,7 @@ use Utopia\Database\Document; use Utopia\Database\ID; use Utopia\Database\Query; -use Utopia\Domains\Domain; + use Utopia\Domains\Domain; use Utopia\Queue\Client; use Utopia\Queue\Message; use Utopia\Queue\Server; @@ -28,7 +28,7 @@ Database $dbForConsole, Document $document, Domain $domain, - $queueForCacheSyncOut, + $queueForEdgeSyncOut, bool $skipRenewCheck = false, ) { /** @@ -110,7 +110,7 @@ $certificate->setAttribute('attempts', 0); $certificate->setAttribute('issueDate', DateTime::now()); - $queueForCacheSyncOut->enqueue([ + $queueForEdgeSyncOut->enqueue([ 'type' => 'certificate', 'key' => [ 'domain' => $domain, @@ -423,7 +423,7 @@ function updateDomainDocuments(string $certificateId, string $domain, Database $ ->inject('message') ->inject('dbForConsole') ->inject('execute') - ->action(function ($message, $dbForConsole, $execute, Client $queueForCacheSyncOut) use ($server) { + ->action(function ($message, $dbForConsole, $execute, Client $queueForEdgeSyncOut) use ($server) { $payload = $message->getPayload() ?? []; if (empty($payload)) { @@ -438,7 +438,7 @@ function updateDomainDocuments(string $certificateId, string $domain, Database $ dbForConsole: $dbForConsole, document: $document, domain: $domain, - queueForCacheSyncOut: $queueForCacheSyncOut, + queueForEdgeSyncOut: $queueForEdgeSyncOut, skipRenewCheck: $skipRenewCheck, ); }); diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index 7ffd8e24f2..2cd596ba9a 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -25,11 +25,11 @@ public function __construct() ->desc('Schedules edge sync tasks') ->inject('pools') ->inject('dbForConsole') - ->inject('queueForCacheSyncOut') - ->callback(fn (Group $pools, Database $dbForConsole, Client $queueForCacheSyncOut) => $this->action($pools, $dbForConsole, $queueForCacheSyncOut)); + ->inject('queueForSyncOut') + ->callback(fn (Group $pools, Database $dbForConsole, Client $queueForEdgeSyncOut) => $this->action($pools, $dbForConsole, $queueForEdgeSyncOut)); } - public function action(Group $pools, Database $dbForConsole, Client $queueForCacheSyncOut): void + public function action(Group $pools, Database $dbForConsole, Client $queueForEdgeSyncOut): void { Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); @@ -42,7 +42,7 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac ); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $dbForConsole, $queueForCacheSyncOut, $regions) { + Console::loop(function () use ($interval, $dbForConsole, $queueForEdgeSyncOut, $regions) { $time = DateTime::now(); Console::success("[{$time}] New task every {$interval} seconds"); @@ -78,7 +78,7 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForCac if (!empty($keys)) { Console::info("[{$time}] Enqueueing keys chunk {$count} to region {$code}"); - $queueForCacheSyncOut + $queueForEdgeSyncOut ->enqueue([ 'region' => $code, 'keys' => $keys From 9860b013fb622a9105bc0070c18b538617745459 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 16:55:21 +0200 Subject: [PATCH 53/87] tidy up --- app/cli.php | 8 ++++---- src/Appwrite/Platform/Tasks/EdgeSync.php | 14 ++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/cli.php b/app/cli.php index 907aa8853e..9c5d6bfb42 100644 --- a/app/cli.php +++ b/app/cli.php @@ -18,7 +18,7 @@ use Utopia\Logger\Log; use Utopia\Pools\Group; use Utopia\Queue\Client; -use Utopia\Queue\Server; +use Utopia\Queue\Connection; use Utopia\Registry\Registry; Authorization::disable(); @@ -144,15 +144,15 @@ return $database; }, ['register']); -App::setResource('queue', function (Group $pools) { +CLI::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); }, ['pools']); -CLI::setResource('queueForFunctions', function (Client $queue) { +CLI::setResource('queueForFunctions', function (Connection $queue) { return new Func($queue); }, ['queue']); -CLI::setResource('queueForEdgeSyncOut', function (Client $queue) { +CLI::setResource('queueForEdgeSyncOut', function (Connection $queue) { return new Client('v1-sync-out', $queue); }, ['queue']); diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index 2cd596ba9a..c3ff92fd8a 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -9,7 +9,6 @@ use Utopia\Database\DateTime; use Utopia\Database\Query; use Utopia\Database\Database; -use Utopia\Pools\Group; use Utopia\Queue\Client; class EdgeSync extends Action @@ -23,13 +22,12 @@ public function __construct() { $this ->desc('Schedules edge sync tasks') - ->inject('pools') ->inject('dbForConsole') - ->inject('queueForSyncOut') - ->callback(fn (Group $pools, Database $dbForConsole, Client $queueForEdgeSyncOut) => $this->action($pools, $dbForConsole, $queueForEdgeSyncOut)); + ->inject('queueForEdgeSyncOut') + ->callback(fn (Database $dbForConsole, Client $queueForEdgeSyncOut) => $this->action($dbForConsole, $queueForEdgeSyncOut)); } - public function action(Group $pools, Database $dbForConsole, Client $queueForEdgeSyncOut): void + public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): void { Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); @@ -50,9 +48,9 @@ public function action(Group $pools, Database $dbForConsole, Client $queueForEdg foreach ($regions as $code => $region) { $count = 0; $chunk = 0; - $limit = 50; - $sum = $limit; - $keys = []; + $limit = 500; + $sum = $limit; + $keys = []; while ($sum === $limit) { $chunk++; From db05793a3cfd0b92596f17fc1cdf33df805dde3e Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 17:25:04 +0200 Subject: [PATCH 54/87] tidy up --- app/workers/sync-out.php | 3 +-- src/Appwrite/Platform/Tasks/EdgeSync.php | 26 +++++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 4607e77b38..1a9dfbdc13 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -50,7 +50,7 @@ function call(string $url, string $token, array $data): int . json_encode($keys) . $eol; } $payload .= "--" . $delimiter . "--" . $eol; - var_dump($payload); + $status = 404; $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ @@ -95,7 +95,6 @@ function handle($dbForConsole, $regions, $data): void $token = $jwt->encode([]); foreach ($regions as $code => $region) { - var_dump($region); $time = DateTime::now(); $status = call($region['domain'] . '/v1/edge/sync', $token, $data); if ($status !== Response::STATUS_CODE_OK) { diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index c3ff92fd8a..ce30729960 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -46,14 +46,14 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi Console::success("[{$time}] New task every {$interval} seconds"); foreach ($regions as $code => $region) { - $count = 0; $chunk = 0; $limit = 500; $sum = $limit; $keys = []; + $found = false; while ($sum === $limit) { $chunk++; - + $count = 0; $results = $dbForConsole->find('syncs', [ Query::equal('region', [App::getEnv('_APP_REGION')]), Query::equal('target', [$code]), @@ -62,6 +62,7 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi $sum = count($results); if ($sum > 0) { + $found = true; foreach ($results as $document) { $key = $document->getAttribute('key'); $keys[] = [ @@ -72,17 +73,18 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi $count++; } } - } - if (!empty($keys)) { - Console::info("[{$time}] Enqueueing keys chunk {$count} to region {$code}"); - $queueForEdgeSyncOut - ->enqueue([ - 'region' => $code, - 'keys' => $keys - ]); - } else { - Console::info("[{$time}] No keys where found for region {$code}."); + if (!empty($keys)) { + Console::info("[{$time}] Enqueueing chunk {$chunk}, {$count} keys to region {$code}"); + $queueForEdgeSyncOut + ->enqueue([ + 'region' => $code, + 'keys' => $keys + ]); + } + } + if (!$found) { + Console::info("[{$time}] No keys where found for region {$code}."); } } }, $interval); From 754aaba68c9296d0d9fba8f67b75d78796c334a6 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 17:46:19 +0200 Subject: [PATCH 55/87] deletes-worker --- app/cli.php | 4 ++++ src/Appwrite/Event/Delete.php | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/cli.php b/app/cli.php index 9c5d6bfb42..4857f2a07a 100644 --- a/app/cli.php +++ b/app/cli.php @@ -148,6 +148,10 @@ return $pools->get('queue')->pop()->getResource(); }, ['pools']); +CLI::setResource('queueForDeletes', function (Connection $queue) { + return new Delete($queue); +}, ['queue']); + CLI::setResource('queueForFunctions', function (Connection $queue) { return new Func($queue); }, ['queue']); diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index d1519121a6..32c84ee90c 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -2,8 +2,9 @@ namespace Appwrite\Event; -use Resque; use Utopia\Database\Document; +use Utopia\Queue\Client; +use Utopia\Queue\Connection; class Delete extends Event { @@ -14,9 +15,9 @@ class Delete extends Event protected ?string $hourlyUsageRetentionDatetime = null; - public function __construct() + public function __construct(protected Connection $connection) { - parent::__construct(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME); + parent::__construct(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, $connection); } /** @@ -121,7 +122,11 @@ public function getDocument(): ?Document */ public function trigger(): string|bool { - return Resque::enqueue($this->queue, $this->class, [ + $client = new Client($this->queue, $this->connection); + + $events = $this->getEvent() ? Event::generateEvents($this->getEvent(), $this->getParams()) : null; + + return $client->enqueue([ 'project' => $this->project, 'type' => $this->type, 'document' => $this->document, From d040454473a6a2933691096f29e71bd492b99062 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 17:51:44 +0200 Subject: [PATCH 56/87] deletes-worker --- bin/worker-deletes | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/bin/worker-deletes b/bin/worker-deletes index 02c2311fa7..93964ed7b5 100644 --- a/bin/worker-deletes +++ b/bin/worker-deletes @@ -1,10 +1,3 @@ #!/bin/sh -if [ -z "$_APP_REDIS_USER" ] && [ -z "$_APP_REDIS_PASS" ] -then - REDIS_BACKEND="${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -else - REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}" -fi - -INTERVAL=1 QUEUE='v1-deletes' APP_INCLUDE='/usr/src/code/app/workers/deletes.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php \ No newline at end of file +QUEUE=v1-deletes php /usr/src/code/app/workers/deletes.php $@ \ No newline at end of file From 149d8fe361ca621093d275fc250e8f27ee74c93d Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 17:51:58 +0200 Subject: [PATCH 57/87] deletes-worker --- src/Appwrite/Platform/Tasks/Maintenance.php | 76 ++++++++++----------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 0739923e34..c25341bce7 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -1,8 +1,6 @@ desc('Schedules maintenance tasks and publishes them to resque') + ->desc('Schedules maintenance tasks and publishes them to queues') ->inject('dbForConsole') - ->callback(fn (Database $dbForConsole) => $this->action($dbForConsole)); + ->inject('queueForCertificates') + ->inject('queueForDeletes') + ->callback(fn (Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes) => $this->action($dbForConsole, $queueForCertificates, $queueForDeletes)); } - public function action(Database $dbForConsole): void + public function action(Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes): void { Console::title('Maintenance V1'); Console::success(APP_NAME . ' maintenance process v1 has started'); - function notifyDeleteExecutionLogs(int $interval) + function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_EXECUTIONS) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); } - function notifyDeleteAbuseLogs(int $interval) + function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_ABUSE) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); } - function notifyDeleteAuditLogs(int $interval) + function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_AUDIT) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); } - function notifyDeleteUsageStats(int $usageStatsRetentionHourly) + function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_USAGE) ->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly)) ->trigger(); } - function notifyDeleteConnections() + function notifyDeleteConnections(Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_REALTIME) ->setDatetime(DateTime::addSeconds(new \DateTime(), -60)) ->trigger(); } - function notifyDeleteExpiredSessions() + function notifyDeleteExpiredSessions(Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_SESSIONS) ->trigger(); } - function renewCertificates($dbForConsole) + function renewCertificates(Database $dbForConsole, Certificate $queueForCertificate) { $time = DateTime::now(); $certificates = $dbForConsole->find('certificates', [ - Query::lessThan('attempts', 5), // Maximum 5 attempts - Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) - Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) + Query::lessThan('attempts', 5), // Maximum 5 attempts + Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) + Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) ]); if (\count($certificates) > 0) { Console::info("[{$time}] Found " . \count($certificates) . " certificates for renewal, scheduling jobs."); - $event = new Certificate(); foreach ($certificates as $certificate) { - $event + $queueForCertificate ->setDomain(new Document([ 'domain' => $certificate->getAttribute('domain') ])) @@ -107,19 +106,19 @@ function renewCertificates($dbForConsole) } } - function notifyDeleteCache($interval) + function notifyDeleteCache($interval, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_CACHE_BY_TIMESTAMP) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); } - function notifyDeleteSchedules($interval) + function notifyDeleteSchedules($interval, Delete $queueForDeletes) { - (new Delete()) + ($queueForDeletes) ->setType(DELETE_TYPE_SCHEDULES) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -131,23 +130,22 @@ function notifyDeleteSchedules($interval) $auditLogRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', '1209600'); $abuseLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', '86400'); $usageStatsRetentionHourly = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_HOURLY', '8640000'); //100 days - $cacheRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_CACHE', '2592000'); // 30 days $schedulesDeletionRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_SCHEDULES', '86400'); // 1 Day - Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $cacheRetention, $schedulesDeletionRetention, $usageStatsRetentionHourly, $dbForConsole) { + Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $cacheRetention, $schedulesDeletionRetention, $usageStatsRetentionHourly, $dbForConsole, $queueForDeletes, $queueForCertificates) { $time = DateTime::now(); Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); - notifyDeleteExecutionLogs($executionLogsRetention); - notifyDeleteAbuseLogs($abuseLogsRetention); - notifyDeleteAuditLogs($auditLogRetention); - notifyDeleteUsageStats($usageStatsRetentionHourly); - notifyDeleteConnections(); - notifyDeleteExpiredSessions(); - renewCertificates($dbForConsole); - notifyDeleteCache($cacheRetention); - notifyDeleteSchedules($schedulesDeletionRetention); + notifyDeleteExecutionLogs($executionLogsRetention, $queueForDeletes); + notifyDeleteAbuseLogs($abuseLogsRetention, $queueForDeletes); + notifyDeleteAuditLogs($auditLogRetention, $queueForDeletes); + notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes); + notifyDeleteConnections($queueForDeletes); + notifyDeleteExpiredSessions($queueForDeletes); + renewCertificates($dbForConsole, $queueForCertificates); + notifyDeleteCache($cacheRetention, $queueForDeletes); + notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes); }, $interval); } -} +} \ No newline at end of file From 150d3572c40320f81674eaa8f96d35048dfb3422 Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 19:30:29 +0200 Subject: [PATCH 58/87] deletes-worker --- app/cli.php | 7 + composer.lock | 6879 ---------------------------- src/Appwrite/Event/Certificate.php | 3 +- src/Appwrite/Event/Delete.php | 4 +- 4 files changed, 10 insertions(+), 6883 deletions(-) delete mode 100644 composer.lock diff --git a/app/cli.php b/app/cli.php index 4857f2a07a..57eb98537e 100644 --- a/app/cli.php +++ b/app/cli.php @@ -3,6 +3,8 @@ require_once __DIR__ . '/init.php'; require_once __DIR__ . '/controllers/general.php'; +use Appwrite\Event\Certificate; +use Appwrite\Event\Delete; use Appwrite\Event\Func; use Appwrite\Platform\Appwrite; use Utopia\CLI\CLI; @@ -144,10 +146,15 @@ return $database; }, ['register']); + CLI::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); }, ['pools']); +CLI::setResource('queueForCertificates', function (Connection $queue) { + return new Certificate($queue); +}, ['queue']); + CLI::setResource('queueForDeletes', function (Connection $queue) { return new Delete($queue); }, ['queue']); diff --git a/composer.lock b/composer.lock deleted file mode 100644 index f35a9b4408..0000000000 --- a/composer.lock +++ /dev/null @@ -1,6879 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "4d3e2a569d5f848f135a5fc854924af4", - "packages": [ - { - "name": "adhocore/jwt", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/adhocore/php-jwt.git", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", - "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Ahc\\Jwt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jitendra Adhikari", - "email": "jiten.adhikary@gmail.com" - } - ], - "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", - "keywords": [ - "auth", - "json-web-token", - "jwt", - "jwt-auth", - "jwt-php", - "token" - ], - "support": { - "issues": "https://github.com/adhocore/php-jwt/issues", - "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" - }, - "funding": [ - { - "url": "https://paypal.me/ji10", - "type": "custom" - } - ], - "time": "2021-02-20T09:56:44+00:00" - }, - { - "name": "appwrite/php-clamav", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/appwrite/php-clamav.git", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", - "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", - "shasum": "" - }, - "require": { - "ext-sockets": "*", - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\ClamAV\\": "src/ClamAV" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "ClamAV network and pipe client for PHP", - "keywords": [ - "anti virus", - "appwrite", - "clamav", - "php" - ], - "support": { - "issues": "https://github.com/appwrite/php-clamav/issues", - "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" - }, - "time": "2020-10-02T05:23:46+00:00" - }, - { - "name": "appwrite/php-runtimes", - "version": "0.11.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/runtimes.git", - "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" - }, - "require": { - "php": ">=8.0", - "utopia-php/system": "0.6.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\Runtimes\\": "src/Runtimes" - } - }, - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", - "keywords": [ - "appwrite", - "php", - "runtimes" - ], - "time": "2022-11-07T16:45:52+00:00" - }, - { - "name": "chillerlan/php-qrcode", - "version": "4.3.3", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-qrcode.git", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", - "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", - "shasum": "" - }, - "require": { - "chillerlan/php-settings-container": "^2.1", - "ext-mbstring": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5", - "setasign/fpdf": "^1.8.2" - }, - "suggest": { - "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", - "setasign/fpdf": "Required to use the QR FPDF output." - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\QRCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kazuhiko Arase", - "homepage": "https://github.com/kazuhikoarase" - }, - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - }, - { - "name": "Contributors", - "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" - } - ], - "description": "A QR code generator. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-qrcode", - "keywords": [ - "phpqrcode", - "qr", - "qr code", - "qrcode", - "qrcode-generator" - ], - "support": { - "issues": "https://github.com/chillerlan/php-qrcode/issues", - "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2021-11-25T22:38:09+00:00" - }, - { - "name": "chillerlan/php-settings-container", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phan/phan": "^5.3", - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "chillerlan\\Settings\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Smiley", - "email": "smiley@chillerlan.net", - "homepage": "https://github.com/codemasher" - } - ], - "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", - "homepage": "https://github.com/chillerlan/php-settings-container", - "keywords": [ - "PHP7", - "Settings", - "configuration", - "container", - "helper" - ], - "support": { - "issues": "https://github.com/chillerlan/php-settings-container/issues", - "source": "https://github.com/chillerlan/php-settings-container" - }, - "funding": [ - { - "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", - "type": "custom" - }, - { - "url": "https://ko-fi.com/codemasher", - "type": "ko_fi" - } - ], - "time": "2022-07-05T22:32:14+00:00" - }, - { - "name": "colinmollenhour/credis", - "version": "v1.14.0", - "source": { - "type": "git", - "url": "https://github.com/colinmollenhour/credis.git", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", - "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "suggest": { - "ext-redis": "Improved performance for communicating with redis" - }, - "type": "library", - "autoload": { - "classmap": [ - "Client.php", - "Cluster.php", - "Sentinel.php", - "Module.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin Mollenhour", - "email": "colin@mollenhour.com" - } - ], - "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", - "homepage": "https://github.com/colinmollenhour/credis", - "support": { - "issues": "https://github.com/colinmollenhour/credis/issues", - "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" - }, - "time": "2022-11-09T01:18:39+00:00" - }, - { - "name": "dragonmantank/cron-expression", - "version": "v3.3.1", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "webmozart/assert": "^1.0" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Cron\\": "src/Cron/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" - } - ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", - "keywords": [ - "cron", - "schedule" - ], - "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2022-01-18T15:43:28+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", - "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.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "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 - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "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.5.0" - }, - "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": "2022-08-28T15:39:27+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "autoload": { - "files": [ - "src/functions_include.php" - ], - "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/1.5.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2022-08-28T14:55:35+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.4.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "67c26b443f348a51926030c83481b85718457d3d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", - "reference": "67c26b443f348a51926030c83481b85718457d3d", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.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.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "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.4.3" - }, - "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": "2022-10-26T14:07:24+00:00" - }, - { - "name": "influxdb/influxdb-php", - "version": "1.15.2", - "source": { - "type": "git", - "url": "https://github.com/influxdata/influxdb-php.git", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", - "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^6.0|^7.0", - "php": "^5.5 || ^7.0 || ^8.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.2.1", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "ext-curl": "Curl extension, needed for Curl driver", - "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." - }, - "type": "library", - "autoload": { - "psr-4": { - "InfluxDB\\": "src/InfluxDB" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stephen Hoogendijk", - "email": "stephen@tca0.nl" - }, - { - "name": "Daniel Martinez", - "email": "danimartcas@hotmail.com" - }, - { - "name": "Gianluca Arbezzano", - "email": "gianarb92@gmail.com" - } - ], - "description": "InfluxDB client library for PHP", - "keywords": [ - "client", - "influxdata", - "influxdb", - "influxdb class", - "influxdb client", - "influxdb library", - "time series" - ], - "support": { - "issues": "https://github.com/influxdata/influxdb-php/issues", - "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" - }, - "abandoned": true, - "time": "2020-12-26T17:45:17+00:00" - }, - { - "name": "laravel/pint", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", - "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.32.0", - "laravel-zero/framework": "^9.2.0", - "mockery/mockery": "^1.5.1", - "nunomaduro/larastan": "^2.2.0", - "nunomaduro/termwind": "^1.14.0", - "pestphp/pest": "^1.22.1" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "psr-4": { - "App\\": "app/", - "Database\\Seeders\\": "database/seeders/", - "Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "An opinionated code formatter for PHP.", - "homepage": "https://laravel.com", - "keywords": [ - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2022-11-29T16:25:20+00:00" - }, - { - "name": "matomo/device-detector", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/matomo-org/device-detector.git", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", - "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", - "shasum": "" - }, - "require": { - "mustangostang/spyc": "*", - "php": "^7.2|^8.0" - }, - "replace": { - "piwik/device-detector": "self.version" - }, - "require-dev": { - "matthiasmullie/scrapbook": "^1.4.7", - "mayflower/mo4-coding-standard": "^v8.0.0", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8.5.8", - "psr/cache": "^1.0.1", - "psr/simple-cache": "^1.0.1", - "symfony/yaml": "^5.1.7" - }, - "suggest": { - "doctrine/cache": "Can directly be used for caching purpose", - "ext-yaml": "Necessary for using the Pecl YAML parser" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeviceDetector\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "The Matomo Team", - "email": "hello@matomo.org", - "homepage": "https://matomo.org/team/" - } - ], - "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", - "homepage": "https://matomo.org", - "keywords": [ - "devicedetection", - "parser", - "useragent" - ], - "support": { - "forum": "https://forum.matomo.org/", - "issues": "https://github.com/matomo-org/device-detector/issues", - "source": "https://github.com/matomo-org/matomo", - "wiki": "https://dev.matomo.org/" - }, - "time": "2022-04-11T09:58:17+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.3", - "source": { - "type": "git", - "url": "git@github.com:mustangostang/spyc.git", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", - "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2019-09-10T13:16:29+00:00" - }, - { - "name": "phpmailer/phpmailer", - "version": "v6.6.0", - "source": { - "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.2", - "yoast/phpunit-polyfills": "^1.0.0" - }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1-only" - ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } - ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", - "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" - }, - "funding": [ - { - "url": "https://github.com/Synchro", - "type": "github" - } - ], - "time": "2022-02-28T15:31:21+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.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": "http://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/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-factory", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.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": "http://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" - }, - "time": "2019-04-30T12:38:16+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.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": "http://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/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "psr/log", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "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/1.1.4" - }, - "time": "2021-05-03T11:20: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": "resque/php-resque", - "version": "v1.3.6", - "source": { - "type": "git", - "url": "https://github.com/resque/php-resque.git", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", - "reference": "fe41c04763699b1318d97ed14cc78583e9380161", - "shasum": "" - }, - "require": { - "colinmollenhour/credis": "~1.7", - "php": ">=5.6.0", - "psr/log": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7" - }, - "suggest": { - "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", - "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", - "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." - }, - "bin": [ - "bin/resque", - "bin/resque-scheduler" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "Resque": "lib", - "ResqueScheduler": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dan Hunsaker", - "email": "danhunsaker+resque@gmail.com", - "role": "Maintainer" - }, - { - "name": "Rajib Ahmed", - "homepage": "https://github.com/rajibahmed", - "role": "Maintainer" - }, - { - "name": "Steve Klabnik", - "email": "steve@steveklabnik.com", - "role": "Maintainer" - }, - { - "name": "Chris Boulton", - "email": "chris@bigcommerce.com", - "role": "Creator" - } - ], - "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", - "homepage": "http://www.github.com/resque/php-resque/", - "keywords": [ - "background", - "job", - "redis", - "resque" - ], - "support": { - "issues": "https://github.com/resque/php-resque/issues", - "source": "https://github.com/resque/php-resque/tree/v1.3.6" - }, - "time": "2020-04-16T16:39:50+00:00" - }, - { - "name": "slickdeals/statsd", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/Slickdeals/statsd-php.git", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", - "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", - "shasum": "" - }, - "require": { - "php": ">= 7.3 || ^8" - }, - "replace": { - "domnikl/statsd": "self.version" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "phpunit/phpunit": "^9", - "vimeo/psalm": "^4.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Domnikl\\Statsd\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dominik Liebler", - "email": "liebler.dominik@gmail.com" - } - ], - "description": "a PHP client for statsd", - "homepage": "https://github.com/Slickdeals/statsd-php", - "keywords": [ - "Metrics", - "monitoring", - "statistics", - "statsd", - "udp" - ], - "support": { - "issues": "https://github.com/Slickdeals/statsd-php/issues", - "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" - }, - "time": "2021-06-04T20:33:46+00:00" - }, - { - "name": "symfony/deprecation-contracts", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.3-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-25T10:21:52+00:00" - }, - { - "name": "utopia-php/abuse", - "version": "0.16.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "6370d9150425460416583feba0990504ac789e98" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6370d9150425460416583feba0990504ac789e98", - "reference": "6370d9150425460416583feba0990504ac789e98", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.28.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.4", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Abuse\\": "src/Abuse" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple abuse library to manage application usage limits", - "keywords": [ - "Abuse", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.16.0" - }, - "time": "2022-10-31T14:46:41+00:00" - }, - { - "name": "utopia-php/analytics", - "version": "0.2.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/analytics.git", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Analytics\\": "src/Analytics" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library to track events & users.", - "keywords": [ - "analytics", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/analytics/issues", - "source": "https://github.com/utopia-php/analytics/tree/0.2.0" - }, - "time": "2021-03-23T21:33:07+00:00" - }, - { - "name": "utopia-php/audit", - "version": "0.17.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/audit.git", - "reference": "455471bd4de8d74026809e843f8c9740eb32922c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/455471bd4de8d74026809e843f8c9740eb32922c", - "reference": "455471bd4de8d74026809e843f8c9740eb32922c", - "shasum": "" - }, - "require": { - "ext-pdo": "*", - "php": ">=8.0", - "utopia-php/database": "0.28.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Audit\\": "src/Audit" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple audit library to manage application users logs", - "keywords": [ - "Audit", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.17.0" - }, - "time": "2022-10-31T14:44:52+00:00" - }, - { - "name": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cache.git", - "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", - "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-memcached": "*", - "ext-redis": "*", - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpstan/phpstan": "1.9.x-dev", - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Cache\\": "src/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple cache library to manage application cache storing, loading and purging", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" - }, - "time": "2022-12-27T10:47:29+00:00" - }, - { - "name": "utopia-php/cli", - "version": "0.14.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/cli.git", - "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cli/zipball/c30ef985a4e739758a0d95eb0706b357b6d8c086", - "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086", - "shasum": "" - }, - "require": { - "php": ">=7.4", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\CLI\\": "src/CLI" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple CLI library to manage command line applications", - "keywords": [ - "cli", - "command line", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/cli/issues", - "source": "https://github.com/utopia-php/cli/tree/0.14.0" - }, - "time": "2022-10-09T10:19:07+00:00" - }, - { - "name": "utopia-php/config", - "version": "0.2.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/config.git", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Config\\": "src/Config" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Config library to managing application config variables", - "keywords": [ - "config", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/config/issues", - "source": "https://github.com/utopia-php/config/tree/0.2.2" - }, - "time": "2020-10-24T09:49:09+00:00" - }, - { - "name": "utopia-php/database", - "version": "0.28.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/database.git", - "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/ef6506af1c09c22f5dc1e7859159d323f7fafa94", - "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cache": "0.8.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "ext-mongodb": "*", - "ext-pdo": "*", - "ext-redis": "*", - "fakerphp/faker": "^1.14", - "mongodb/mongodb": "1.8.0", - "phpunit/phpunit": "^9.4", - "swoole/ide-helper": "4.8.0", - "utopia-php/cli": "^0.11.0", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Database\\": "src/Database" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library to manage application persistency using multiple database adapters", - "keywords": [ - "database", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.28.0" - }, - "time": "2022-10-31T09:58:46+00:00" - }, - { - "name": "utopia-php/domains", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/domains.git", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Domains\\": "src/Domains" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "domains", - "framework", - "icann", - "php", - "public suffix", - "tld", - "tld extract", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/master" - }, - "time": "2020-02-23T07:40:02+00:00" - }, - { - "name": "utopia-php/dsn", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/dsn.git", - "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea", - "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\DSN\\": "src/DSN" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple library for parsing and managing Data Source Names ( DSNs )", - "keywords": [ - "dsn", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/dsn/issues", - "source": "https://github.com/utopia-php/dsn/tree/0.1.0" - }, - "time": "2022-10-26T10:06:20+00:00" - }, - { - "name": "utopia-php/framework", - "version": "0.25.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/framework.git", - "reference": "2391b397135586b2100d39e338827bef8d2f4ad0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0", - "reference": "2391b397135586b2100d39e338827bef8d2f4ad0", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "require-dev": { - "laravel/pint": "^1.2", - "phpunit/phpunit": "^9.5.25", - "vimeo/psalm": "4.27.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A simple, light and advanced PHP framework", - "keywords": [ - "framework", - "php", - "upf" - ], - "support": { - "issues": "https://github.com/utopia-php/framework/issues", - "source": "https://github.com/utopia-php/framework/tree/0.25.1" - }, - "time": "2022-11-23T18:22:23+00:00" - }, - { - "name": "utopia-php/image", - "version": "0.5.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/image.git", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", - "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", - "shasum": "" - }, - "require": { - "ext-imagick": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.13.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Image\\": "src/Image" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Image manipulation library", - "keywords": [ - "framework", - "image", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/image/issues", - "source": "https://github.com/utopia-php/image/tree/0.5.4" - }, - "time": "2022-05-11T12:30:41+00:00" - }, - { - "name": "utopia-php/locale", - "version": "0.4.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/locale.git", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Locale\\": "src/Locale" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple locale library to manage application translations", - "keywords": [ - "framework", - "locale", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/locale/issues", - "source": "https://github.com/utopia-php/locale/tree/0.4.0" - }, - "time": "2021-07-24T11:35:55+00:00" - }, - { - "name": "utopia-php/logger", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Logger\\": "src/Logger" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], - "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", - "keywords": [ - "appsignal", - "errors", - "framework", - "logger", - "logging", - "logs", - "php", - "raygun", - "sentry", - "upf", - "utopia", - "warnings" - ], - "support": { - "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" - }, - "time": "2022-03-18T10:56:57+00:00" - }, - { - "name": "utopia-php/messaging", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/messaging.git", - "reference": "501272fad666f06bec8f130076862e7981a73f8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", - "reference": "501272fad666f06bec8f130076862e7981a73f8c", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=8.0.0" - }, - "require-dev": { - "phpmailer/phpmailer": "6.6.*", - "phpunit/phpunit": "9.5.*", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Messaging\\": "src/Utopia/Messaging" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jake Barnby", - "email": "jake@appwrite.io" - } - ], - "description": "A simple, light and advanced PHP messaging library", - "keywords": [ - "library", - "messaging", - "php", - "upf", - "utopia", - "utopia-php" - ], - "support": { - "issues": "https://github.com/utopia-php/messaging/issues", - "source": "https://github.com/utopia-php/messaging/tree/0.1.0" - }, - "time": "2022-09-29T11:22:48+00:00" - }, - { - "name": "utopia-php/orchestration", - "version": "0.9.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/orchestration.git", - "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/1d4f66684b8c4927f31b695817eae6d84aafd172", - "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.14.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Orchestration\\": "src/Orchestration" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Lite & fast micro PHP abstraction library for container orchestration", - "keywords": [ - "docker", - "framework", - "kubernetes", - "orchestration", - "php", - "swarm", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/orchestration/issues", - "source": "https://github.com/utopia-php/orchestration/tree/0.9.0" - }, - "time": "2022-11-09T17:38:00+00:00" - }, - { - "name": "utopia-php/platform", - "version": "0.3.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/platform.git", - "reference": "fe9f64420957dc8fb6201d22b499572f021411e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/fe9f64420957dc8fb6201d22b499572f021411e4", - "reference": "fe9f64420957dc8fb6201d22b499572f021411e4", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-redis": "*", - "php": ">=8.0", - "utopia-php/cli": "0.14.*", - "utopia-php/framework": "0.25.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Platform\\": "src/Platform" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Light and Fast Platform Library", - "keywords": [ - "cache", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.3.1" - }, - "time": "2022-11-10T07:04:24+00:00" - }, - { - "name": "utopia-php/pools", - "version": "0.4.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/pools.git", - "reference": "d2870ab74b31b7f4027799f082e85122154f8bed" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/pools/zipball/d2870ab74b31b7f4027799f082e85122154f8bed", - "reference": "d2870ab74b31b7f4027799f082e85122154f8bed", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpstan/phpstan": "1.8.*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Pools\\": "src/Pools" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Team Appwrite", - "email": "team@appwrite.io" - } - ], - "description": "A simple library to manage connection pools", - "keywords": [ - "framework", - "php", - "pools", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/pools/issues", - "source": "https://github.com/utopia-php/pools/tree/0.4.2" - }, - "time": "2022-11-22T07:55:45+00:00" - }, - { - "name": "utopia-php/preloader", - "version": "0.2.4", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/preloader.git", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", - "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Preloader\\": "src/Preloader" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "team@appwrite.io" - } - ], - "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", - "keywords": [ - "framework", - "php", - "preload", - "preloader", - "preloading", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/preloader/issues", - "source": "https://github.com/utopia-php/preloader/tree/0.2.4" - }, - "time": "2020-10-24T07:04:59+00:00" - }, - { - "name": "utopia-php/queue", - "version": "0.5.1", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/queue.git", - "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/queue/zipball/4b39e1f232b2e619b0d7fb4004f2356df334ddc1", - "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1", - "shasum": "" - }, - "require": { - "php": ">=8.0", - "utopia-php/cli": "0.14.*", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "laravel/pint": "^0.2.3", - "phpstan/phpstan": "^1.8", - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.8.8", - "workerman/workerman": "^4.0" - }, - "suggest": { - "ext-swoole": "Needed to support Swoole.", - "workerman/workerman": "Needed to support Workerman." - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Queue\\": "src/Queue" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A powerful task queue.", - "keywords": [ - "Tasks", - "framework", - "php", - "queue", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/queue/issues", - "source": "https://github.com/utopia-php/queue/tree/0.5.1" - }, - "time": "2022-11-16T19:47:26+00:00" - }, - { - "name": "utopia-php/registry", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/registry.git", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", - "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", - "shasum": "" - }, - "require": { - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Registry\\": "src/Registry" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple dependency management library for PHP", - "keywords": [ - "dependency management", - "di", - "framework", - "php", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/registry/issues", - "source": "https://github.com/utopia-php/registry/tree/0.5.0" - }, - "time": "2021-03-10T10:45:22+00:00" - }, - { - "name": "utopia-php/storage", - "version": "0.13.2", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/storage.git", - "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/storage/zipball/ad1c00f24ca56e73888acc2af3deee4919b1194b", - "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-zlib": "*", - "ext-zstd": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Storage\\": "src/Storage" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "A simple Storage library to manage application storage", - "keywords": [ - "framework", - "php", - "storage", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/storage/issues", - "source": "https://github.com/utopia-php/storage/tree/0.13.2" - }, - "time": "2022-12-20T11:11:35+00:00" - }, - { - "name": "utopia-php/swoole", - "version": "0.5.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/swoole.git", - "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", - "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", - "shasum": "" - }, - "require": { - "ext-swoole": "*", - "php": ">=8.0", - "utopia-php/framework": "0.*.*" - }, - "require-dev": { - "laravel/pint": "1.2.*", - "phpunit/phpunit": "^9.3", - "swoole/ide-helper": "4.8.3", - "vimeo/psalm": "4.15.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\Swoole\\": "src/Swoole" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", - "keywords": [ - "framework", - "http", - "php", - "server", - "swoole", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.5.0" - }, - "time": "2022-10-19T22:19:07+00:00" - }, - { - "name": "utopia-php/system", - "version": "0.6.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/system.git", - "reference": "289c4327713deadc9c748b5317d248133a02f245" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", - "reference": "289c4327713deadc9c748b5317d248133a02f245", - "shasum": "" - }, - "require": { - "laravel/pint": "1.2.*", - "php": ">=7.4" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.6", - "vimeo/psalm": "4.0.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\System\\": "src/System" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple library for obtaining information about the host's system.", - "keywords": [ - "framework", - "php", - "system", - "upf", - "utopia" - ], - "support": { - "issues": "https://github.com/utopia-php/system/issues", - "source": "https://github.com/utopia-php/system/tree/0.6.0" - }, - "time": "2022-11-07T13:51:59+00:00" - }, - { - "name": "utopia-php/websocket", - "version": "0.1.0", - "source": { - "type": "git", - "url": "https://github.com/utopia-php/websocket.git", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", - "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", - "shasum": "" - }, - "require": { - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.5", - "swoole/ide-helper": "4.6.6", - "textalk/websocket": "1.5.2", - "vimeo/psalm": "^4.8.1", - "workerman/workerman": "^4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Utopia\\WebSocket\\": "src/WebSocket" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Torsten Dittmann", - "email": "torsten@appwrite.io" - } - ], - "description": "A simple abstraction for WebSocket servers.", - "keywords": [ - "framework", - "php", - "upf", - "utopia", - "websocket" - ], - "support": { - "issues": "https://github.com/utopia-php/websocket/issues", - "source": "https://github.com/utopia-php/websocket/tree/0.1.0" - }, - "time": "2021-12-20T10:50:09+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" - } - ], - "packages-dev": [ - { - "name": "appwrite/sdk-generator", - "version": "0.28.1", - "source": { - "type": "git", - "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", - "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "matthiasmullie/minify": "^1.3.68", - "php": ">=7.0.0", - "twig/twig": "^3.4.1" - }, - "require-dev": { - "brianium/paratest": "^6.4", - "phpunit/phpunit": "^9.5.21" - }, - "type": "library", - "autoload": { - "psr-4": { - "Appwrite\\SDK\\": "src/SDK", - "Appwrite\\Spec\\": "src/Spec" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - } - ], - "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", - "support": { - "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" - }, - "time": "2022-09-22T09:15:54+00:00" - }, - { - "name": "doctrine/annotations", - "version": "1.14.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^1 || ^2", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "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": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.2" - }, - "time": "2022-12-15T06:48:22+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "shasum": "" - }, - "require": { - "php": "^7.1|^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "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/v1.0.0" - }, - "time": "2022-05-02T15:47:09+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "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.22" - }, - "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.4.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%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2022-03-03T08:28:38+00:00" - }, - { - "name": "doctrine/lexer", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.0" - }, - "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.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%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-12-14T08:49:07+00:00" - }, - { - "name": "matthiasmullie/minify", - "version": "1.3.70", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.1", - "php": ">=5.3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": ">=2.0", - "matthiasmullie/scrapbook": ">=1.3", - "phpunit/phpunit": ">=4.8", - "squizlabs/php_codesniffer": ">=3.0" - }, - "suggest": { - "psr/cache-implementation": "Cache implementation to use with Minify::cache" - }, - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "https://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", - "homepage": "https://github.com/matthiasmullie/minify", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ], - "support": { - "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" - }, - "funding": [ - { - "url": "https://github.com/matthiasmullie", - "type": "github" - } - ], - "time": "2022-12-09T12:56:44+00:00" - }, - { - "name": "matthiasmullie/path-converter", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/path-converter.git", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "autoload": { - "psr-4": { - "MatthiasMullie\\PathConverter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "pathconverter@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "Relative path converter", - "homepage": "http://github.com/matthiasmullie/path-converter", - "keywords": [ - "converter", - "path", - "paths", - "relative" - ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, - "time": "2019-02-05T23:41:09+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" - }, - "time": "2022-11-12T15:38:23+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" - }, - "time": "2021-07-20T11:28:43+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpbench/container", - "version": "2.2.1", - "source": { - "type": "git", - "url": "https://github.com/phpbench/container.git", - "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/container/zipball/6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", - "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", - "shasum": "" - }, - "require": { - "psr/container": "^1.0|^2.0", - "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "phpstan/phpstan": "^0.12.52", - "phpunit/phpunit": "^8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "PhpBench\\DependencyInjection\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "Simple, configurable, service container.", - "support": { - "issues": "https://github.com/phpbench/container/issues", - "source": "https://github.com/phpbench/container/tree/2.2.1" - }, - "time": "2022-01-25T10:17:35+00:00" - }, - { - "name": "phpbench/dom", - "version": "0.3.2", - "source": { - "type": "git", - "url": "https://github.com/phpbench/dom.git", - "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/dom/zipball/b013b717832ddbaadf2a40984b04bc66af9a7110", - "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": "^7.2||^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.18", - "phpstan/phpstan": "^0.12.83", - "phpunit/phpunit": "^8.0||^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpBench\\Dom\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "DOM wrapper to simplify working with the PHP DOM implementation", - "support": { - "issues": "https://github.com/phpbench/dom/issues", - "source": "https://github.com/phpbench/dom/tree/0.3.2" - }, - "time": "2021-09-24T15:26:07+00:00" - }, - { - "name": "phpbench/phpbench", - "version": "1.2.7", - "source": { - "type": "git", - "url": "https://github.com/phpbench/phpbench.git", - "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpbench/phpbench/zipball/dce145304abbb16c8d9af69c19d96f47e9d0e670", - "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.13", - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "ext-tokenizer": "*", - "php": "^7.3 || ^8.0", - "phpbench/container": "^2.1", - "phpbench/dom": "~0.3.1", - "psr/log": "^1.1 || ^2.0 || ^3.0", - "seld/jsonlint": "^1.1", - "symfony/console": "^4.2 || ^5.0 || ^6.0", - "symfony/filesystem": "^4.2 || ^5.0 || ^6.0", - "symfony/finder": "^4.2 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0", - "symfony/process": "^4.2 || ^5.0 || ^6.0", - "webmozart/glob": "^4.6" - }, - "require-dev": { - "dantleech/invoke": "^2.0", - "friendsofphp/php-cs-fixer": "^3.0", - "jangregor/phpstan-prophecy": "^1.0", - "phpspec/prophecy": "^1.12", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5.8 || ^9.0", - "symfony/error-handler": "^5.2 || ^6.0", - "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0" - }, - "suggest": { - "ext-xdebug": "For Xdebug profiling extension." - }, - "bin": [ - "bin/phpbench" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "files": [ - "lib/Report/Func/functions.php" - ], - "psr-4": { - "PhpBench\\": "lib/", - "PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Leech", - "email": "daniel@dantleech.com" - } - ], - "description": "PHP Benchmarking Framework", - "support": { - "issues": "https://github.com/phpbench/phpbench/issues", - "source": "https://github.com/phpbench/phpbench/tree/1.2.7" - }, - "funding": [ - { - "url": "https://github.com/dantleech", - "type": "github" - } - ], - "time": "2022-10-15T09:57:51+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" - }, - "time": "2022-10-14T12:47:21+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.16.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" - }, - "time": "2022-11-29T15:06:56+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.23", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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 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", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-12-28T12:41:10+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2021-12-02T12:48:52+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:58:55+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T05:33:50+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "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/5.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:16:10+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.5.20", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", - "sebastian/version": "^3.0.2" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.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", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-01T12:37:26+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+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": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:08:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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/1.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:08:54+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:30:19+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T12:41:17+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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 calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T15:52:27+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-04-03T09:37:03+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "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", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-14T06:03:37+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-02-14T08:28:10+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.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", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-11-28T06:42:11+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", - "shasum": "" - }, - "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "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/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:12:34+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:14:26+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:45:17+00:00" - }, - { - "name": "sebastian/type", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "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": "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/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2022-09-12T14:47:03+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library 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/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T06:39:44+00:00" - }, - { - "name": "seld/jsonlint", - "version": "1.9.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", - "shasum": "" - }, - "require": { - "php": "^5.3 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" - }, - "bin": [ - "bin/jsonlint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Seld\\JsonLint\\": "src/Seld/JsonLint/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "JSON Linter", - "keywords": [ - "json", - "linter", - "parser", - "validator" - ], - "support": { - "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", - "type": "tidelift" - } - ], - "time": "2022-04-01T13:37:23+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.1", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2022-06-18T07:21:10+00:00" - }, - { - "name": "swoole/ide-helper", - "version": "4.8.9", - "source": { - "type": "git", - "url": "https://github.com/swoole/ide-helper.git", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", - "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/4.8.9" - }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-04-18T20:38:04+00:00" - }, - { - "name": "symfony/console", - "version": "v5.4.17", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", - "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" - }, - "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" - }, - "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "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/v5.4.17" - }, - "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": "2022-12-28T14:15:31+00:00" - }, - { - "name": "symfony/filesystem", - "version": "v5.4.13", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", - "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/polyfill-php80": "^1.16" - }, - "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/v5.4.13" - }, - "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": "2022-09-21T19:53:16+00:00" - }, - { - "name": "symfony/finder", - "version": "v5.4.17", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "40c08632019838dfb3350f18cf5563b8080055fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/40c08632019838dfb3350f18cf5563b8080055fc", - "reference": "40c08632019838dfb3350f18cf5563b8080055fc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" - }, - "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/v5.4.17" - }, - "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": "2022-12-22T10:31:03+00:00" - }, - { - "name": "symfony/options-resolver", - "version": "v5.4.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", - "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" - }, - "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/v5.4.11" - }, - "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": "2022-07-20T13:00:38+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-intl": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "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 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.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": "2022-11-03T14:55:06+00:00" - }, - { - "name": "symfony/process", - "version": "v5.4.11", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "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/v5.4.11" - }, - "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": "2022-06-27T16:58:25+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/container": "^2.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.3-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-11-25T10:21:52+00:00" - }, - { - "name": "symfony/string", - "version": "v6.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "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.0" - }, - "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.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/v6.2.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2022-12-14T16:11:27+00:00" - }, - { - "name": "textalk/websocket", - "version": "1.5.7", - "source": { - "type": "git", - "url": "https://github.com/Textalk/websocket-php.git", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", - "shasum": "" - }, - "require": { - "php": "^7.2 | ^8.0", - "psr/log": "^1 | ^2 | ^3" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.0", - "phpunit/phpunit": "^8.0|^9.0", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "WebSocket\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "ISC" - ], - "authors": [ - { - "name": "Fredrik Liljegren" - }, - { - "name": "Sören Jensen", - "email": "soren@abicart.se" - } - ], - "description": "WebSocket client and server", - "support": { - "issues": "https://github.com/Textalk/websocket-php/issues", - "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" - }, - "time": "2022-03-29T09:46:59+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", - "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.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "twig/twig", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" - }, - "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, - "autoload": { - "psr-4": { - "Twig\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Twig Team", - "role": "Contributors" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ - "templating" - ], - "support": { - "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/twig/twig", - "type": "tidelift" - } - ], - "time": "2022-12-27T12:28:18+00:00" - }, - { - "name": "webmozart/glob", - "version": "4.6.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/glob.git", - "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655", - "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "symfony/filesystem": "^5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Glob\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "A PHP implementation of Ant's glob.", - "support": { - "issues": "https://github.com/webmozarts/glob/issues", - "source": "https://github.com/webmozarts/glob/tree/4.6.0" - }, - "time": "2022-05-24T19:45:58+00:00" - } - ], - "aliases": [ - { - "package": "utopia-php/cache", - "version": "dev-feat-redis-sync", - "alias": "0.8.1", - "alias_normalized": "0.8.1.0" - } - ], - "minimum-stability": "stable", - "stability-flags": { - "utopia-php/cache": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=8.0.0", - "ext-curl": "*", - "ext-imagick": "*", - "ext-mbstring": "*", - "ext-json": "*", - "ext-yaml": "*", - "ext-dom": "*", - "ext-redis": "*", - "ext-swoole": "*", - "ext-pdo": "*", - "ext-openssl": "*", - "ext-zlib": "*", - "ext-sockets": "*" - }, - "platform-dev": { - "ext-fileinfo": "*" - }, - "platform-overrides": { - "php": "8.0" - }, - "plugin-api-version": "2.2.0" -} diff --git a/src/Appwrite/Event/Certificate.php b/src/Appwrite/Event/Certificate.php index e56b922ee5..a33c21740d 100644 --- a/src/Appwrite/Event/Certificate.php +++ b/src/Appwrite/Event/Certificate.php @@ -13,7 +13,7 @@ class Certificate extends Event public function __construct(protected Connection $connection) { - parent::__construct(Event::FUNCTIONS_QUEUE_NAME, Event::FUNCTIONS_CLASS_NAME); + parent::__construct(Event::CERTIFICATES_QUEUE_NAME, Event::CERTIFICATES_CLASS_NAME); } /** @@ -71,6 +71,7 @@ public function getSkipRenewCheck(): bool public function trigger(): string|bool { $client = new Client($this->queue, $this->connection); + return $client->enqueue([ 'project' => $this->project, 'domain' => $this->domain, diff --git a/src/Appwrite/Event/Delete.php b/src/Appwrite/Event/Delete.php index 32c84ee90c..d174396062 100644 --- a/src/Appwrite/Event/Delete.php +++ b/src/Appwrite/Event/Delete.php @@ -17,7 +17,7 @@ class Delete extends Event public function __construct(protected Connection $connection) { - parent::__construct(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, $connection); + parent::__construct(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME); } /** @@ -124,8 +124,6 @@ public function trigger(): string|bool { $client = new Client($this->queue, $this->connection); - $events = $this->getEvent() ? Event::generateEvents($this->getEvent(), $this->getParams()) : null; - return $client->enqueue([ 'project' => $this->project, 'type' => $this->type, From 91c818c6386a82c7403be54b09fd657de9bbabcd Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 5 Jan 2023 19:35:24 +0200 Subject: [PATCH 59/87] deletes-worker --- app/init.php | 4 +- app/workers/deletes.php | 1058 +++++++++---------- docker-compose.yml | 5 +- src/Appwrite/Platform/Tasks/EdgeSync.php | 2 +- src/Appwrite/Platform/Tasks/Maintenance.php | 4 +- 5 files changed, 538 insertions(+), 535 deletions(-) diff --git a/app/init.php b/app/init.php index acfc16ffeb..090f51d39f 100644 --- a/app/init.php +++ b/app/init.php @@ -41,7 +41,6 @@ use Appwrite\Usage\Stats; use Utopia\App; use Utopia\Queue\Client; -use Utopia\Queue\Server; use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Database\ID; @@ -860,6 +859,9 @@ function (mixed $value) { App::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); }, ['pools']); +App::setResource('queueForDeletes', function (Connection $queue) { + return new Delete($queue); +}, ['queue']); App::setResource('queueForFunctions', function (Connection $queue) { return new Func($queue); }, ['queue']); diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 6bf29cc3ff..a17c7f4229 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -1,5 +1,7 @@ job() + ->inject('message') + ->action(function (Message $message) { + $payload = $message->getPayload() ?? []; - public function init(): void - { - } + if (empty($payload)) { + throw new Exception('Missing payload'); + } - public function run(): void - { - $project = new Document($this->args['project'] ?? []); - $type = $this->args['type'] ?? ''; + $project = new Document($payload['project'] ?? []); + $type = $payload['type'] ?? ''; switch (strval($type)) { case DELETE_TYPE_DOCUMENT: - $document = new Document($this->args['document'] ?? []); + $document = new Document($payload['document'] ?? []); switch ($document->getCollection()) { case DELETE_TYPE_DATABASES: - $this->deleteDatabase($document, $project); + deleteDatabase($document, $project); break; case DELETE_TYPE_COLLECTIONS: - $this->deleteCollection($document, $project); + deleteCollection($document, $project); break; case DELETE_TYPE_PROJECTS: - $this->deleteProject($document); + deleteProject($document); break; case DELETE_TYPE_FUNCTIONS: - $this->deleteFunction($document, $project); + deleteFunction($document, $project); break; case DELETE_TYPE_DEPLOYMENTS: - $this->deleteDeployment($document, $project); + deleteDeployment($document, $project); break; case DELETE_TYPE_USERS: - $this->deleteUser($document, $project); + deleteUser($document, $project); break; case DELETE_TYPE_TEAMS: - $this->deleteMemberships($document, $project); + deleteMemberships($document, $project); break; case DELETE_TYPE_BUCKETS: - $this->deleteBucket($document, $project); + deleteBucket($document, $project); break; default: Console::error('No lazy delete operation available for document of type: ' . $document->getCollection()); @@ -72,664 +69,663 @@ public function run(): void break; case DELETE_TYPE_EXECUTIONS: - $this->deleteExecutionLogs($this->args['datetime']); + deleteExecutionLogs($payload['datetime']); break; case DELETE_TYPE_AUDIT: - $datetime = $this->args['datetime'] ?? null; + $datetime = $payload['datetime'] ?? null; if (!empty($datetime)) { - $this->deleteAuditLogs($datetime); + deleteAuditLogs($datetime); } - $document = new Document($this->args['document'] ?? []); + $document = new Document($payload['document'] ?? []); if (!$document->isEmpty()) { - $this->deleteAuditLogsByResource('document/' . $document->getId(), $project); + deleteAuditLogsByResource('document/' . $document->getId(), $project); } break; case DELETE_TYPE_ABUSE: - $this->deleteAbuseLogs($this->args['datetime']); + deleteAbuseLogs($payload['datetime']); break; case DELETE_TYPE_REALTIME: - $this->deleteRealtimeUsage($this->args['datetime']); + deleteRealtimeUsage($payload['datetime']); break; case DELETE_TYPE_SESSIONS: - $this->deleteExpiredSessions(); + deleteExpiredSessions(); break; case DELETE_TYPE_CERTIFICATES: - $document = new Document($this->args['document']); - $this->deleteCertificates($document); + $document = new Document($payload['document']); + deleteCertificates($document); break; case DELETE_TYPE_USAGE: - $this->deleteUsageStats($this->args['hourlyUsageRetentionDatetime']); + deleteUsageStats($payload['hourlyUsageRetentionDatetime']); break; case DELETE_TYPE_CACHE_BY_RESOURCE: - $this->deleteCacheByResource($this->args['resource']); + deleteCacheByResource($payload['resource']); break; case DELETE_TYPE_CACHE_BY_TIMESTAMP: - $this->deleteCacheByDate(); + deleteCacheByDate($payload); break; case DELETE_TYPE_SCHEDULES: - $this->deleteSchedules($this->args['datetime']); + deleteSchedules($payload['datetime']); break; default: Console::error('No delete operation for type: ' . $type); break; } - } + }); - public function shutdown(): void - { - } - /** - * @throws Exception - */ - protected function deleteSchedules(string $datetime): void - { - $this->listByGroup( - 'schedules', - [ - Query::equal('region', [App::getEnv('_APP_REGION', 'default')]), - Query::equal('resourceType', ['function']), - Query::lessThanEqual('resourceUpdatedAt', $datetime), - Query::equal('active', [false]), - ], - $this->getConsoleDB(), - function (Document $document) { - $project = $this->getConsoleDB()->getDocument('projects', $document->getAttribute('projectId')); - - if ($project->isEmpty()) { - Console::warning('Unable to delete schedule for function ' . $document->getAttribute('resourceId')); - return; - } +/** + * @throws Exception + */ +function deleteSchedules(string $datetime): void +{ + listByGroup( + 'schedules', + [ + Query::equal('region', [App::getEnv('_APP_REGION', 'default')]), + Query::equal('resourceType', ['function']), + Query::lessThanEqual('resourceUpdatedAt', $datetime), + Query::equal('active', [false]), + ], + getConsoleDB(), + function (Document $document) { + $project = getConsoleDB()->getDocument('projects', $document->getAttribute('projectId')); + + if ($project->isEmpty()) { + Console::warning('Unable to delete schedule for function ' . $document->getAttribute('resourceId')); + return; + } - $function = $this->getProjectDB($project)->getDocument('functions', $document->getAttribute('resourceId')); + $function = getProjectDB($project)->getDocument('functions', $document->getAttribute('resourceId')); - if ($function->isEmpty()) { - $this->getConsoleDB()->deleteDocument('schedules', $document->getId()); - Console::success('Deleting schedule for function ' . $document->getAttribute('resourceId')); - } + if ($function->isEmpty()) { + getConsoleDB()->deleteDocument('schedules', $document->getId()); + Console::success('Deleting schedule for function ' . $document->getAttribute('resourceId')); } - ); - } + } + ); +} - /** - * @param string $resource - */ - protected function deleteCacheByResource(string $resource): void - { - $this->deleteCacheFiles([ - Query::equal('resource', [$resource]), - ]); - } +/** + * @param string $resource + */ +function deleteCacheByResource(string $resource): void +{ + deleteCacheFiles([ + Query::equal('resource', [$resource]), + ]); +} - protected function deleteCacheByDate(): void - { - $this->deleteCacheFiles([ - Query::lessThan('accessedAt', $this->args['datetime']), - ]); - } +function deleteCacheByDate($payload): void +{ + deleteCacheFiles([ + Query::lessThan('accessedAt', $payload['datetime']), + ]); +} - protected function deleteCacheFiles($query): void - { - $this->deleteForProjectIds(function (Document $project) use ($query) { - - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $cache = new Cache( - new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) - ); - - $this->deleteByGroup( - 'cache', - $query, - $dbForProject, - function (Document $document) use ($cache, $projectId) { - $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); - - if ($cache->purge($document->getId())) { - Console::success('Deleting cache file: ' . $path); - } else { - Console::error('Failed to delete cache file: ' . $path); - } - } - ); - }); - } +function deleteCacheFiles($query): void +{ + deleteForProjectIds(function (Document $project) use ($query) { - /** - * @param Document $document database document - * @param Document $projectId - */ - protected function deleteDatabase(Document $document, Document $project): void - { - $databaseId = $document->getId(); $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $cache = new Cache( + new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId) + ); - $dbForProject = $this->getProjectDB($project); + deleteByGroup( + 'cache', + $query, + $dbForProject, + function (Document $document) use ($cache, $projectId) { + $path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId(); - $this->deleteByGroup('database_' . $document->getInternalId(), [], $dbForProject, function ($document) use ($project) { - $this->deleteCollection($document, $project); - }); + if ($cache->purge($document->getId())) { + Console::success('Deleting cache file: ' . $path); + } else { + Console::error('Failed to delete cache file: ' . $path); + } + } + ); + }); +} - $dbForProject->deleteCollection('database_' . $document->getInternalId()); +/** + * @param Document $document database document + * @param Document $projectId + */ +function deleteDatabase(Document $document, Document $project): void +{ + $databaseId = $document->getId(); + $projectId = $project->getId(); - $this->deleteAuditLogsByResource('database/' . $databaseId, $project); - } + $dbForProject = getProjectDB($project); - /** - * @param Document $document teams document - * @param Document $project - */ - protected function deleteCollection(Document $document, Document $project): void - { - $collectionId = $document->getId(); - $databaseId = $document->getAttribute('databaseId'); - $databaseInternalId = $document->getAttribute('databaseInternalId'); + deleteByGroup('database_' . $document->getInternalId(), [], $dbForProject, function ($document) use ($project) { + deleteCollection($document, $project); + }); - $dbForProject = $this->getProjectDB($project); + $dbForProject->deleteCollection('database_' . $document->getInternalId()); - $dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $document->getInternalId()); + deleteAuditLogsByResource('database/' . $databaseId, $project); +} - $this->deleteByGroup('attributes', [ - Query::equal('databaseId', [$databaseId]), - Query::equal('collectionId', [$collectionId]) - ], $dbForProject); +/** + * @param Document $document teams document + * @param Document $project + */ +function deleteCollection(Document $document, Document $project): void +{ + $collectionId = $document->getId(); + $databaseId = $document->getAttribute('databaseId'); + $databaseInternalId = $document->getAttribute('databaseInternalId'); - $this->deleteByGroup('indexes', [ - Query::equal('databaseId', [$databaseId]), - Query::equal('collectionId', [$collectionId]) - ], $dbForProject); + $dbForProject = getProjectDB($project); - $this->deleteAuditLogsByResource('database/' . $databaseId . '/collection/' . $collectionId, $project); - } + $dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $document->getInternalId()); - /** - * @param string $hourlyUsageRetentionDatetime - */ - protected function deleteUsageStats(string $hourlyUsageRetentionDatetime) - { - $this->deleteForProjectIds(function (Document $project) use ($hourlyUsageRetentionDatetime) { - $dbForProject = $this->getProjectDB($project); - // Delete Usage stats - $this->deleteByGroup('stats', [ - Query::lessThan('time', $hourlyUsageRetentionDatetime), - Query::equal('period', ['1h']), - ], $dbForProject); - }); - } + deleteByGroup('attributes', [ + Query::equal('databaseId', [$databaseId]), + Query::equal('collectionId', [$collectionId]) + ], $dbForProject); - /** - * @param Document $document teams document - * @param Document $project - */ - protected function deleteMemberships(Document $document, Document $project): void - { - $teamId = $document->getAttribute('teamId', ''); - - // Delete Memberships - $this->deleteByGroup('memberships', [ - Query::equal('teamId', [$teamId]) - ], $this->getProjectDB($project)); - } + deleteByGroup('indexes', [ + Query::equal('databaseId', [$databaseId]), + Query::equal('collectionId', [$collectionId]) + ], $dbForProject); - /** - * @param Document $document project document - */ - protected function deleteProject(Document $document): void - { - $projectId = $document->getId(); + deleteAuditLogsByResource('database/' . $databaseId . '/collection/' . $collectionId, $project); +} - // Delete all DBs - $this->getProjectDB($document)->delete($projectId); +/** + * @param string $hourlyUsageRetentionDatetime + */ +function deleteUsageStats(string $hourlyUsageRetentionDatetime) +{ + deleteForProjectIds(function (Document $project) use ($hourlyUsageRetentionDatetime) { + $dbForProject = getProjectDB($project); + // Delete Usage stats + deleteByGroup('stats', [ + Query::lessThan('time', $hourlyUsageRetentionDatetime), + Query::equal('period', ['1h']), + ], $dbForProject); + }); +} - // Delete all storage directories - $uploads = $this->getFilesDevice($document->getId()); - $cache = new Local(APP_STORAGE_CACHE . '/app-' . $document->getId()); +/** + * @param Document $document teams document + * @param Document $project + */ +function deleteMemberships(Document $document, Document $project): void +{ + $teamId = $document->getAttribute('teamId', ''); - $uploads->delete($uploads->getRoot(), true); - $cache->delete($cache->getRoot(), true); - } + // Delete Memberships + deleteByGroup('memberships', [ + Query::equal('teamId', [$teamId]) + ], getProjectDB($project)); +} - /** - * @param Document $document user document - * @param Document $project - */ - protected function deleteUser(Document $document, Document $project): void - { - $userId = $document->getId(); +/** + * @param Document $document project document + */ +function deleteProject(Document $document): void +{ + $projectId = $document->getId(); - $dbForProject = $this->getProjectDB($project); + // Delete all DBs + getProjectDB($document)->delete($projectId); - // Delete all sessions of this user from the sessions table and update the sessions field of the user record - $this->deleteByGroup('sessions', [ - Query::equal('userId', [$userId]) - ], $dbForProject); + // Delete all storage directories + $uploads = getFilesDevice($document->getId()); + $cache = new Local(APP_STORAGE_CACHE . '/app-' . $document->getId()); - $dbForProject->deleteCachedDocument('users', $userId); - - // Delete Memberships and decrement team membership counts - $this->deleteByGroup('memberships', [ - Query::equal('userId', [$userId]) - ], $dbForProject, function (Document $document) use ($dbForProject) { - if ($document->getAttribute('confirm')) { // Count only confirmed members - $teamId = $document->getAttribute('teamId'); - $team = $dbForProject->getDocument('teams', $teamId); - if (!$team->isEmpty()) { - $team = $dbForProject->updateDocument( - 'teams', - $teamId, - // Ensure that total >= 0 - $team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0)) - ); - } + $uploads->delete($uploads->getRoot(), true); + $cache->delete($cache->getRoot(), true); +} + +/** + * @param Document $document user document + * @param Document $project + */ +function deleteUser(Document $document, Document $project): void +{ + $userId = $document->getId(); + + $dbForProject = getProjectDB($project); + + // Delete all sessions of this user from the sessions table and update the sessions field of the user record + deleteByGroup('sessions', [ + Query::equal('userId', [$userId]) + ], $dbForProject); + + $dbForProject->deleteCachedDocument('users', $userId); + + // Delete Memberships and decrement team membership counts + deleteByGroup('memberships', [ + Query::equal('userId', [$userId]) + ], $dbForProject, function (Document $document) use ($dbForProject) { + if ($document->getAttribute('confirm')) { // Count only confirmed members + $teamId = $document->getAttribute('teamId'); + $team = $dbForProject->getDocument('teams', $teamId); + if (!$team->isEmpty()) { + $team = $dbForProject->updateDocument( + 'teams', + $teamId, + // Ensure that total >= 0 + $team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0)) + ); } - }); + } + }); + + // Delete tokens + deleteByGroup('tokens', [ + Query::equal('userId', [$userId]) + ], $dbForProject); +} - // Delete tokens - $this->deleteByGroup('tokens', [ - Query::equal('userId', [$userId]) +/** + * @param string $datetime + */ +function deleteExecutionLogs(string $datetime): void +{ + deleteForProjectIds(function (Document $project) use ($datetime) { + $dbForProject = getProjectDB($project); + // Delete Executions + deleteByGroup('executions', [ + Query::lessThan('$createdAt', $datetime) ], $dbForProject); - } + }); +} - /** - * @param string $datetime - */ - protected function deleteExecutionLogs(string $datetime): void - { - $this->deleteForProjectIds(function (Document $project) use ($datetime) { - $dbForProject = $this->getProjectDB($project); - // Delete Executions - $this->deleteByGroup('executions', [ - Query::lessThan('$createdAt', $datetime) - ], $dbForProject); - }); - } +function deleteExpiredSessions(): void +{ + $consoleDB = getConsoleDB(); - protected function deleteExpiredSessions(): void - { - $consoleDB = $this->getConsoleDB(); + deleteForProjectIds(function (Document $project) use ($consoleDB) { + $dbForProject = getProjectDB($project); - $this->deleteForProjectIds(function (Document $project) use ($consoleDB) { - $dbForProject = $this->getProjectDB($project); + $project = $consoleDB->getDocument('projects', $project->getId()); + $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; + $expired = DateTime::addSeconds(new \DateTime(), -1 * $duration); - $project = $consoleDB->getDocument('projects', $project->getId()); - $duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG; - $expired = DateTime::addSeconds(new \DateTime(), -1 * $duration); + // Delete Sessions + deleteByGroup('sessions', [ + Query::lessThan('$createdAt', $expired) + ], $dbForProject); + }); +} - // Delete Sessions - $this->deleteByGroup('sessions', [ - Query::lessThan('$createdAt', $expired) - ], $dbForProject); - }); - } +/** + * @param string $datetime + */ +function deleteRealtimeUsage(string $datetime): void +{ + deleteForProjectIds(function (Document $project) use ($datetime) { + $dbForProject = getProjectDB($project); + // Delete Dead Realtime Logs + deleteByGroup('realtime', [ + Query::lessThan('timestamp', $datetime) + ], $dbForProject); + }); +} - /** - * @param string $datetime - */ - protected function deleteRealtimeUsage(string $datetime): void - { - $this->deleteForProjectIds(function (Document $project) use ($datetime) { - $dbForProject = $this->getProjectDB($project); - // Delete Dead Realtime Logs - $this->deleteByGroup('realtime', [ - Query::lessThan('timestamp', $datetime) - ], $dbForProject); - }); +/** + * @param string $datetime + * @throws Exception + */ +function deleteAbuseLogs(string $datetime): void +{ + if (empty($datetime)) { + throw new Exception('Failed to delete audit logs. No datetime provided'); } - /** - * @param string $datetime - * @throws Exception - */ - protected function deleteAbuseLogs(string $datetime): void - { - if (empty($datetime)) { - throw new Exception('Failed to delete audit logs. No datetime provided'); + deleteForProjectIds(function (Document $project) use ($datetime) { + $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $timeLimit = new TimeLimit("", 0, 1, $dbForProject); + $abuse = new Abuse($timeLimit); + $status = $abuse->cleanup($datetime); + if (!$status) { + throw new Exception('Failed to delete Abuse logs for project ' . $projectId); } + }); +} - $this->deleteForProjectIds(function (Document $project) use ($datetime) { - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $timeLimit = new TimeLimit("", 0, 1, $dbForProject); - $abuse = new Abuse($timeLimit); - $status = $abuse->cleanup($datetime); - if (!$status) { - throw new Exception('Failed to delete Abuse logs for project ' . $projectId); - } - }); +/** + * @param string $datetime + * @throws Exception + */ +function deleteAuditLogs(string $datetime): void +{ + if (empty($datetime)) { + throw new Exception('Failed to delete audit logs. No datetime provided'); } - /** - * @param string $datetime - * @throws Exception - */ - protected function deleteAuditLogs(string $datetime): void - { - if (empty($datetime)) { - throw new Exception('Failed to delete audit logs. No datetime provided'); + deleteForProjectIds(function (Document $project) use ($datetime) { + $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $audit = new Audit($dbForProject); + $status = $audit->cleanup($datetime); + if (!$status) { + throw new Exception('Failed to delete Audit logs for project' . $projectId); } + }); +} - $this->deleteForProjectIds(function (Document $project) use ($datetime) { - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $audit = new Audit($dbForProject); - $status = $audit->cleanup($datetime); - if (!$status) { - throw new Exception('Failed to delete Audit logs for project' . $projectId); - } - }); - } +/** + * @param string $resource + * @param Document $project + */ +function deleteAuditLogsByResource(string $resource, Document $project): void +{ + $dbForProject = getProjectDB($project); - /** - * @param string $resource - * @param Document $project - */ - protected function deleteAuditLogsByResource(string $resource, Document $project): void - { - $dbForProject = $this->getProjectDB($project); + deleteByGroup(Audit::COLLECTION, [ + Query::equal('resource', [$resource]) + ], $dbForProject); +} - $this->deleteByGroup(Audit::COLLECTION, [ - Query::equal('resource', [$resource]) - ], $dbForProject); - } +/** + * @param Document $document function document + * @param Document $project + */ +function deleteFunction(Document $document, Document $project): void +{ + $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $functionId = $document->getId(); /** - * @param Document $document function document - * @param Document $project + * Delete Variables */ - protected function deleteFunction(Document $document, Document $project): void - { - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $functionId = $document->getId(); - - /** - * Delete Variables - */ - Console::info("Deleting variables for function " . $functionId); - $this->deleteByGroup('variables', [ - Query::equal('functionId', [$functionId]) - ], $dbForProject); - - /** - * Delete Deployments - */ - Console::info("Deleting deployments for function " . $functionId); - $storageFunctions = $this->getFunctionsDevice($projectId); - $deploymentIds = []; - $this->deleteByGroup('deployments', [ - Query::equal('resourceId', [$functionId]) - ], $dbForProject, function (Document $document) use ($storageFunctions, &$deploymentIds) { - $deploymentIds[] = $document->getId(); - if ($storageFunctions->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted deployment files: ' . $document->getAttribute('path', '')); - } else { - Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', '')); - } - }); - - /** - * Delete builds - */ - Console::info("Deleting builds for function " . $functionId); - $storageBuilds = $this->getBuildsDevice($projectId); - foreach ($deploymentIds as $deploymentId) { - $this->deleteByGroup('builds', [ - Query::equal('deploymentId', [$deploymentId]) - ], $dbForProject, function (Document $document) use ($storageBuilds, $deploymentId) { - if ($storageBuilds->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted build files: ' . $document->getAttribute('path', '')); - } else { - Console::error('Failed to delete build files: ' . $document->getAttribute('path', '')); - } - }); - } - - /** - * Delete Executions - */ - Console::info("Deleting executions for function " . $functionId); - $this->deleteByGroup('executions', [ - Query::equal('functionId', [$functionId]) - ], $dbForProject); - - // TODO: Request executor to delete runtime - } + Console::info("Deleting variables for function " . $functionId); + deleteByGroup('variables', [ + Query::equal('functionId', [$functionId]) + ], $dbForProject); /** - * @param Document $document deployment document - * @param Document $project + * Delete Deployments */ - protected function deleteDeployment(Document $document, Document $project): void - { - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $deploymentId = $document->getId(); - $functionId = $document->getAttribute('resourceId'); - - /** - * Delete deployment files - */ - Console::info("Deleting deployment files for deployment " . $deploymentId); - $storageFunctions = $this->getFunctionsDevice($projectId); + Console::info("Deleting deployments for function " . $functionId); + $storageFunctions = getFunctionsDevice($projectId); + $deploymentIds = []; + deleteByGroup('deployments', [ + Query::equal('resourceId', [$functionId]) + ], $dbForProject, function (Document $document) use ($storageFunctions, &$deploymentIds) { + $deploymentIds[] = $document->getId(); if ($storageFunctions->delete($document->getAttribute('path', ''), true)) { Console::success('Deleted deployment files: ' . $document->getAttribute('path', '')); } else { Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', '')); } + }); - /** - * Delete builds - */ - Console::info("Deleting builds for deployment " . $deploymentId); - $storageBuilds = $this->getBuildsDevice($projectId); - $this->deleteByGroup('builds', [ + /** + * Delete builds + */ + Console::info("Deleting builds for function " . $functionId); + $storageBuilds = getBuildsDevice($projectId); + foreach ($deploymentIds as $deploymentId) { + deleteByGroup('builds', [ Query::equal('deploymentId', [$deploymentId]) - ], $dbForProject, function (Document $document) use ($storageBuilds) { + ], $dbForProject, function (Document $document) use ($storageBuilds, $deploymentId) { if ($storageBuilds->delete($document->getAttribute('path', ''), true)) { Console::success('Deleted build files: ' . $document->getAttribute('path', '')); } else { Console::error('Failed to delete build files: ' . $document->getAttribute('path', '')); } }); - - // TODO: Request executor to delete runtime } - /** - * @param Document $document to be deleted - * @param Database $database to delete it from - * @param callable $callback to perform after document is deleted - * - * @return bool + * Delete Executions */ - protected function deleteById(Document $document, Database $database, callable $callback = null): bool - { - if ($database->deleteDocument($document->getCollection(), $document->getId())) { - Console::success('Deleted document "' . $document->getId() . '" successfully'); + Console::info("Deleting executions for function " . $functionId); + deleteByGroup('executions', [ + Query::equal('functionId', [$functionId]) + ], $dbForProject); - if (is_callable($callback)) { - $callback($document); - } + // TODO: Request executor to delete runtime +} - return true; - } else { - Console::error('Failed to delete document: ' . $document->getId()); - return false; - } - } +/** + * @param Document $document deployment document + * @param Document $project + */ +function deleteDeployment(Document $document, Document $project): void +{ + $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $deploymentId = $document->getId(); + $functionId = $document->getAttribute('resourceId'); /** - * @param callable $callback + * Delete deployment files */ - protected function deleteForProjectIds(callable $callback): void - { - // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document - $count = 0; - $chunk = 0; - $limit = 50; - $projects = []; - $sum = $limit; + Console::info("Deleting deployment files for deployment " . $deploymentId); + $storageFunctions = getFunctionsDevice($projectId); + if ($storageFunctions->delete($document->getAttribute('path', ''), true)) { + Console::success('Deleted deployment files: ' . $document->getAttribute('path', '')); + } else { + Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', '')); + } - $executionStart = \microtime(true); + /** + * Delete builds + */ + Console::info("Deleting builds for deployment " . $deploymentId); + $storageBuilds = getBuildsDevice($projectId); + deleteByGroup('builds', [ + Query::equal('deploymentId', [$deploymentId]) + ], $dbForProject, function (Document $document) use ($storageBuilds) { + if ($storageBuilds->delete($document->getAttribute('path', ''), true)) { + Console::success('Deleted build files: ' . $document->getAttribute('path', '')); + } else { + Console::error('Failed to delete build files: ' . $document->getAttribute('path', '')); + } + }); - while ($sum === $limit) { - $projects = $this->getConsoleDB()->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]); + // TODO: Request executor to delete runtime +} - $chunk++; - /** @var string[] $projectIds */ - $sum = count($projects); +/** + * @param Document $document to be deleted + * @param Database $database to delete it from + * @param callable $callback to perform after document is deleted + * + * @return bool + */ +function deleteById(Document $document, Database $database, callable $callback = null): bool +{ + if ($database->deleteDocument($document->getCollection(), $document->getId())) { + Console::success('Deleted document "' . $document->getId() . '" successfully'); - Console::info('Executing delete function for chunk #' . $chunk . '. Found ' . $sum . ' projects'); - foreach ($projects as $project) { - $callback($project); - $count++; - } + if (is_callable($callback)) { + $callback($document); } - $executionEnd = \microtime(true); - Console::info("Found {$count} projects " . ($executionEnd - $executionStart) . " seconds"); + return true; + } else { + Console::error('Failed to delete document: ' . $document->getId()); + return false; } +} - /** - * @param string $collection collectionID - * @param Query[] $queries - * @param Database $database - * @param callable $callback - */ - protected function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void - { - $count = 0; - $chunk = 0; - $limit = 50; - $results = []; - $sum = $limit; - - $executionStart = \microtime(true); +/** + * @param callable $callback + */ +function deleteForProjectIds(callable $callback): void +{ + // TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document + $count = 0; + $chunk = 0; + $limit = 50; + $projects = []; + $sum = $limit; - while ($sum === $limit) { - $chunk++; + $executionStart = \microtime(true); - $results = $database->find($collection, \array_merge([Query::limit($limit)], $queries)); + while ($sum === $limit) { + $projects = getConsoleDB()->find('projects', [Query::limit($limit), Query::offset($chunk * $limit)]); - $sum = count($results); + $chunk++; - Console::info('Deleting chunk #' . $chunk . '. Found ' . $sum . ' documents'); + /** @var string[] $projectIds */ + $sum = count($projects); - foreach ($results as $document) { - $this->deleteById($document, $database, $callback); - $count++; - } + Console::info('Executing delete function for chunk #' . $chunk . '. Found ' . $sum . ' projects'); + foreach ($projects as $project) { + $callback($project); + $count++; } + } - $executionEnd = \microtime(true); + $executionEnd = \microtime(true); + Console::info("Found {$count} projects " . ($executionEnd - $executionStart) . " seconds"); +} + +/** + * @param string $collection collectionID + * @param Query[] $queries + * @param Database $database + * @param callable $callback + */ +function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void +{ + $count = 0; + $chunk = 0; + $limit = 50; + $results = []; + $sum = $limit; - Console::info("Deleted {$count} document by group in " . ($executionEnd - $executionStart) . " seconds"); + $executionStart = \microtime(true); + + while ($sum === $limit) { + $chunk++; + + $results = $database->find($collection, \array_merge([Query::limit($limit)], $queries)); + + $sum = count($results); + + Console::info('Deleting chunk #' . $chunk . '. Found ' . $sum . ' documents'); + + foreach ($results as $document) { + deleteById($document, $database, $callback); + $count++; + } } - /** - * @param string $collection collectionID - * @param Query[] $queries - * @param Database $database - * @param callable $callback - */ - protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void - { - $count = 0; - $chunk = 0; - $limit = 50; - $results = []; - $sum = $limit; + $executionEnd = \microtime(true); + + Console::info("Deleted {$count} document by group in " . ($executionEnd - $executionStart) . " seconds"); +} - $executionStart = \microtime(true); +/** + * @param string $collection collectionID + * @param Query[] $queries + * @param Database $database + * @param callable $callback + */ +function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void +{ + $count = 0; + $chunk = 0; + $limit = 50; + $results = []; + $sum = $limit; - while ($sum === $limit) { - $chunk++; + $executionStart = \microtime(true); - $results = $database->find($collection, \array_merge([Query::limit($limit)], $queries)); + while ($sum === $limit) { + $chunk++; - $sum = count($results); + $results = $database->find($collection, \array_merge([Query::limit($limit)], $queries)); - foreach ($results as $document) { - if (is_callable($callback)) { - $callback($document); - } + $sum = count($results); - $count++; + foreach ($results as $document) { + if (is_callable($callback)) { + $callback($document); } + + $count++; } + } - $executionEnd = \microtime(true); + $executionEnd = \microtime(true); - Console::info("Listed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds"); - } + Console::info("Listed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds"); +} - /** - * @param Document $document certificates document - */ - protected function deleteCertificates(Document $document): void - { - $consoleDB = $this->getConsoleDB(); +/** + * @param Document $document certificates document + */ +function deleteCertificates(Document $document): void +{ + $consoleDB = getConsoleDB(); - // If domain has certificate generated - if (isset($document['certificateId'])) { - $domainUsingCertificate = $consoleDB->findOne('domains', [ - Query::equal('certificateId', [$document['certificateId']]) - ]); - - if (!$domainUsingCertificate) { - $mainDomain = App::getEnv('_APP_DOMAIN_TARGET', ''); - if ($mainDomain === $document->getAttribute('domain')) { - $domainUsingCertificate = $mainDomain; - } - } + // If domain has certificate generated + if (isset($document['certificateId'])) { + $domainUsingCertificate = $consoleDB->findOne('domains', [ + Query::equal('certificateId', [$document['certificateId']]) + ]); - // If certificate is still used by some domain, mark we can't delete. - // Current domain should not be found, because we only have copy. Original domain is already deleted from database. - if ($domainUsingCertificate) { - Console::warning("Skipping certificate deletion, because a domain is still using it."); - return; + if (!$domainUsingCertificate) { + $mainDomain = App::getEnv('_APP_DOMAIN_TARGET', ''); + if ($mainDomain === $document->getAttribute('domain')) { + $domainUsingCertificate = $mainDomain; } } - $domain = $document->getAttribute('domain'); - $directory = APP_STORAGE_CERTIFICATES . '/' . $domain; - $checkTraversal = realpath($directory) === $directory; + // If certificate is still used by some domain, mark we can't delete. + // Current domain should not be found, because we only have copy. Original domain is already deleted from database. + if ($domainUsingCertificate) { + Console::warning("Skipping certificate deletion, because a domain is still using it."); + return; + } + } - if ($domain && $checkTraversal && is_dir($directory)) { - // Delete certificate document, so Appwrite is aware of change - if (isset($document['certificateId'])) { - $consoleDB->deleteDocument('certificates', $document['certificateId']); - } + $domain = $document->getAttribute('domain'); + $directory = APP_STORAGE_CERTIFICATES . '/' . $domain; + $checkTraversal = realpath($directory) === $directory; - // Delete files, so Traefik is aware of change - array_map('unlink', glob($directory . '/*.*')); - rmdir($directory); - Console::info("Deleted certificate files for {$domain}"); - } else { - Console::info("No certificate files found for {$domain}"); + if ($domain && $checkTraversal && is_dir($directory)) { + // Delete certificate document, so Appwrite is aware of change + if (isset($document['certificateId'])) { + $consoleDB->deleteDocument('certificates', $document['certificateId']); } + + // Delete files, so Traefik is aware of change + array_map('unlink', glob($directory . '/*.*')); + rmdir($directory); + Console::info("Deleted certificate files for {$domain}"); + } else { + Console::info("No certificate files found for {$domain}"); } +} - protected function deleteBucket(Document $document, Document $project) - { - $projectId = $project->getId(); - $dbForProject = $this->getProjectDB($project); - $dbForProject->deleteCollection('bucket_' . $document->getInternalId()); +function deleteBucket(Document $document, Document $project) +{ + $projectId = $project->getId(); + $dbForProject = getProjectDB($project); + $dbForProject->deleteCollection('bucket_' . $document->getInternalId()); - $device = $this->getFilesDevice($projectId); + $device = getFilesDevice($projectId); - $device->deletePath($document->getId()); - } + $device->deletePath($document->getId()); } + +$server->workerStart(); +$server->start(); \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 813a785a7d..fe430fbb07 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -392,6 +392,7 @@ services: - _APP_LOGGING_CONFIG - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST + - _APP_REGION appwrite-worker-databases: entrypoint: worker-databases @@ -505,6 +506,7 @@ services: - _APP_CONNECTIONS_QUEUE - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG + - _APP_REGION appwrite-worker-functions: entrypoint: worker-functions @@ -637,9 +639,10 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_CACHE diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index ce30729960..f4450785dc 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -83,7 +83,7 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi ]); } } - if (!$found) { + if (!$found) { Console::info("[{$time}] No keys where found for region {$code}."); } } diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index c25341bce7..2f236d32ca 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -1,4 +1,5 @@ Date: Sun, 8 Jan 2023 09:19:08 +0200 Subject: [PATCH 60/87] deletes-queue --- app/controllers/api/databases.php | 18 +++++++-------- app/controllers/api/functions.php | 12 +++++----- app/controllers/api/projects.php | 18 +++++++-------- app/controllers/api/storage.php | 18 +++++++-------- app/controllers/api/teams.php | 6 ++--- app/controllers/api/users.php | 6 ++--- app/controllers/general.php | 5 +++-- app/controllers/shared/api.php | 8 +++---- docker-compose.yml | 25 +++++++++------------ src/Appwrite/Platform/Tasks/EdgeSync.php | 2 +- src/Appwrite/Platform/Tasks/Maintenance.php | 20 +++++++++-------- src/Appwrite/Platform/Tasks/SSL.php | 10 ++++++--- 12 files changed, 75 insertions(+), 73 deletions(-) diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php index 5022681d87..1439a0c61f 100644 --- a/app/controllers/api/databases.php +++ b/app/controllers/api/databases.php @@ -442,8 +442,8 @@ function createAttribute(string $databaseId, string $collectionId, Document $att ->inject('response') ->inject('dbForProject') ->inject('events') - ->inject('deletes') - ->action(function (string $databaseId, Response $response, Database $dbForProject, Event $events, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $databaseId, Response $response, Database $dbForProject, Event $events, Delete $queueForDeletes) { $database = $dbForProject->getDocument('databases', $databaseId); @@ -457,7 +457,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att $dbForProject->deleteCachedCollection('databases' . $database->getInternalId()); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($database) ; @@ -814,8 +814,8 @@ function createAttribute(string $databaseId, string $collectionId, Document $att ->inject('response') ->inject('dbForProject') ->inject('events') - ->inject('deletes') - ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, Event $events, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $databaseId, string $collectionId, Response $response, Database $dbForProject, Event $events, Delete $queueForDeletes) { $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -835,7 +835,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att $dbForProject->deleteCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId()); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($collection) ; @@ -2380,9 +2380,9 @@ function createAttribute(string $databaseId, string $collectionId, Document $att ->inject('response') ->inject('dbForProject') ->inject('events') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('mode') - ->action(function (string $databaseId, string $collectionId, string $documentId, Response $response, Database $dbForProject, Event $events, Delete $deletes, string $mode) { + ->action(function (string $databaseId, string $collectionId, string $documentId, Response $response, Database $dbForProject, Event $events, Delete $queueForDeletes, string $mode) { $database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId)); @@ -2430,7 +2430,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att $document->setAttribute('$collectionId', $collectionId); $document->setAttribute('$databaseId', $databaseId); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_AUDIT) ->setDocument($document) ; diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 4c84795712..3d0ff0e179 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -572,11 +572,11 @@ ->param('functionId', '', new UID(), 'Function ID.') ->inject('response') ->inject('dbForProject') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('events') ->inject('project') ->inject('dbForConsole') - ->action(function (string $functionId, Response $response, Database $dbForProject, Delete $deletes, Event $events, Document $project, Database $dbForConsole) { + ->action(function (string $functionId, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $events, Document $project, Database $dbForConsole) { $function = $dbForProject->getDocument('functions', $functionId); @@ -597,7 +597,7 @@ Authorization::skip(fn () => $dbForConsole->updateDocument('schedules', $schedule->getId(), $schedule)); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($function); @@ -939,10 +939,10 @@ ->param('deploymentId', '', new UID(), 'Deployment ID.') ->inject('response') ->inject('dbForProject') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('events') ->inject('deviceFunctions') - ->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Delete $deletes, Event $events, Device $deviceFunctions) { + ->action(function (string $functionId, string $deploymentId, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $events, Device $deviceFunctions) { $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { @@ -974,7 +974,7 @@ ->setParam('functionId', $function->getId()) ->setParam('deploymentId', $deployment->getId()); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($deployment); diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 5fef7eab78..4c4e84467c 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -483,8 +483,8 @@ ->inject('response') ->inject('user') ->inject('dbForConsole') - ->inject('deletes') - ->action(function (string $projectId, string $password, Response $response, Document $user, Database $dbForConsole, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $projectId, string $password, Response $response, Document $user, Database $dbForConsole, Delete $queueForDeletes) { if (!Auth::passwordVerify($password, $user->getAttribute('password'), $user->getAttribute('hash'), $user->getAttribute('hashOptions'))) { // Double check user password throw new Exception(Exception::USER_INVALID_CREDENTIALS); @@ -496,7 +496,7 @@ throw new Exception(Exception::PROJECT_NOT_FOUND); } - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($project) ; @@ -1314,7 +1314,8 @@ ->param('domainId', '', new UID(), 'Domain unique ID.') ->inject('response') ->inject('dbForConsole') - ->action(function (string $projectId, string $domainId, Response $response, Database $dbForConsole) { + ->inject('queueForCertificates') + ->action(function (string $projectId, string $domainId, Response $response, Database $dbForConsole, Certificate $queueForCertificates) { $project = $dbForConsole->getDocument('projects', $projectId); @@ -1352,8 +1353,7 @@ $dbForConsole->deleteCachedDocument('projects', $project->getId()); // Issue a TLS certificate when domain is verified - $event = new Certificate(); - $event + $queueForCertificates ->setDomain($domain) ->trigger(); @@ -1373,8 +1373,8 @@ ->param('domainId', '', new UID(), 'Domain unique ID.') ->inject('response') ->inject('dbForConsole') - ->inject('deletes') - ->action(function (string $projectId, string $domainId, Response $response, Database $dbForConsole, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $projectId, string $domainId, Response $response, Database $dbForConsole, Delete $queueForDeletes) { $project = $dbForConsole->getDocument('projects', $projectId); @@ -1395,7 +1395,7 @@ $dbForConsole->deleteCachedDocument('projects', $project->getId()); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_CERTIFICATES) ->setDocument($domain); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 71979cca55..a7f1ec985e 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -300,9 +300,9 @@ ->param('bucketId', '', new UID(), 'Bucket unique ID.') ->inject('response') ->inject('dbForProject') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('events') - ->action(function (string $bucketId, Response $response, Database $dbForProject, Delete $deletes, Event $events) { + ->action(function (string $bucketId, Response $response, Database $dbForProject, Delete $queueForDeletes, Event $events) { $bucket = $dbForProject->getDocument('buckets', $bucketId); if ($bucket->isEmpty()) { @@ -313,7 +313,7 @@ throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove bucket from DB'); } - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($bucket); @@ -359,8 +359,8 @@ ->inject('mode') ->inject('deviceFiles') ->inject('deviceLocal') - ->inject('deletes') - ->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $events, string $mode, Device $deviceFiles, Device $deviceLocal, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $events, string $mode, Device $deviceFiles, Device $deviceLocal, Delete $queueForDeletes) { $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); @@ -642,7 +642,7 @@ ->setContext('bucket', $bucket) ; - $deletes + $queueForDeletes ->setType(DELETE_TYPE_CACHE_BY_RESOURCE) ->setResource('file/' . $file->getId()) ; @@ -1364,8 +1364,8 @@ ->inject('events') ->inject('mode') ->inject('deviceFiles') - ->inject('deletes') - ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $events, string $mode, Device $deviceFiles, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $events, string $mode, Device $deviceFiles, Delete $queueForDeletes) { $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && $mode !== APP_MODE_ADMIN)) { @@ -1402,7 +1402,7 @@ } if ($deviceDeleted) { - $deletes + $queueForDeletes ->setType(DELETE_TYPE_CACHE_BY_RESOURCE) ->setResource('file/' . $fileId) ; diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 572b6f02a8..5370744343 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -246,8 +246,8 @@ ->inject('response') ->inject('dbForProject') ->inject('events') - ->inject('deletes') - ->action(function (string $teamId, Response $response, Database $dbForProject, Event $events, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $teamId, Response $response, Database $dbForProject, Event $events, Delete $queueForDeletes) { $team = $dbForProject->getDocument('teams', $teamId); @@ -271,7 +271,7 @@ throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove team from DB'); } - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($team); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index dce493b024..b71c33862d 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -1070,8 +1070,8 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e ->inject('response') ->inject('dbForProject') ->inject('events') - ->inject('deletes') - ->action(function (string $userId, Response $response, Database $dbForProject, Event $events, Delete $deletes) { + ->inject('queueForDeletes') + ->action(function (string $userId, Response $response, Database $dbForProject, Event $events, Delete $queueForDeletes) { $user = $dbForProject->getDocument('users', $userId); @@ -1084,7 +1084,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e $dbForProject->deleteDocument('users', $userId); - $deletes + $queueForDeletes ->setType(DELETE_TYPE_DOCUMENT) ->setDocument($clone); diff --git a/app/controllers/general.php b/app/controllers/general.php index 95bece43fc..d432916d7a 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -52,7 +52,8 @@ ->inject('locale') ->inject('clients') ->inject('servers') - ->action(function (App $utopia, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $clients, array $servers) { + ->inject('queueForCertificates') + ->action(function (App $utopia, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $clients, array $servers, Certificate $queueForCertificates) { /* * Request format */ @@ -123,7 +124,7 @@ Console::info('Issuing a TLS certificate for the main domain (' . $domain->get() . ') in a few seconds...'); - (new Certificate()) + $queueForCertificates ->setDomain($domainDocument) ->trigger(); } diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index c61a4f6f91..4682942b95 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -102,11 +102,11 @@ ->inject('audits') ->inject('mails') ->inject('usage') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('database') ->inject('dbForProject') ->inject('mode') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $events, Audit $audits, Mail $mails, Stats $usage, Delete $deletes, EventDatabase $database, Database $dbForProject, string $mode) use ($databaseListener) { + ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $events, Audit $audits, Mail $mails, Stats $usage, Delete $queueForDeletes, EventDatabase $database, Database $dbForProject, string $mode) use ($databaseListener) { $route = $utopia->match($request); @@ -200,7 +200,7 @@ ->setParam('project.{scope}.network.inbound', 0) ->setParam('project.{scope}.network.outbound', 0); - $deletes->setProject($project); + $queueForDeletes->setProject($project); $database->setProject($project); $dbForProject->on(Database::EVENT_DOCUMENT_CREATE, fn ($event, Document $document) => $databaseListener($event, $document, $usage)); @@ -329,7 +329,7 @@ ->inject('events') ->inject('audits') ->inject('usage') - ->inject('deletes') + ->inject('queueForDeletes') ->inject('database') ->inject('mode') ->inject('dbForProject') diff --git a/docker-compose.yml b/docker-compose.yml index fe430fbb07..22043ad1cb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -621,11 +621,14 @@ services: - ./app:/usr/src/code/app - ./src:/usr/src/code/src depends_on: + - mariadb - redis environment: - _APP_ENV - - _APP_WORKER_PER_CORE - _APP_CONNECTIONS_MAX + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE - _APP_POOL_CLIENTS - _APP_DOMAIN - _APP_DOMAIN_TARGET @@ -639,10 +642,6 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS - - _APP_CONNECTIONS_DB_PROJECT - - _APP_CONNECTIONS_DB_CONSOLE - - _APP_CONNECTIONS_CACHE - - _APP_CONNECTIONS_QUEUE - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_CACHE @@ -661,11 +660,16 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - ./vendor/utopia-php/cli:/usr/src/code/vendor/utopia-php/cli depends_on: - mariadb - redis environment: + - _APP_CONNECTIONS_MAX + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE + - _APP_POOL_CLIENTS - _APP_ENV - _APP_REDIS_HOST - _APP_REDIS_PORT @@ -676,15 +680,8 @@ services: - _APP_DB_SCHEMA - _APP_DB_USER - _APP_DB_PASS - - _APP_CONNECTIONS_MAX - - _APP_POOL_CLIENTS - _APP_SYNC_EDGE_INTERVAL - - _APP_CONNECTIONS_DB_PROJECT - - _APP_CONNECTIONS_DB_CONSOLE - - _APP_CONNECTIONS_CACHE - - _APP_CONNECTIONS_QUEUE - _APP_REGION - - _APP_WORKER_PER_CORE appwrite-usage: entrypoint: usage @@ -739,7 +736,6 @@ services: - redis environment: - _APP_ENV - - _APP_WORKER_PER_CORE - _APP_CONNECTIONS_MAX - _APP_POOL_CLIENTS - _APP_REDIS_HOST @@ -754,7 +750,6 @@ services: - _APP_CONNECTIONS_DB_PROJECT - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE - - _APP_CONNECTIONS_QUEUE - _APP_REGION openruntimes-executor: diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index f4450785dc..ce30729960 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -83,7 +83,7 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi ]); } } - if (!$found) { + if (!$found) { Console::info("[{$time}] No keys where found for region {$code}."); } } diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 2f236d32ca..94d42a6a53 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -29,6 +29,9 @@ public function __construct() ->callback(fn (Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes) => $this->action($dbForConsole, $queueForCertificates, $queueForDeletes)); } + /** + * @throws \Exception + */ public function action(Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes): void { Console::title('Maintenance V1'); @@ -36,7 +39,7 @@ public function action(Database $dbForConsole, Certificate $queueForCertificates function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_EXECUTIONS) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -44,7 +47,7 @@ function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes) function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_ABUSE) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -52,7 +55,7 @@ function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes) function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_AUDIT) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -60,7 +63,7 @@ function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes) function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_USAGE) ->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly)) ->trigger(); @@ -68,7 +71,7 @@ function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueFor function notifyDeleteConnections(Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_REALTIME) ->setDatetime(DateTime::addSeconds(new \DateTime(), -60)) ->trigger(); @@ -76,7 +79,7 @@ function notifyDeleteConnections(Delete $queueForDeletes) function notifyDeleteExpiredSessions(Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_SESSIONS) ->trigger(); } @@ -110,7 +113,7 @@ function renewCertificates(Database $dbForConsole, Certificate $queueForCertific function notifyDeleteCache($interval, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_CACHE_BY_TIMESTAMP) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -119,7 +122,7 @@ function notifyDeleteCache($interval, Delete $queueForDeletes) function notifyDeleteSchedules($interval, Delete $queueForDeletes) { - ($queueForDeletes) + $queueForDeletes ->setType(DELETE_TYPE_SCHEDULES) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); @@ -131,7 +134,6 @@ function notifyDeleteSchedules($interval, Delete $queueForDeletes) $auditLogRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', '1209600'); $abuseLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', '86400'); $usageStatsRetentionHourly = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_HOURLY', '8640000'); //100 days - $cacheRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_CACHE', '2592000'); // 30 days $schedulesDeletionRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_SCHEDULES', '86400'); // 1 Day diff --git a/src/Appwrite/Platform/Tasks/SSL.php b/src/Appwrite/Platform/Tasks/SSL.php index 43026b0753..698c950dcc 100644 --- a/src/Appwrite/Platform/Tasks/SSL.php +++ b/src/Appwrite/Platform/Tasks/SSL.php @@ -21,14 +21,18 @@ public function __construct() $this ->desc('Validate server certificates') ->param('domain', App::getEnv('_APP_DOMAIN', ''), new Hostname(), 'Domain to generate certificate for. If empty, main domain will be used.', true) - ->callback(fn ($domain) => $this->action($domain)); + ->inject('queueForCertificates') + ->callback(fn ($domain, Certificate $queueForCertificates) => $this->action($domain, $queueForCertificates)); } - public function action(string $domain): void + /** + * @throws \Exception + */ + public function action(string $domain, Certificate $queueForCertificates): void { Console::success('Scheduling a job to issue a TLS certificate for domain: ' . $domain); - (new Certificate()) + $queueForCertificates ->setDomain(new Document([ 'domain' => $domain ])) From 20fe16b40300aad31abbdfeb90911b5608f79adc Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 8 Jan 2023 09:25:25 +0200 Subject: [PATCH 61/87] deletes-queue --- composer.lock | 6879 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6879 insertions(+) create mode 100644 composer.lock diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..a832c76640 --- /dev/null +++ b/composer.lock @@ -0,0 +1,6879 @@ +{ + "_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": "4d3e2a569d5f848f135a5fc854924af4", + "packages": [ + { + "name": "adhocore/jwt", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-jwt.git", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899", + "reference": "6c434af7170090bb7a8880d2bc220a2254ba7899", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ahc\\Jwt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Ultra lightweight JSON web token (JWT) library for PHP5.5+.", + "keywords": [ + "auth", + "json-web-token", + "jwt", + "jwt-auth", + "jwt-php", + "token" + ], + "support": { + "issues": "https://github.com/adhocore/php-jwt/issues", + "source": "https://github.com/adhocore/php-jwt/tree/1.1.2" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + } + ], + "time": "2021-02-20T09:56:44+00:00" + }, + { + "name": "appwrite/php-clamav", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/appwrite/php-clamav.git", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/php-clamav/zipball/61d00f24f9e7766fbba233e7b8d09c5475388073", + "reference": "61d00f24f9e7766fbba233e7b8d09c5475388073", + "shasum": "" + }, + "require": { + "ext-sockets": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\ClamAV\\": "src/ClamAV" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "ClamAV network and pipe client for PHP", + "keywords": [ + "anti virus", + "appwrite", + "clamav", + "php" + ], + "support": { + "issues": "https://github.com/appwrite/php-clamav/issues", + "source": "https://github.com/appwrite/php-clamav/tree/1.1.0" + }, + "time": "2020-10-02T05:23:46+00:00" + }, + { + "name": "appwrite/php-runtimes", + "version": "0.11.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/runtimes.git", + "reference": "9d74a477ba3333cbcfac565c46fcf19606b7b603" + }, + "require": { + "php": ">=8.0", + "utopia-php/system": "0.6.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\Runtimes\\": "src/Runtimes" + } + }, + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.", + "keywords": [ + "appwrite", + "php", + "runtimes" + ], + "time": "2022-11-07T16:45:52+00:00" + }, + { + "name": "chillerlan/php-qrcode", + "version": "4.3.3", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-qrcode.git", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/6356b246948ac1025882b3f55e7c68ebd4515ae3", + "reference": "6356b246948ac1025882b3f55e7c68ebd4515ae3", + "shasum": "" + }, + "require": { + "chillerlan/php-settings-container": "^2.1", + "ext-mbstring": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", + "setasign/fpdf": "Required to use the QR FPDF output." + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\QRCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kazuhiko Arase", + "homepage": "https://github.com/kazuhikoarase" + }, + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + }, + { + "name": "Contributors", + "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors" + } + ], + "description": "A QR code generator. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-qrcode", + "keywords": [ + "phpqrcode", + "qr", + "qr code", + "qrcode", + "qrcode-generator" + ], + "support": { + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode/tree/4.3.3" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2021-11-25T22:38:09+00:00" + }, + { + "name": "chillerlan/php-settings-container", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/chillerlan/php-settings-container.git", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phan/phan": "^5.3", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "chillerlan\\Settings\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Smiley", + "email": "smiley@chillerlan.net", + "homepage": "https://github.com/codemasher" + } + ], + "description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+", + "homepage": "https://github.com/chillerlan/php-settings-container", + "keywords": [ + "PHP7", + "Settings", + "configuration", + "container", + "helper" + ], + "support": { + "issues": "https://github.com/chillerlan/php-settings-container/issues", + "source": "https://github.com/chillerlan/php-settings-container" + }, + "funding": [ + { + "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4", + "type": "custom" + }, + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], + "time": "2022-07-05T22:32:14+00:00" + }, + { + "name": "colinmollenhour/credis", + "version": "v1.14.0", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc", + "reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "suggest": { + "ext-redis": "Improved performance for communicating with redis" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php", + "Module.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "support": { + "issues": "https://github.com/colinmollenhour/credis/issues", + "source": "https://github.com/colinmollenhour/credis/tree/v1.14.0" + }, + "time": "2022-11-09T01:18:39+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9 || ^2.4", + "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.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "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 + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "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.5.0" + }, + "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": "2022-08-28T15:39:27+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "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/1.5.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2022-08-28T14:55:35+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.4.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "67c26b443f348a51926030c83481b85718457d3d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/67c26b443f348a51926030c83481b85718457d3d", + "reference": "67c26b443f348a51926030c83481b85718457d3d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.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.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "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.4.3" + }, + "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": "2022-10-26T14:07:24+00:00" + }, + { + "name": "influxdb/influxdb-php", + "version": "1.15.2", + "source": { + "type": "git", + "url": "https://github.com/influxdata/influxdb-php.git", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/d6e59f4f04ab9107574fda69c2cbe36671253d03", + "reference": "d6e59f4f04ab9107574fda69c2cbe36671253d03", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0|^7.0", + "php": "^5.5 || ^7.0 || ^8.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.2.1", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "ext-curl": "Curl extension, needed for Curl driver", + "stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP." + }, + "type": "library", + "autoload": { + "psr-4": { + "InfluxDB\\": "src/InfluxDB" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Hoogendijk", + "email": "stephen@tca0.nl" + }, + { + "name": "Daniel Martinez", + "email": "danimartcas@hotmail.com" + }, + { + "name": "Gianluca Arbezzano", + "email": "gianarb92@gmail.com" + } + ], + "description": "InfluxDB client library for PHP", + "keywords": [ + "client", + "influxdata", + "influxdb", + "influxdb class", + "influxdb client", + "influxdb library", + "time series" + ], + "support": { + "issues": "https://github.com/influxdata/influxdb-php/issues", + "source": "https://github.com/influxdata/influxdb-php/tree/1.15.2" + }, + "abandoned": true, + "time": "2020-12-26T17:45:17+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11.0", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", + "nunomaduro/termwind": "^1.14.0", + "pestphp/pest": "^1.22.1" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2022-11-29T16:25:20+00:00" + }, + { + "name": "matomo/device-detector", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/matomo-org/device-detector.git", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9", + "reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9", + "shasum": "" + }, + "require": { + "mustangostang/spyc": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "piwik/device-detector": "self.version" + }, + "require-dev": { + "matthiasmullie/scrapbook": "^1.4.7", + "mayflower/mo4-coding-standard": "^v8.0.0", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8.5.8", + "psr/cache": "^1.0.1", + "psr/simple-cache": "^1.0.1", + "symfony/yaml": "^5.1.7" + }, + "suggest": { + "doctrine/cache": "Can directly be used for caching purpose", + "ext-yaml": "Necessary for using the Pecl YAML parser" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeviceDetector\\": "" + }, + "exclude-from-classmap": [ + "Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The Matomo Team", + "email": "hello@matomo.org", + "homepage": "https://matomo.org/team/" + } + ], + "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.", + "homepage": "https://matomo.org", + "keywords": [ + "devicedetection", + "parser", + "useragent" + ], + "support": { + "forum": "https://forum.matomo.org/", + "issues": "https://github.com/matomo-org/device-detector/issues", + "source": "https://github.com/matomo-org/matomo", + "wiki": "https://dev.matomo.org/" + }, + "time": "2022-04-11T09:58:17+00:00" + }, + { + "name": "mustangostang/spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "git@github.com:mustangostang/spyc.git", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0", + "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "files": [ + "Spyc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP", + "homepage": "https://github.com/mustangostang/spyc/", + "keywords": [ + "spyc", + "yaml", + "yml" + ], + "time": "2019-09-10T13:16:29+00:00" + }, + { + "name": "phpmailer/phpmailer", + "version": "v6.6.0", + "source": { + "type": "git", + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "reference": "e43bac82edc26ca04b36143a48bde1c051cfd5b1", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.2", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.6.2", + "yoast/phpunit-polyfills": "^1.0.0" + }, + "suggest": { + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPMailer\\PHPMailer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-only" + ], + "authors": [ + { + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" + } + ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", + "support": { + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.0" + }, + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2022-02-28T15:31:21+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.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": "http://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/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.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": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.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": "http://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/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "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/1.1.4" + }, + "time": "2021-05-03T11:20: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": "resque/php-resque", + "version": "v1.3.6", + "source": { + "type": "git", + "url": "https://github.com/resque/php-resque.git", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/resque/php-resque/zipball/fe41c04763699b1318d97ed14cc78583e9380161", + "reference": "fe41c04763699b1318d97ed14cc78583e9380161", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "~1.7", + "php": ">=5.6.0", + "psr/log": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-pcntl": "REQUIRED for forking processes on platforms that support it (so anything but Windows).", + "ext-proctitle": "Allows php-resque to rename the title of UNIX processes to show the status of a worker.", + "ext-redis": "Native PHP extension for Redis connectivity. Credis will automatically utilize when available." + }, + "bin": [ + "bin/resque", + "bin/resque-scheduler" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Resque": "lib", + "ResqueScheduler": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dan Hunsaker", + "email": "danhunsaker+resque@gmail.com", + "role": "Maintainer" + }, + { + "name": "Rajib Ahmed", + "homepage": "https://github.com/rajibahmed", + "role": "Maintainer" + }, + { + "name": "Steve Klabnik", + "email": "steve@steveklabnik.com", + "role": "Maintainer" + }, + { + "name": "Chris Boulton", + "email": "chris@bigcommerce.com", + "role": "Creator" + } + ], + "description": "Redis backed library for creating background jobs and processing them later. Based on resque for Ruby.", + "homepage": "http://www.github.com/resque/php-resque/", + "keywords": [ + "background", + "job", + "redis", + "resque" + ], + "support": { + "issues": "https://github.com/resque/php-resque/issues", + "source": "https://github.com/resque/php-resque/tree/v1.3.6" + }, + "time": "2020-04-16T16:39:50+00:00" + }, + { + "name": "slickdeals/statsd", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/Slickdeals/statsd-php.git", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f", + "reference": "225588a0a079e145359049f6e5e23eedb1b4c17f", + "shasum": "" + }, + "require": { + "php": ">= 7.3 || ^8" + }, + "replace": { + "domnikl/statsd": "self.version" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Domnikl\\Statsd\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dominik Liebler", + "email": "liebler.dominik@gmail.com" + } + ], + "description": "a PHP client for statsd", + "homepage": "https://github.com/Slickdeals/statsd-php", + "keywords": [ + "Metrics", + "monitoring", + "statistics", + "statsd", + "udp" + ], + "support": { + "issues": "https://github.com/Slickdeals/statsd-php/issues", + "source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0" + }, + "time": "2021-06-04T20:33:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-25T10:21:52+00:00" + }, + { + "name": "utopia-php/abuse", + "version": "0.16.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/abuse.git", + "reference": "6370d9150425460416583feba0990504ac789e98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/6370d9150425460416583feba0990504ac789e98", + "reference": "6370d9150425460416583feba0990504ac789e98", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.4", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Abuse\\": "src/Abuse" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple abuse library to manage application usage limits", + "keywords": [ + "Abuse", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/abuse/issues", + "source": "https://github.com/utopia-php/abuse/tree/0.16.0" + }, + "time": "2022-10-31T14:46:41+00:00" + }, + { + "name": "utopia-php/analytics", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/analytics.git", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/analytics/zipball/adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "reference": "adfc2d057a7f6ab618a77c8a20ed3e35485ff416", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Analytics\\": "src/Analytics" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library to track events & users.", + "keywords": [ + "analytics", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/analytics/issues", + "source": "https://github.com/utopia-php/analytics/tree/0.2.0" + }, + "time": "2021-03-23T21:33:07+00:00" + }, + { + "name": "utopia-php/audit", + "version": "0.17.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/audit.git", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/455471bd4de8d74026809e843f8c9740eb32922c", + "reference": "455471bd4de8d74026809e843f8c9740eb32922c", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "php": ">=8.0", + "utopia-php/database": "0.28.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Audit\\": "src/Audit" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple audit library to manage application users logs", + "keywords": [ + "Audit", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/audit/issues", + "source": "https://github.com/utopia-php/audit/tree/0.17.0" + }, + "time": "2022-10-31T14:44:52+00:00" + }, + { + "name": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cache.git", + "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", + "reference": "8aaec883a9f0137f99d6e1a3a06c4d4ca1ed8c7e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-memcached": "*", + "ext-redis": "*", + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.9.x-dev", + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Cache\\": "src/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple cache library to manage application cache storing, loading and purging", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cache/issues", + "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" + }, + "time": "2022-12-27T10:47:29+00:00" + }, + { + "name": "utopia-php/cli", + "version": "0.14.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/cli.git", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/cli/zipball/c30ef985a4e739758a0d95eb0706b357b6d8c086", + "reference": "c30ef985a4e739758a0d95eb0706b357b6d8c086", + "shasum": "" + }, + "require": { + "php": ">=7.4", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\CLI\\": "src/CLI" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple CLI library to manage command line applications", + "keywords": [ + "cli", + "command line", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/cli/issues", + "source": "https://github.com/utopia-php/cli/tree/0.14.0" + }, + "time": "2022-10-09T10:19:07+00:00" + }, + { + "name": "utopia-php/config", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/config.git", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Config\\": "src/Config" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Config library to managing application config variables", + "keywords": [ + "config", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/config/issues", + "source": "https://github.com/utopia-php/config/tree/0.2.2" + }, + "time": "2020-10-24T09:49:09+00:00" + }, + { + "name": "utopia-php/database", + "version": "0.28.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "reference": "ef6506af1c09c22f5dc1e7859159d323f7fafa94", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cache": "0.8.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "fakerphp/faker": "^1.14", + "mongodb/mongodb": "1.8.0", + "phpunit/phpunit": "^9.4", + "swoole/ide-helper": "4.8.0", + "utopia-php/cli": "^0.11.0", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Database\\": "src/Database" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library to manage application persistency using multiple database adapters", + "keywords": [ + "database", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/database/issues", + "source": "https://github.com/utopia-php/database/tree/0.28.0" + }, + "time": "2022-10-31T09:58:46+00:00" + }, + { + "name": "utopia-php/domains", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/domains.git", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "reference": "1665e1d9932afa3be63b5c1e0dcfe01fe77d8e73", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Domains\\": "src/Domains" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Utopia Domains library is simple and lite library for parsing web domains. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "domains", + "framework", + "icann", + "php", + "public suffix", + "tld", + "tld extract", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/domains/issues", + "source": "https://github.com/utopia-php/domains/tree/master" + }, + "time": "2020-02-23T07:40:02+00:00" + }, + { + "name": "utopia-php/dsn", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/dsn.git", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\DSN\\": "src/DSN" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library for parsing and managing Data Source Names ( DSNs )", + "keywords": [ + "dsn", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/dsn/issues", + "source": "https://github.com/utopia-php/dsn/tree/0.1.0" + }, + "time": "2022-10-26T10:06:20+00:00" + }, + { + "name": "utopia-php/framework", + "version": "0.25.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/framework.git", + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0", + "reference": "2391b397135586b2100d39e338827bef8d2f4ad0", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "require-dev": { + "laravel/pint": "^1.2", + "phpunit/phpunit": "^9.5.25", + "vimeo/psalm": "4.27.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple, light and advanced PHP framework", + "keywords": [ + "framework", + "php", + "upf" + ], + "support": { + "issues": "https://github.com/utopia-php/framework/issues", + "source": "https://github.com/utopia-php/framework/tree/0.25.1" + }, + "time": "2022-11-23T18:22:23+00:00" + }, + { + "name": "utopia-php/image", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/image.git", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336", + "reference": "ca5f436f9aa22dedaa6648f24f3687733808e336", + "shasum": "" + }, + "require": { + "ext-imagick": "*", + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.13.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Image\\": "src/Image" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Image manipulation library", + "keywords": [ + "framework", + "image", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/image/issues", + "source": "https://github.com/utopia-php/image/tree/0.5.4" + }, + "time": "2022-05-11T12:30:41+00:00" + }, + { + "name": "utopia-php/locale", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/locale.git", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/locale/zipball/c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "reference": "c2d9358d0fe2f6b6ed5448369f9d1e430c615447", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Locale\\": "src/Locale" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple locale library to manage application translations", + "keywords": [ + "framework", + "locale", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/locale/issues", + "source": "https://github.com/utopia-php/locale/tree/0.4.0" + }, + "time": "2021-07-24T11:35:55+00:00" + }, + { + "name": "utopia-php/logger", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/logger.git", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", + "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Logger\\": "src/Logger" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Matej Bačo", + "email": "matej@appwrite.io" + }, + { + "name": "Christy Jacob", + "email": "christy@appwrite.io" + } + ], + "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", + "keywords": [ + "appsignal", + "errors", + "framework", + "logger", + "logging", + "logs", + "php", + "raygun", + "sentry", + "upf", + "utopia", + "warnings" + ], + "support": { + "issues": "https://github.com/utopia-php/logger/issues", + "source": "https://github.com/utopia-php/logger/tree/0.3.0" + }, + "time": "2022-03-18T10:56:57+00:00" + }, + { + "name": "utopia-php/messaging", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/messaging.git", + "reference": "501272fad666f06bec8f130076862e7981a73f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c", + "reference": "501272fad666f06bec8f130076862e7981a73f8c", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=8.0.0" + }, + "require-dev": { + "phpmailer/phpmailer": "6.6.*", + "phpunit/phpunit": "9.5.*", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Messaging\\": "src/Utopia/Messaging" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jake Barnby", + "email": "jake@appwrite.io" + } + ], + "description": "A simple, light and advanced PHP messaging library", + "keywords": [ + "library", + "messaging", + "php", + "upf", + "utopia", + "utopia-php" + ], + "support": { + "issues": "https://github.com/utopia-php/messaging/issues", + "source": "https://github.com/utopia-php/messaging/tree/0.1.0" + }, + "time": "2022-09-29T11:22:48+00:00" + }, + { + "name": "utopia-php/orchestration", + "version": "0.9.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/orchestration.git", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/orchestration/zipball/1d4f66684b8c4927f31b695817eae6d84aafd172", + "reference": "1d4f66684b8c4927f31b695817eae6d84aafd172", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Orchestration\\": "src/Orchestration" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Lite & fast micro PHP abstraction library for container orchestration", + "keywords": [ + "docker", + "framework", + "kubernetes", + "orchestration", + "php", + "swarm", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/orchestration/issues", + "source": "https://github.com/utopia-php/orchestration/tree/0.9.0" + }, + "time": "2022-11-09T17:38:00+00:00" + }, + { + "name": "utopia-php/platform", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/platform.git", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/fe9f64420957dc8fb6201d22b499572f021411e4", + "reference": "fe9f64420957dc8fb6201d22b499572f021411e4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-redis": "*", + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.25.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Platform\\": "src/Platform" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Light and Fast Platform Library", + "keywords": [ + "cache", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/platform/issues", + "source": "https://github.com/utopia-php/platform/tree/0.3.1" + }, + "time": "2022-11-10T07:04:24+00:00" + }, + { + "name": "utopia-php/pools", + "version": "0.4.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/pools.git", + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/d2870ab74b31b7f4027799f082e85122154f8bed", + "reference": "d2870ab74b31b7f4027799f082e85122154f8bed", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpstan/phpstan": "1.8.*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Pools\\": "src/Pools" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Team Appwrite", + "email": "team@appwrite.io" + } + ], + "description": "A simple library to manage connection pools", + "keywords": [ + "framework", + "php", + "pools", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/pools/issues", + "source": "https://github.com/utopia-php/pools/tree/0.4.2" + }, + "time": "2022-11-22T07:55:45+00:00" + }, + { + "name": "utopia-php/preloader", + "version": "0.2.4", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/preloader.git", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/preloader/zipball/65ef48392e72172f584b0baa2e224f9a1cebcce0", + "reference": "65ef48392e72172f584b0baa2e224f9a1cebcce0", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Preloader\\": "src/Preloader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "team@appwrite.io" + } + ], + "description": "Utopia Preloader library is simple and lite library for managing PHP preloading configuration", + "keywords": [ + "framework", + "php", + "preload", + "preloader", + "preloading", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/preloader/issues", + "source": "https://github.com/utopia-php/preloader/tree/0.2.4" + }, + "time": "2020-10-24T07:04:59+00:00" + }, + { + "name": "utopia-php/queue", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/queue.git", + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/queue/zipball/4b39e1f232b2e619b0d7fb4004f2356df334ddc1", + "reference": "4b39e1f232b2e619b0d7fb4004f2356df334ddc1", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "utopia-php/cli": "0.14.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "^0.2.3", + "phpstan/phpstan": "^1.8", + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.8.8", + "workerman/workerman": "^4.0" + }, + "suggest": { + "ext-swoole": "Needed to support Swoole.", + "workerman/workerman": "Needed to support Workerman." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Queue\\": "src/Queue" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A powerful task queue.", + "keywords": [ + "Tasks", + "framework", + "php", + "queue", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/queue/issues", + "source": "https://github.com/utopia-php/queue/tree/0.5.1" + }, + "time": "2022-11-16T19:47:26+00:00" + }, + { + "name": "utopia-php/registry", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/registry.git", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d", + "reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Registry\\": "src/Registry" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple dependency management library for PHP", + "keywords": [ + "dependency management", + "di", + "framework", + "php", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/registry/issues", + "source": "https://github.com/utopia-php/registry/tree/0.5.0" + }, + "time": "2021-03-10T10:45:22+00:00" + }, + { + "name": "utopia-php/storage", + "version": "0.13.2", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/storage.git", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/storage/zipball/ad1c00f24ca56e73888acc2af3deee4919b1194b", + "reference": "ad1c00f24ca56e73888acc2af3deee4919b1194b", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "ext-zlib": "*", + "ext-zstd": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Storage\\": "src/Storage" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "A simple Storage library to manage application storage", + "keywords": [ + "framework", + "php", + "storage", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/storage/issues", + "source": "https://github.com/utopia-php/storage/tree/0.13.2" + }, + "time": "2022-12-20T11:11:35+00:00" + }, + { + "name": "utopia-php/swoole", + "version": "0.5.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/swoole.git", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "reference": "c2a3a4f944a2f22945af3cbcb95b13f0769628b1", + "shasum": "" + }, + "require": { + "ext-swoole": "*", + "php": ">=8.0", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "laravel/pint": "1.2.*", + "phpunit/phpunit": "^9.3", + "swoole/ide-helper": "4.8.3", + "vimeo/psalm": "4.15.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Swoole\\": "src/Swoole" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "An extension for Utopia Framework to work with PHP Swoole as a PHP FPM alternative", + "keywords": [ + "framework", + "http", + "php", + "server", + "swoole", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/swoole/issues", + "source": "https://github.com/utopia-php/swoole/tree/0.5.0" + }, + "time": "2022-10-19T22:19:07+00:00" + }, + { + "name": "utopia-php/system", + "version": "0.6.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/system.git", + "reference": "289c4327713deadc9c748b5317d248133a02f245" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/system/zipball/289c4327713deadc9c748b5317d248133a02f245", + "reference": "289c4327713deadc9c748b5317d248133a02f245", + "shasum": "" + }, + "require": { + "laravel/pint": "1.2.*", + "php": ">=7.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.6", + "vimeo/psalm": "4.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\System\\": "src/System" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple library for obtaining information about the host's system.", + "keywords": [ + "framework", + "php", + "system", + "upf", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/system/issues", + "source": "https://github.com/utopia-php/system/tree/0.6.0" + }, + "time": "2022-11-07T13:51:59+00:00" + }, + { + "name": "utopia-php/websocket", + "version": "0.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/websocket.git", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5", + "reference": "51fcb86171400d8aa40d76c54593481fd273dab5", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.5", + "swoole/ide-helper": "4.6.6", + "textalk/websocket": "1.5.2", + "vimeo/psalm": "^4.8.1", + "workerman/workerman": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\WebSocket\\": "src/WebSocket" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + }, + { + "name": "Torsten Dittmann", + "email": "torsten@appwrite.io" + } + ], + "description": "A simple abstraction for WebSocket servers.", + "keywords": [ + "framework", + "php", + "upf", + "utopia", + "websocket" + ], + "support": { + "issues": "https://github.com/utopia-php/websocket/issues", + "source": "https://github.com/utopia-php/websocket/tree/0.1.0" + }, + "time": "2021-12-20T10:50:09+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "appwrite/sdk-generator", + "version": "0.28.1", + "source": { + "type": "git", + "url": "https://github.com/appwrite/sdk-generator.git", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ed8d3daa66589733b49b11c053d524cdf576ffee", + "reference": "ed8d3daa66589733b49b11c053d524cdf576ffee", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "matthiasmullie/minify": "^1.3.68", + "php": ">=7.0.0", + "twig/twig": "^3.4.1" + }, + "require-dev": { + "brianium/paratest": "^6.4", + "phpunit/phpunit": "^9.5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Appwrite\\SDK\\": "src/SDK", + "Appwrite\\Spec\\": "src/Spec" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eldad Fux", + "email": "eldad@appwrite.io" + } + ], + "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", + "support": { + "issues": "https://github.com/appwrite/sdk-generator/issues", + "source": "https://github.com/appwrite/sdk-generator/tree/0.28.1" + }, + "time": "2022-09-22T09:15:54+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.14.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "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": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.14.2" + }, + "time": "2022-12-15T06:48:22+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "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/v1.0.0" + }, + "time": "2022-05-02T15:47:09+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.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "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.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%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-14T08:49:07+00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.70", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", + "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" + }, + "suggest": { + "psr/cache-implementation": "Cache implementation to use with Minify::cache" + }, + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "https://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", + "homepage": "https://github.com/matthiasmullie/minify", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2022-12-09T12:56:44+00:00" + }, + { + "name": "matthiasmullie/path-converter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/path-converter.git", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\PathConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "pathconverter@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Relative path converter", + "homepage": "http://github.com/matthiasmullie/path-converter", + "keywords": [ + "converter", + "path", + "paths", + "relative" + ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, + "time": "2019-02-05T23:41:09+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + }, + "time": "2022-11-12T15:38:23+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpbench/container", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpbench/container.git", + "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/container/zipball/6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", + "reference": "6d555ff7174fca13f9b1ec0b4a089ed41d0ab392", + "shasum": "" + }, + "require": { + "psr/container": "^1.0|^2.0", + "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "phpstan/phpstan": "^0.12.52", + "phpunit/phpunit": "^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpBench\\DependencyInjection\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "Simple, configurable, service container.", + "support": { + "issues": "https://github.com/phpbench/container/issues", + "source": "https://github.com/phpbench/container/tree/2.2.1" + }, + "time": "2022-01-25T10:17:35+00:00" + }, + { + "name": "phpbench/dom", + "version": "0.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpbench/dom.git", + "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/dom/zipball/b013b717832ddbaadf2a40984b04bc66af9a7110", + "reference": "b013b717832ddbaadf2a40984b04bc66af9a7110", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^7.2||^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.18", + "phpstan/phpstan": "^0.12.83", + "phpunit/phpunit": "^8.0||^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpBench\\Dom\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "DOM wrapper to simplify working with the PHP DOM implementation", + "support": { + "issues": "https://github.com/phpbench/dom/issues", + "source": "https://github.com/phpbench/dom/tree/0.3.2" + }, + "time": "2021-09-24T15:26:07+00:00" + }, + { + "name": "phpbench/phpbench", + "version": "1.2.7", + "source": { + "type": "git", + "url": "https://github.com/phpbench/phpbench.git", + "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpbench/phpbench/zipball/dce145304abbb16c8d9af69c19d96f47e9d0e670", + "reference": "dce145304abbb16c8d9af69c19d96f47e9d0e670", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.13", + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "ext-tokenizer": "*", + "php": "^7.3 || ^8.0", + "phpbench/container": "^2.1", + "phpbench/dom": "~0.3.1", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "seld/jsonlint": "^1.1", + "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/filesystem": "^4.2 || ^5.0 || ^6.0", + "symfony/finder": "^4.2 || ^5.0 || ^6.0", + "symfony/options-resolver": "^4.2 || ^5.0 || ^6.0", + "symfony/process": "^4.2 || ^5.0 || ^6.0", + "webmozart/glob": "^4.6" + }, + "require-dev": { + "dantleech/invoke": "^2.0", + "friendsofphp/php-cs-fixer": "^3.0", + "jangregor/phpstan-prophecy": "^1.0", + "phpspec/prophecy": "^1.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^8.5.8 || ^9.0", + "symfony/error-handler": "^5.2 || ^6.0", + "symfony/var-dumper": "^4.0 || ^5.0 || ^6.0" + }, + "suggest": { + "ext-xdebug": "For Xdebug profiling extension." + }, + "bin": [ + "bin/phpbench" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "files": [ + "lib/Report/Func/functions.php" + ], + "psr-4": { + "PhpBench\\": "lib/", + "PhpBench\\Extensions\\XDebug\\": "extensions/xdebug/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Leech", + "email": "daniel@dantleech.com" + } + ], + "description": "PHP Benchmarking Framework", + "support": { + "issues": "https://github.com/phpbench/phpbench/issues", + "source": "https://github.com/phpbench/phpbench/tree/1.2.7" + }, + "funding": [ + { + "url": "https://github.com/dantleech", + "type": "github" + } + ], + "time": "2022-10-15T09:57:51+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + }, + "time": "2022-10-14T12:47:21+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" + }, + "time": "2022-11-29T15:06:56+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.23", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.14", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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 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", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-12-28T12:41:10+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "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/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.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", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+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": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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 calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "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", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T06:03:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "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/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "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": "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/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-12T14:47:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library 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/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "4211420d25eba80712bff236a98960ef68b866b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", + "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "support": { + "issues": "https://github.com/Seldaek/jsonlint/issues", + "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2022-04-01T13:37:23+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, + { + "name": "swoole/ide-helper", + "version": "4.8.9", + "source": { + "type": "git", + "url": "https://github.com/swoole/ide-helper.git", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe", + "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/4.8.9" + }, + "funding": [ + { + "url": "https://gitee.com/swoole/swoole?donate=true", + "type": "custom" + }, + { + "url": "https://github.com/swoole", + "type": "github" + } + ], + "time": "2022-04-18T20:38:04+00:00" + }, + { + "name": "symfony/console", + "version": "v5.4.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", + "reference": "58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "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/v5.4.17" + }, + "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": "2022-12-28T14:15:31+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ac09569844a9109a5966b9438fc29113ce77cf51", + "reference": "ac09569844a9109a5966b9438fc29113ce77cf51", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.13" + }, + "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": "2022-09-21T19:53:16+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.17", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "40c08632019838dfb3350f18cf5563b8080055fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/40c08632019838dfb3350f18cf5563b8080055fc", + "reference": "40c08632019838dfb3350f18cf5563b8080055fc", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.17" + }, + "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": "2022-12-22T10:31:03+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "reference": "54f14e36aa73cb8f7261d7686691fd4d75ea2690", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.11" + }, + "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": "2022-07-20T13:00:38+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.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": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "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/v5.4.11" + }, + "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": "2022-06-27T16:58:25+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-25T10:21:52+00:00" + }, + { + "name": "symfony/string", + "version": "v6.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "863219fd713fa41cbcd285a79723f94672faff4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", + "reference": "863219fd713fa41cbcd285a79723f94672faff4d", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "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.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.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/v6.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-14T16:11:27+00:00" + }, + { + "name": "textalk/websocket", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/Textalk/websocket-php.git", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46", + "shasum": "" + }, + "require": { + "php": "^7.2 | ^8.0", + "psr/log": "^1 | ^2 | ^3" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "WebSocket\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Fredrik Liljegren" + }, + { + "name": "Sören Jensen", + "email": "soren@abicart.se" + } + ], + "description": "WebSocket client and server", + "support": { + "issues": "https://github.com/Textalk/websocket-php/issues", + "source": "https://github.com/Textalk/websocket-php/tree/1.5.7" + }, + "time": "2022-03-29T09:46:59+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "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.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "twig/twig", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2022-12-27T12:28:18+00:00" + }, + { + "name": "webmozart/glob", + "version": "4.6.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/glob.git", + "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655", + "reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/filesystem": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Glob\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A PHP implementation of Ant's glob.", + "support": { + "issues": "https://github.com/webmozarts/glob/issues", + "source": "https://github.com/webmozarts/glob/tree/4.6.0" + }, + "time": "2022-05-24T19:45:58+00:00" + } + ], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "alias": "0.8.1", + "alias_normalized": "0.8.1.0" + } + ], + "minimum-stability": "stable", + "stability-flags": { + "utopia-php/cache": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0.0", + "ext-curl": "*", + "ext-imagick": "*", + "ext-mbstring": "*", + "ext-json": "*", + "ext-yaml": "*", + "ext-dom": "*", + "ext-redis": "*", + "ext-swoole": "*", + "ext-pdo": "*", + "ext-openssl": "*", + "ext-zlib": "*", + "ext-sockets": "*" + }, + "platform-dev": { + "ext-fileinfo": "*" + }, + "platform-overrides": { + "php": "8.0" + }, + "plugin-api-version": "2.2.0" +} From 7701d3a05327e02d8e933adc9afe27e7b26583c1 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 8 Jan 2023 10:11:56 +0200 Subject: [PATCH 62/87] deletes-queue --- app/cli.php | 10 +- app/worker.php | 114 +++++++++++++++++++- docker-compose.yml | 10 +- src/Appwrite/Platform/Tasks/Maintenance.php | 6 +- 4 files changed, 125 insertions(+), 15 deletions(-) diff --git a/app/cli.php b/app/cli.php index 57eb98537e..526a0dbfa9 100644 --- a/app/cli.php +++ b/app/cli.php @@ -37,8 +37,7 @@ $adapters[] = $pools ->get($value) ->pop() - ->getResource() - ; + ->getResource(); } return new Cache(new Sharding($adapters)); @@ -70,7 +69,8 @@ $collections = Config::getParam('collections', []); $last = \array_key_last($collections); - if (!($dbForConsole->exists($dbForConsole->getDefaultDatabase(), $last))) { /** TODO cache ready variable using registry */ + if (!($dbForConsole->exists($dbForConsole->getDefaultDatabase(), $last))) { + /** TODO cache ready variable using registry */ throw new Exception('Tables not ready yet.'); } @@ -123,7 +123,8 @@ }, ['pools', 'dbForConsole', 'cache']); CLI::setResource('influxdb', function (Registry $register) { - $client = $register->get('influxdb'); /** @var InfluxDB\Client $client */ + $client = $register->get('influxdb'); + /** @var InfluxDB\Client $client */ $attempts = 0; $max = 10; $sleep = 1; @@ -146,7 +147,6 @@ return $database; }, ['register']); - CLI::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); }, ['pools']); diff --git a/app/worker.php b/app/worker.php index 0c966a13f1..97203d3bfc 100644 --- a/app/worker.php +++ b/app/worker.php @@ -33,8 +33,7 @@ $database = $pools ->get('console') ->pop() - ->getResource() - ; + ->getResource(); $adapter = new Database($database, $cache); $adapter->setNamespace('console'); @@ -71,8 +70,7 @@ $adapters[] = $pools ->get($value) ->pop() - ->getResource() - ; + ->getResource(); } return new Cache(new Sharding($adapters)); @@ -163,3 +161,111 @@ Console::error('[Error] File: ' . $error->getFile()); Console::error('[Error] Line: ' . $error->getLine()); }); + +/** + * Get Console DB + * + * @returns Cache + */ +function getCache(): Cache +{ + global $register; + + $pools = $register->get('pools'); + /** @var \Utopia\Pools\Group $pools */ + + $list = Config::getParam('pools-cache', []); + $adapters = []; + + foreach ($list as $value) { + $adapters[] = $pools + ->get($value) + ->pop() + ->getResource(); + } + + return new Cache(new Sharding($adapters)); +} + +/** + * Get Console DB + * + * @returns Database + */ +function getConsoleDB(): Database +{ + global $register; + + /** @var \Utopia\Pools\Group $pools */ + $pools = $register->get('pools'); + + $dbAdapter = $pools + ->get('console') + ->pop() + ->getResource(); + + $database = new Database($dbAdapter, getCache()); + + $database->setNamespace('console'); + + return $database; +} + +/** + * Get Project DB + * + * @param Document $project + * @returns Database + */ +function getProjectDB(Document $project): Database +{ + global $register; + + /** @var \Utopia\Pools\Group $pools */ + $pools = $register->get('pools'); + + if ($project->isEmpty() || $project->getId() === 'console') { + return getConsoleDB(); + } + + $dbAdapter = $pools + ->get($project->getAttribute('database')) + ->pop() + ->getResource(); + + $database = new Database($dbAdapter, getCache()); + $database->setNamespace('_' . $project->getInternalId()); + + return $database; +} + + +/** + * Get Functions Storage Device + * @param string $projectId of the project + * @return Device + */ +function getFunctionsDevice($projectId): Device +{ + return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $projectId); +} + +/** + * Get Files Storage Device + * @param string $projectId of the project + * @return Device + */ +function getFilesDevice($projectId): Device +{ + return getDevice(APP_STORAGE_UPLOADS . '/app-' . $projectId); +} + +/** + * Get Builds Storage Device + * @param string $projectId of the project + * @return Device + */ +function getBuildsDevice($projectId): Device +{ + return getDevice(APP_STORAGE_BUILDS . '/app-' . $projectId); +} diff --git a/docker-compose.yml b/docker-compose.yml index 22043ad1cb..802860f503 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -625,10 +625,8 @@ services: - redis environment: - _APP_ENV + - _APP_WORKER_PER_CORE - _APP_CONNECTIONS_MAX - - _APP_CONNECTIONS_DB_CONSOLE - - _APP_CONNECTIONS_CACHE - - _APP_CONNECTIONS_QUEUE - _APP_POOL_CLIENTS - _APP_DOMAIN - _APP_DOMAIN_TARGET @@ -642,6 +640,10 @@ services: - _APP_REDIS_PORT - _APP_REDIS_USER - _APP_REDIS_PASS + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_QUEUE + - _APP_CONNECTIONS_CACHE - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_CACHE @@ -736,6 +738,7 @@ services: - redis environment: - _APP_ENV + - _APP_WORKER_PER_CORE - _APP_CONNECTIONS_MAX - _APP_POOL_CLIENTS - _APP_REDIS_HOST @@ -750,6 +753,7 @@ services: - _APP_CONNECTIONS_DB_PROJECT - _APP_CONNECTIONS_DB_CONSOLE - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE - _APP_REGION openruntimes-executor: diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 94d42a6a53..d3cb8e4a9f 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -89,9 +89,9 @@ function renewCertificates(Database $dbForConsole, Certificate $queueForCertific $time = DateTime::now(); $certificates = $dbForConsole->find('certificates', [ - Query::lessThan('attempts', 5), // Maximum 5 attempts - Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) - Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) + Query::lessThan('attempts', 5), // Maximum 5 attempts + Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) + Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) ]); From 3a43b6a56ae8cdfbe9280b98d2dadc0eb5595339 Mon Sep 17 00:00:00 2001 From: shimon Date: Sun, 8 Jan 2023 11:33:24 +0200 Subject: [PATCH 63/87] file_exists check --- app/workers/certificates.php | 18 ++++++++++-------- src/Appwrite/Platform/Tasks/Maintenance.php | 21 ++++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/workers/certificates.php b/app/workers/certificates.php index af99e1d6ef..ab24097cc7 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -109,14 +109,6 @@ $certificate->setAttribute('renewDate', getRenewDate($domain->get())); $certificate->setAttribute('attempts', 0); $certificate->setAttribute('issueDate', DateTime::now()); - - $queueForEdgeSyncOut->enqueue([ - 'type' => 'certificate', - 'key' => [ - 'domain' => $domain, - 'contents' => base64_encode(file_get_contents(APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz')), - ] - ]); } catch (Throwable $e) { // Set exception as log in certificate document $certificate->setAttribute('log', $e->getMessage()); @@ -136,6 +128,16 @@ // Save all changes we made to certificate document into database saveCertificateDocument($domain->get(), $certificate, $dbForConsole); + $filename = APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz'; + if (file_exists($filename)) { + $queueForEdgeSyncOut->enqueue([ + 'type' => 'certificate', + 'key' => [ + 'domain' => $domain, + 'contents' => base64_encode(file_get_contents($filename)), + ] + ]); + } } }; }); diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index d3cb8e4a9f..ccaed77ac0 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -19,6 +19,9 @@ public static function getName(): string return 'maintenance'; } + /** + * @throws \Exception + */ public function __construct() { $this @@ -37,7 +40,7 @@ public function action(Database $dbForConsole, Certificate $queueForCertificates Console::title('Maintenance V1'); Console::success(APP_NAME . ' maintenance process v1 has started'); - function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes) + function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_EXECUTIONS) @@ -45,7 +48,7 @@ function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes) ->trigger(); } - function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes) + function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_ABUSE) @@ -53,7 +56,7 @@ function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes) ->trigger(); } - function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes) + function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_AUDIT) @@ -61,7 +64,7 @@ function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes) ->trigger(); } - function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes) + function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_USAGE) @@ -69,7 +72,7 @@ function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueFor ->trigger(); } - function notifyDeleteConnections(Delete $queueForDeletes) + function notifyDeleteConnections(Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_REALTIME) @@ -77,14 +80,14 @@ function notifyDeleteConnections(Delete $queueForDeletes) ->trigger(); } - function notifyDeleteExpiredSessions(Delete $queueForDeletes) + function notifyDeleteExpiredSessions(Delete $queueForDeletes): void { $queueForDeletes ->setType(DELETE_TYPE_SESSIONS) ->trigger(); } - function renewCertificates(Database $dbForConsole, Certificate $queueForCertificate) + function renewCertificates(Database $dbForConsole, Certificate $queueForCertificate): void { $time = DateTime::now(); @@ -110,7 +113,7 @@ function renewCertificates(Database $dbForConsole, Certificate $queueForCertific } } - function notifyDeleteCache($interval, Delete $queueForDeletes) + function notifyDeleteCache($interval, Delete $queueForDeletes): void { $queueForDeletes @@ -119,7 +122,7 @@ function notifyDeleteCache($interval, Delete $queueForDeletes) ->trigger(); } - function notifyDeleteSchedules($interval, Delete $queueForDeletes) + function notifyDeleteSchedules($interval, Delete $queueForDeletes): void { $queueForDeletes From 1e85b5a95d51b91b4e1d03a6b2ec2e360e87c1e8 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 9 Jan 2023 10:19:23 +0200 Subject: [PATCH 64/87] file_exists check --- app/workers/certificates.php | 1 + src/Appwrite/Platform/Tasks/Maintenance.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/workers/certificates.php b/app/workers/certificates.php index ab24097cc7..82bbd75339 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -128,6 +128,7 @@ // Save all changes we made to certificate document into database saveCertificateDocument($domain->get(), $certificate, $dbForConsole); + $filename = APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz'; if (file_exists($filename)) { $queueForEdgeSyncOut->enqueue([ diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index ccaed77ac0..405fd44d6c 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -42,7 +42,7 @@ public function action(Database $dbForConsole, Certificate $queueForCertificates function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes): void { - $queueForDeletes + ($queueForDeletes) ->setType(DELETE_TYPE_EXECUTIONS) ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) ->trigger(); From 20c3c10152f4be66ede78bb8990e0d7c95485e73 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 9 Jan 2023 11:13:02 +0200 Subject: [PATCH 65/87] maintenance switched loop internal functions to class scope --- src/Appwrite/Platform/Tasks/Maintenance.php | 187 ++++++++++---------- 1 file changed, 95 insertions(+), 92 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Maintenance.php b/src/Appwrite/Platform/Tasks/Maintenance.php index 405fd44d6c..60b389ea32 100644 --- a/src/Appwrite/Platform/Tasks/Maintenance.php +++ b/src/Appwrite/Platform/Tasks/Maintenance.php @@ -32,104 +32,107 @@ public function __construct() ->callback(fn (Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes) => $this->action($dbForConsole, $queueForCertificates, $queueForDeletes)); } - /** - * @throws \Exception - */ - public function action(Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes): void + private function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes): void { - Console::title('Maintenance V1'); - Console::success(APP_NAME . ' maintenance process v1 has started'); + ($queueForDeletes) + ->setType(DELETE_TYPE_EXECUTIONS) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) + ->trigger(); + } - function notifyDeleteExecutionLogs(int $interval, Delete $queueForDeletes): void - { - ($queueForDeletes) - ->setType(DELETE_TYPE_EXECUTIONS) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) - ->trigger(); - } + private function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes): void + { + $queueForDeletes + ->setType(DELETE_TYPE_ABUSE) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) + ->trigger(); + } - function notifyDeleteAbuseLogs(int $interval, Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_ABUSE) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) - ->trigger(); - } + private function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes): void + { + $queueForDeletes + ->setType(DELETE_TYPE_AUDIT) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) + ->trigger(); + } - function notifyDeleteAuditLogs(int $interval, Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_AUDIT) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) - ->trigger(); - } + private function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes): void + { + $queueForDeletes + ->setType(DELETE_TYPE_USAGE) + ->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly)) + ->trigger(); + } - function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_USAGE) - ->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly)) - ->trigger(); - } + private function notifyDeleteConnections(Delete $queueForDeletes): void + { + $queueForDeletes + ->setType(DELETE_TYPE_REALTIME) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -60)) + ->trigger(); + } - function notifyDeleteConnections(Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_REALTIME) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -60)) - ->trigger(); - } + private function notifyDeleteExpiredSessions(Delete $queueForDeletes): void + { + $queueForDeletes + ->setType(DELETE_TYPE_SESSIONS) + ->trigger(); + } - function notifyDeleteExpiredSessions(Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_SESSIONS) - ->trigger(); - } + private function renewCertificates(Database $dbForConsole, Certificate $queueForCertificate): void + { + $time = DateTime::now(); + + $certificates = $dbForConsole->find('certificates', [ + Query::lessThan('attempts', 5), // Maximum 5 attempts + Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) + Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) + ]); - function renewCertificates(Database $dbForConsole, Certificate $queueForCertificate): void - { - $time = DateTime::now(); - $certificates = $dbForConsole->find('certificates', [ - Query::lessThan('attempts', 5), // Maximum 5 attempts - Query::lessThanEqual('renewDate', $time), // includes 60 days cooldown (we have 30 days to renew) - Query::limit(200), // Limit 200 comes from LetsEncrypt (300 orders per 3 hours, keeping some for new domains) - ]); - - - if (\count($certificates) > 0) { - Console::info("[{$time}] Found " . \count($certificates) . " certificates for renewal, scheduling jobs."); - - foreach ($certificates as $certificate) { - $queueForCertificate - ->setDomain(new Document([ - 'domain' => $certificate->getAttribute('domain') - ])) - ->trigger(); - } - } else { - Console::info("[{$time}] No certificates for renewal."); + if (\count($certificates) > 0) { + Console::info("[{$time}] Found " . \count($certificates) . " certificates for renewal, scheduling jobs."); + + foreach ($certificates as $certificate) { + $queueForCertificate + ->setDomain(new Document([ + 'domain' => $certificate->getAttribute('domain') + ])) + ->trigger(); } + } else { + Console::info("[{$time}] No certificates for renewal."); } + } - function notifyDeleteCache($interval, Delete $queueForDeletes): void - { + private function notifyDeleteCache($interval, Delete $queueForDeletes): void + { - $queueForDeletes - ->setType(DELETE_TYPE_CACHE_BY_TIMESTAMP) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) - ->trigger(); - } + $queueForDeletes + ->setType(DELETE_TYPE_CACHE_BY_TIMESTAMP) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) + ->trigger(); + } + + private function notifyDeleteSchedules($interval, Delete $queueForDeletes): void + { + + $queueForDeletes + ->setType(DELETE_TYPE_SCHEDULES) + ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) + ->trigger(); + } + + + /** + * @throws \Exception + */ + public function action(Database $dbForConsole, Certificate $queueForCertificates, Delete $queueForDeletes): void + { + Console::title('Maintenance V1'); + Console::success(APP_NAME . ' maintenance process v1 has started'); - function notifyDeleteSchedules($interval, Delete $queueForDeletes): void - { - $queueForDeletes - ->setType(DELETE_TYPE_SCHEDULES) - ->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval)) - ->trigger(); - } // # of days in seconds (1 day = 86400s) $interval = (int) App::getEnv('_APP_MAINTENANCE_INTERVAL', '86400'); @@ -144,15 +147,15 @@ function notifyDeleteSchedules($interval, Delete $queueForDeletes): void $time = DateTime::now(); Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds"); - notifyDeleteExecutionLogs($executionLogsRetention, $queueForDeletes); - notifyDeleteAbuseLogs($abuseLogsRetention, $queueForDeletes); - notifyDeleteAuditLogs($auditLogRetention, $queueForDeletes); - notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes); - notifyDeleteConnections($queueForDeletes); - notifyDeleteExpiredSessions($queueForDeletes); - renewCertificates($dbForConsole, $queueForCertificates); - notifyDeleteCache($cacheRetention, $queueForDeletes); - notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes); + $this->notifyDeleteExecutionLogs($executionLogsRetention, $queueForDeletes); + $this->notifyDeleteAbuseLogs($abuseLogsRetention, $queueForDeletes); + $this->notifyDeleteAuditLogs($auditLogRetention, $queueForDeletes); + $this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes); + $this->notifyDeleteConnections($queueForDeletes); + $this->notifyDeleteExpiredSessions($queueForDeletes); + $this->renewCertificates($dbForConsole, $queueForCertificates); + $this->notifyDeleteCache($cacheRetention, $queueForDeletes); + $this->notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes); }, $interval); } } From 93a5a3d1dbdc4f132f68b60482f5c1ca226ddd14 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 9 Jan 2023 15:54:52 +0200 Subject: [PATCH 66/87] minor fixes --- app/controllers/api/edge.php | 4 ++-- app/init.php | 23 ++++++++--------------- app/workers/sync-out.php | 1 + tests/e2e/General/AbuseTest.php | 2 +- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 9d35515255..bbd1599a4b 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -33,7 +33,7 @@ ->desc('Purge cache keys') ->groups(['edge']) ->label('scope', 'public') - ->param('keys', '', new ArrayList(new Text(4056), 600), 'Cache keys. an array containing alphanumerical cache keys') + ->param('keys', '', new ArrayList(new Text(9012), 600), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') ->inject('response') ->inject('queueForEdgeSyncIn') @@ -42,7 +42,7 @@ if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); } - + var_dump($keys); foreach ($keys as $parts) { $key = json_decode($parts); $queueForEdgeSyncIn diff --git a/app/init.php b/app/init.php index 090f51d39f..99097ff8ba 100644 --- a/app/init.php +++ b/app/init.php @@ -1158,21 +1158,14 @@ function getDevice($root): Device Console::error($e->getMessage() . 'Invalid DSN. Defaulting to Local device.'); } - switch ($device) { - case Storage::DEVICE_S3: - return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl); - case STORAGE::DEVICE_DO_SPACES: - return new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl); - case Storage::DEVICE_BACKBLAZE: - return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl); - case Storage::DEVICE_LINODE: - return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl); - case Storage::DEVICE_WASABI: - return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl); - case Storage::DEVICE_LOCAL: - default: - return new Local($root); - } + return match ($device) { + Storage::DEVICE_S3 => new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl), + STORAGE::DEVICE_DO_SPACES => new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl), + Storage::DEVICE_BACKBLAZE => new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl), + Storage::DEVICE_LINODE => new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl), + Storage::DEVICE_WASABI => new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl), + default => new Local($root), + }; } App::setResource('mode', function ($request) { diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 1a9dfbdc13..03179a56e5 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -44,6 +44,7 @@ function call(string $url, string $token, array $data): int $delimiter = '-------------' . $boundary; $payload = ''; $eol = "\r\n"; + var_dump($data); foreach ($data as $keys) { $payload .= "--" . $delimiter . $eol . 'Content-Disposition: form-data; name="keys[]"' . $eol . $eol diff --git a/tests/e2e/General/AbuseTest.php b/tests/e2e/General/AbuseTest.php index 90a4b33800..0db8ce04d9 100644 --- a/tests/e2e/General/AbuseTest.php +++ b/tests/e2e/General/AbuseTest.php @@ -17,7 +17,7 @@ class AbuseTest extends Scope use ProjectCustom; use SideNone; - protected function setUp(): void + public function setUp(): void { parent::setUp(); From d32dea81e7defe46f8b197830644d60c3ef0cac4 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 9 Jan 2023 15:55:07 +0200 Subject: [PATCH 67/87] minor fixes --- tests/e2e/General/UsageTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 4dddaf1535..2bf1033904 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -21,7 +21,7 @@ class UsageTest extends Scope protected string $projectId; - protected function setUp(): void + public function setUp(): void { parent::setUp(); } @@ -791,7 +791,7 @@ public function testFunctionsStats(array $data): void $this->validateDates($response['executionsFailure']); } - protected function tearDown(): void + public function tearDown(): void { $this->usersCount = 0; $this->requestsCount = 0; From 23d0867f67b6b67ba565d3a37674b81230e2a3fd Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 10 Jan 2023 16:16:22 +0200 Subject: [PATCH 68/87] minor fixes --- app/workers/sync-out.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 03179a56e5..94e03a7dc6 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -44,6 +44,7 @@ function call(string $url, string $token, array $data): int $delimiter = '-------------' . $boundary; $payload = ''; $eol = "\r\n"; + console::warning('Sending ' . count($data) . 'to ' . $url); var_dump($data); foreach ($data as $keys) { $payload .= "--" . $delimiter . $eol @@ -53,6 +54,7 @@ function call(string $url, string $token, array $data): int $payload .= "--" . $delimiter . "--" . $eol; $status = 404; + $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, From fc8b5a2afd7af9a7d0381dc353fbb0046bb66cc8 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 11 Jan 2023 16:06:50 +0200 Subject: [PATCH 69/87] minor fixes --- app/controllers/api/edge.php | 10 +++++++--- app/worker.php | 15 ++++++++------- app/workers/certificates.php | 24 +++++++++++++----------- app/workers/{sync-In.php => sync-in.php} | 0 app/workers/sync-out.php | 1 + 5 files changed, 29 insertions(+), 21 deletions(-) rename app/workers/{sync-In.php => sync-in.php} (100%) diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index bbd1599a4b..71b11b9c4d 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -6,13 +6,11 @@ use Appwrite\Utopia\Request; use Appwrite\Utopia\Response; use Utopia\App; -use Utopia\Database\Database; +use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Queue\Client; use Utopia\Validator\ArrayList; -use Utopia\Validator\Assoc; use Utopia\Validator\Text; -use Utopia\Validator\WhiteList; App::init() ->groups(['edge']) @@ -42,7 +40,13 @@ if (empty($keys)) { throw new Exception(Exception::KEY_NOT_FOUND); } + + $originEdgeUrl = $request->getHeader('origin-edge-url'); + $time = DateTime::now(); + + var_dump('[' . $time . '] incoming request from:' . $originEdgeUrl); var_dump($keys); + foreach ($keys as $parts) { $key = json_decode($parts); $queueForEdgeSyncIn diff --git a/app/worker.php b/app/worker.php index 97203d3bfc..b6572e59c1 100644 --- a/app/worker.php +++ b/app/worker.php @@ -12,7 +12,7 @@ use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Pools\Connection; +use Utopia\Queue\Connection; use Utopia\Queue\Adapter\Swoole; use Utopia\Queue\Client; use Utopia\Queue\Message; @@ -21,6 +21,7 @@ use Utopia\Logger\Log; use Utopia\Logger\Logger; use Utopia\Pools\Group; +use Utopia\Storage\Device; Runtime::enableCoroutine(SWOOLE_HOOK_ALL); @@ -88,7 +89,7 @@ return new Certificate($queue); }, ['queue']); -Server::setResource('queueForSyncOut', function (Connection $queue) { +Server::setResource('queueForEdgeSyncOut', function (Connection $queue) { return new Client('v1-sync-out', $queue); }, ['queue']); @@ -107,13 +108,13 @@ $pools = $register->get('pools'); $connection = $pools->get('queue')->pop()->getResource(); $workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6)); -$workerNumber =1; + if (empty(App::getEnv('QUEUE'))) { throw new Exception('Please configure "QUEUE" environemnt variable.'); } $adapter = new Swoole($connection, $workerNumber, App::getEnv('QUEUE')); -$server = new Server($adapter); +$server = new Server($adapter); $server ->shutdown() @@ -245,7 +246,7 @@ function getProjectDB(Document $project): Database * @param string $projectId of the project * @return Device */ -function getFunctionsDevice($projectId): Device +function getFunctionsDevice(string $projectId): Device { return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $projectId); } @@ -255,7 +256,7 @@ function getFunctionsDevice($projectId): Device * @param string $projectId of the project * @return Device */ -function getFilesDevice($projectId): Device +function getFilesDevice(string $projectId): Device { return getDevice(APP_STORAGE_UPLOADS . '/app-' . $projectId); } @@ -265,7 +266,7 @@ function getFilesDevice($projectId): Device * @param string $projectId of the project * @return Device */ -function getBuildsDevice($projectId): Device +function getBuildsDevice(string $projectId): Device { return getDevice(APP_STORAGE_BUILDS . '/app-' . $projectId); } diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 82bbd75339..38a0fb3548 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -109,6 +109,18 @@ $certificate->setAttribute('renewDate', getRenewDate($domain->get())); $certificate->setAttribute('attempts', 0); $certificate->setAttribute('issueDate', DateTime::now()); + + // Enqueue certificate for regional sync + $filename = APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz'; + if (file_exists($filename)) { + $queueForEdgeSyncOut->enqueue([ + 'type' => 'certificate', + 'key' => [ + 'domain' => $domain, + 'contents' => base64_encode(file_get_contents($filename)), + ] + ]); + } } catch (Throwable $e) { // Set exception as log in certificate document $certificate->setAttribute('log', $e->getMessage()); @@ -128,17 +140,6 @@ // Save all changes we made to certificate document into database saveCertificateDocument($domain->get(), $certificate, $dbForConsole); - - $filename = APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz'; - if (file_exists($filename)) { - $queueForEdgeSyncOut->enqueue([ - 'type' => 'certificate', - 'key' => [ - 'domain' => $domain, - 'contents' => base64_encode(file_get_contents($filename)), - ] - ]); - } } }; }); @@ -426,6 +427,7 @@ function updateDomainDocuments(string $certificateId, string $domain, Database $ ->inject('message') ->inject('dbForConsole') ->inject('execute') + ->inject('queueForEdgeSyncOut') ->action(function ($message, $dbForConsole, $execute, Client $queueForEdgeSyncOut) use ($server) { $payload = $message->getPayload() ?? []; diff --git a/app/workers/sync-In.php b/app/workers/sync-in.php similarity index 100% rename from app/workers/sync-In.php rename to app/workers/sync-in.php diff --git a/app/workers/sync-out.php b/app/workers/sync-out.php index 94e03a7dc6..faf7fa29ef 100644 --- a/app/workers/sync-out.php +++ b/app/workers/sync-out.php @@ -58,6 +58,7 @@ function call(string $url, string $token, array $data): int $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, + 'Origin-edge-url: ' . App::getEnv('_APP_REGION'), 'Content-type: multipart/form-data; boundary=' . $delimiter, 'Content-Length: ' . strlen($payload) ]); From f179573954dc9dfa2644706d1f93e73d5a9a36ed Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 16 Jan 2023 14:10:54 +0200 Subject: [PATCH 70/87] test adjustments --- .../Databases/DatabasesConsoleClientTest.php | 82 +++++++++---------- .../Functions/FunctionsCustomServerTest.php | 3 +- .../Realtime/RealtimeCustomClientTest.php | 3 +- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php index 71fa7a590f..12bd85bee9 100644 --- a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php @@ -56,47 +56,47 @@ public function testCreateCollection(): array /** * @depends testCreateCollection */ - // public function testGetDatabaseUsage(array $data) - // { - // $databaseId = $data['databaseId']; - // /** - // * Test for FAILURE - // */ - - // $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'] - // ], $this->getHeaders()), [ - // 'range' => '32h' - // ]); - - // $this->assertEquals(400, $response['headers']['status-code']); - - // /** - // * Test for SUCCESS - // */ - - // $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ - // 'content-type' => 'application/json', - // 'x-appwrite-project' => $this->getProject()['$id'] - // ], $this->getHeaders()), [ - // 'range' => '24h' - // ]); - - // $this->assertEquals(200, $response['headers']['status-code']); - // $this->assertEquals(count($response['body']), 11); - // $this->assertEquals($response['body']['range'], '24h'); - // $this->assertIsArray($response['body']['documentsCount']); - // $this->assertIsArray($response['body']['collectionsCount']); - // $this->assertIsArray($response['body']['documentsCreate']); - // $this->assertIsArray($response['body']['documentsRead']); - // $this->assertIsArray($response['body']['documentsUpdate']); - // $this->assertIsArray($response['body']['documentsDelete']); - // $this->assertIsArray($response['body']['collectionsCreate']); - // $this->assertIsArray($response['body']['collectionsRead']); - // $this->assertIsArray($response['body']['collectionsUpdate']); - // $this->assertIsArray($response['body']['collectionsDelete']); - // } + public function testGetDatabaseUsage(array $data) + { + $databaseId = $data['databaseId']; + /** + * Test for FAILURE + */ + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'] + ], $this->getHeaders()), [ + 'range' => '32h' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + /** + * Test for SUCCESS + */ + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'] + ], $this->getHeaders()), [ + 'range' => '24h' + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(count($response['body']), 11); + $this->assertEquals($response['body']['range'], '24h'); + $this->assertIsArray($response['body']['documentsCount']); + $this->assertIsArray($response['body']['collectionsCount']); + $this->assertIsArray($response['body']['documentsCreate']); + $this->assertIsArray($response['body']['documentsRead']); + $this->assertIsArray($response['body']['documentsUpdate']); + $this->assertIsArray($response['body']['documentsDelete']); + $this->assertIsArray($response['body']['collectionsCreate']); + $this->assertIsArray($response['body']['collectionsRead']); + $this->assertIsArray($response['body']['collectionsUpdate']); + $this->assertIsArray($response['body']['collectionsDelete']); + } /** diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php index e2d7b8482b..e97c1412b6 100644 --- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php +++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php @@ -635,7 +635,7 @@ public function testCreateExecution($data): array $this->assertStringContainsString('8.0', $execution['body']['response']); $this->assertStringContainsString('êä', $execution['body']['response']); // tests unknown utf-8 chars $this->assertEquals('', $execution['body']['stderr']); - $this->assertLessThan(1.500, $execution['body']['duration']); + $this->assertLessThan(3, $execution['body']['duration']); /** * Test for FAILURE @@ -915,7 +915,6 @@ public function testTimeout() $this->assertEquals($executions['body']['executions'][0]['statusCode'], 500); $this->assertGreaterThan(2, $executions['body']['executions'][0]['duration']); $this->assertLessThan(6, $executions['body']['executions'][0]['duration']); - $this->assertGreaterThan(4, $executions['body']['executions'][0]['duration']); $this->assertEquals($executions['body']['executions'][0]['response'], ''); $this->assertEquals($executions['body']['executions'][0]['stderr'], 'An internal curl error has occurred within the executor! Error Msg: Operation timed out'); diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 7f09cb5703..575a9f8dc1 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -576,7 +576,6 @@ public function testChannelAccount() ]); $response = json_decode($client->receive(), true); - $this->assertArrayHasKey('type', $response); $this->assertArrayHasKey('data', $response); $this->assertEquals('event', $response['type']); @@ -1248,7 +1247,7 @@ public function testChannelExecutions() $this->assertNotEmpty($deployment['body']['$id']); // Wait for deployment to be built. - sleep(5); + sleep(10); $response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([ 'content-type' => 'application/json', From dd928d589023fdf6009e72aa8d453962dc426316 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 16 Jan 2023 14:29:52 +0200 Subject: [PATCH 71/87] test adjustments --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 855ed6e546..4c3be01479 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -85,7 +85,7 @@ services: - ./public:/usr/src/code/public - ./src:/usr/src/code/src - ./dev:/usr/local/dev - - ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework + #- ./vendor/utopia-php/framework:/usr/src/code/vendor/utopia-php/framework #- ./vendor/utopia-php/cache:/usr/src/code/vendor/utopia-php/cache depends_on: - mariadb @@ -268,7 +268,7 @@ services: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - appwrite-certificates:/storage/certificates:rw - - ./vendor/utopia-php/pools:/usr/src/code/vendor/utopia-php/pools + #- ./vendor/utopia-php/pools:/usr/src/code/vendor/utopia-php/pools depends_on: - mariadb - redis From 102a8408544c04e2437a12734f12f20e1c91840b Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 16 Jan 2023 14:37:01 +0200 Subject: [PATCH 72/87] test adjustments --- app/workers/deletes.php | 2 +- bla.tar.gz | Bin 0 -> 5412 bytes .../Databases/DatabasesConsoleClientTest.php | 82 +++++++++--------- 3 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 bla.tar.gz diff --git a/app/workers/deletes.php b/app/workers/deletes.php index a17c7f4229..89b577ce1d 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -728,4 +728,4 @@ function deleteBucket(Document $document, Document $project) } $server->workerStart(); -$server->start(); \ No newline at end of file +$server->start(); diff --git a/bla.tar.gz b/bla.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e197de043ea57dd0e42a4435d06f0cf8a84ce70d GIT binary patch literal 5412 zcmaKs^*ys2Og43PxHW%n_ z!VV^UJ7!XE3jYMt>hdbH{$|6o*gI-oFu(uWUUlz%oAx~q(o>p-5TDmNhj{aRQ9ye~ z=<4B}qrsanf{Z{MDzi2kmdQnscjL&_wEvk5lh*+NK3tUI>iVM zJ%k)WX=g7WZ>KTX3%BMrRETg-v@niRc=IEB)Mogd=mVkUJ#-Uud4)+6^!i$p7rv{C zc+Vc|BzGP{BSfPr!dSc~*<>#fYo|5j@JDN;qYH0((^bCk&ybhPM<7*ntixL9Se?%R zp2ha-_rW z9_NKel^c^gE9mSVy!Q0V>ZF=d3a3UmLv%Pji9xi4|B&6Of`D^i1Xvg$_Qndv5ScX+ zb7i&Mr1hx7Rz4fDTf`)b>=@%*Y^+L2H0Tz|k{j4_H|Els#xeaP+spj#l00>OYk*i| z38hFo;W29fqiwMwFZdSIL_25<4-)gPjt>g04KAG9%EU#k{;_^amPHwpU8il4^~3Kf zG{0*S+pp4>Hg}3bFQ2)@P>q>puCH%jw%DkOMuG;PYvPIArqB^cPkXQ$M#-7{I|gOW zg@@W5A5G|^LQRK0vn)iW3x(EcB8({i381aSusXML-1*a)ZRf-qqFr%4!M}ynZKkdX zI)VeUlHcOc=Sfw?;0IB}NXOrF^~4k$=JWJww=~1l^ZymYy~|umRqIr5g0@w3duR4O z_9})nxmqMQkqV!GnnJLvy+j>2Rg#HExNWcIS{>}+^D_UM%A(P44PE~|JjQRkQ(Q%W z^msX5W>S2dT+3%PZsYw~^}%xS4OxV^g{-I^1HL%Md?o2H$zb5l(oDyaTeGl;s0P5h z{0yqKXFX*n@rQSmY0>VO1kbCcsWBYgkdkEJa&LgQq;3xsY-n~~Ea@#R6bmL%PVND= zo{~#2nRv{M+(is##lP9{7OJmC`t#{W*0UC)L8-8f1(R0Q>8rM+z9bPOQY6GGUdEKH zqRM7MaLT{-z~tBS!{c`o8tP(Z@4A}gSF$f4ST+%)m{YiNW8E+7JCi9j_89F+*Ma#wbH2kgEZtH`Gh@{iVzhuwbSNkN7K>Qiafibfo4lbT1EIhnVf z3TICq^70}w9L&sI?>X@J3LKE3lhTB*8e2vTqMPi>+J@TltxclBlu0AscEC`Hf?t}) z)-p81M}jg2yZURN{Y>X{ZJ%KDE{*78u(!0gTj$%aOZ#@D1Y)mBlrTk@#EdKHR}nd` z9Y_A0d{GO;#g!oXcKn$&o{cJ=*jP)#{8f$Wl4T5Mzg z5I_qVLh^u`ksW>|_y@dl32m-mdbMbdwf79cR4EaUC+_C&QkKWHw!wgc>VZmb!C3|^ z*1sxlBh6rad(viBtCP+^#HQh?ghf29AO$Dslg8U;GlT#Q+G0t03CH`DgUj40;gg?t zNen1*FHp(Nd|-<22raBOG5CiU-H}FQI`NtA8hMZhZtO&OYQgc7Jc^aHK^@6MR;$$7 zF2*)hR!a;!^S|Mas9C%U?z^D|*QP4$_k_bL{<=S_Uui5U_EKpoMpF5?2_r_0Ib~d~ zed=UmJFqTId-;9%AI?(`6S0HziS`!;+A?!&y8h%k`AoE%QP14d`L-ruGn5t$%<&GC zx~M6u^~&DKNXmXb!v>3fb0!W)=3-{GAH(C<=fiJW4x4yt)N@@wVno1#H(VEVbQZm@rc2rR8WMd|OTLlyqw_flTryRUy+sD*gm2$1#bf&j z|Ip_s`N-*^z-7GZKmT@aJZR%EZpk4q)v{_rjKRM%*!pP9!MlLKSc`suC7tucDqu_DOj<_^Bit`wcwT6$4?su(&X~B(;AbDucr3@75 zbAAOUXxK9Gxumi9xAoz>gA+q;8+`J`G``;Sjr=?Hkec|BchICxs!q(>tHQiqE(0~r zW~}%IbT7$QH4a3h3pJ;)^ZgRgQxLkmHdi}(%ilDy9o#KQDDD11YTZiov>F_UT>vKB z{mme-tbg^wmn}y1Vnqn-m>D2eyjjmKQd<#wwHl{@i_zdnI^&YI@ZwBqpBe2yMFdHW z&{)@Q{C-u^t2TXn4p-uZmFHRbaj;F_MD}$1KjpEXXe%{~_&4QBpT+3i0*5F@;iE|t zg;lEPr_Fx))#&eKKigcB4QUyByUfC~3_Vs6^%c z#WD*RKhq-lg4160S;|H$TISI7<5cSfZ~*`ME?USXwR?6i^SNyA@VS3uPi6U5nqd5 z?{N1*kuNVFEp8Y*OBax1dPdYzqd%@@l54`Cdcu&coqJ_i*z;*)&KulS*>9E*PD#A- zS=~F&ib;}s7?PUPxdyYA_4moUn6$n-x3dE>nH%D@3bh4rD=f8DWqJ}5!X>*X246o~ zkcHECT~H4!OGLY2azFIU+`o#$4=Y>5z~i8o16rrKZKk>;)nJq0&wYCP=1f^nHl?;T zVv3g>in_Ba&sG&lO?-F5_MIx{F0Y6=RGkcJzedT$)_XqV`#Y3)AkOw-%q<9KMY_b} zG?Z#H{bME;C>>5f^{DUSJFs`>I?|})TF;gVfYmg@ti*>L1-s^X`jm((KrC46jz)dg zU7CzYSO?YHfUc}&*RHt8D=%B`#ct>FAcwQ1;iL=0z5#yUSdOw~;_YnaeM30X)iDujZt;4o#+10K(eUP-?(C=5y8E!N+D3oI44Y$nbk6F)EG*3hD z#V5fz#T~YO&fm$r+Nq|2qCfiW(_XRM>K0T+kv}ENwlyhU29usNaZ>W; z(R~)N*5TL!8G3$b`cZvy85`-fr}fvAI#_L+J4%$C!1#i`BG4PE2EeWi3+4sc(`G6K z?&N&lILIk2^bN(|$A*w6tJ~-yRH{2`ZS9nQduUu?;XtN5IXiqE@k7?;tNFXXytm}4 z!bMPo9>egzz7^zKSBKI;;GX7HN;*q-oAmQ7qucn;fonm%yF8)D9O4T<@oKh97u1NJeD{2bP|{tBH-X z-%{mP)b3fY=kZ+4|3B620ll-uz&Qk z9vqlqv9^fmt>7g)zN=#=2P|%u7seLlqDEJ3B#RCpPLQQ%ua<&cGW)hLH` z(YF_Ad&OA#)_VckZEPO04hIB1ftG#vm@LaFcOl6<1xl{`ptzO>%pi6# zty2GZH40AgESf;&~8^k@KKYM`J zPU>|P)kEbMP96jTGo<;1Wz{cII2ce*l~$*VEbI0}%$Td1OukeYx-ct{StjT9Re}O+ zq`Fm^Co}TqD#>i#HNPOm&*`-~V%WW8N+ZyN?^@Kdn%Ev(9fHS=-k7txdeS3lusmfx zFF3ZJ8%9h)e6Drh_MkWSrG6=7J!I1&*4=1+rAqYve*BdUElw4V`L|G3s9=Od7C(#& zIF%!HbXe1^4e@TTe{wbNFD}%5Bm?-RUZ&J9ykp9Vmv1lyKkUB-u732u6X%oC1?%}( zblm{3ASOFhOgPj26ue(}hzl`WHpVE~lN#FZ6IVl(O@qy3O%x_m)(oolcIe0Nc@ZDI zL<1j8qSXGBnxi?kXFU!E0^XUzw?{m?CC@;^u`G3%rlkbd=LH!}^%-v+o}zOyPGPT~ z7M+Moo<4MHIl?^z*l^@G+n6VA#rcK^+&h?c!GH(Y@-fSZ@CHksA^%ES`ysdbzHf-R zUbLcGkWU{aLTMkA)~~T8s~98G^K~O-8sO#zjO}?t&`v9%VZ6{^>X^fjI6{0V%-(-u z=?u-}R*pXM7UvWXP>GP@s5>yj<4NKQ%a~NH&)BQb1afvk>x8Ma&AX?ym7s+sZd+C@2<65#uP2#Fuv3gLWX~+PQLET1G?E(6bwRv-j zxwQ+%Sl_<73D@J&dANQg&yG<*W5NmLfl0axo3kyqzWo0!F~94E2*YW@V3?1=wF_pH zj|pTy12B81_wovuM?#LU`+LF6hgHnK)4uw-+8wUG_MOL?#B=0dV{nes5_MR$m1?2` zuy}UteM39H#it`(5ZRn$dW$Q#0!}WXXmGB=UEvtFWIJHwZ_>^jSI7ETf=aB?mkRr< zFMWF*6TRCKoo8BOh12fjDx1!(jl0>sX4mLgn-o-UaA7q>Mat?8Q95b0qFErKr2t!0 zs>T`IIM-_W$K=9;+Y>#UMdy02bRggSM}9f`?Sk$8JdIr$?k*23;Bb^w z-z;#HLuSSI9SdpN$&~zlj`{}{(yImpj%zFqp@?_FGJ(1y|!$g|Ak@Or1nK1LK9(i_3`yr_MXds{Q^JrG?&!nLjP_%JbeF=!waRF%_X5A zZekRD8i#8`wVq#CyNxhsnXr1lpw8hsW7Re?;tcH7maT|QIGgT<6E!Csq}CsX<;M}(0PH)D*LKlH>G6w#b>Vdcdo5%ScH zq%HG%QP5R&DxbnH_6jbPT<7VbSCBBaUuao-u!QtZ{wFI<|K}YNhpIHYvP(P6-M7?d zIt#x6%B9=?`*=Lq+t&U;0^8+pUn}WXOoB35qHJkfhjUtm;Lxfhd}?1G#%tqUqQ(7C z(pIxH4F@6yP&*SOHUBQ5g|dJ0yhZPrFh?j&V)ol&A<+2YCv_2ND)2~Oxgavtz|Tbp z-AhRCE;ISpa5+v-!0>b2n0CItnY^vB6@e4dA2{A-G(bmRM?_zQ1Q z97qh%y5=qss#3zj%B!C@B9$FcwFh^9TQ3(Tkhg6(hd%pMAW0Zy7^2$r#v>!p%_)24 zUm^Sn?O<91`zw#$1^gxJS||BU*$hEhhjV+kpqX#=OV~>9N@zkG!ur#+6%VpCUl0k3 z@GX4L1Jv}TYR}85PUPB=!fYMNzfb1|JO+9im`1JHPhrKCjX25?Ag%#T0r)VjZDt+0 zt(T+{eTAs;Xha6hcoq7k%8jjUA>J(b$vU@62lnIfu=F+cT>tDO*Ow)oKN)LIVjc4F zd92D?gHueGVXZ;b>8%u8}V|xm48v_$l!8t9@qr2@uP#abc37HBJMyGdsUG; zf%s+PR)?0+t^q-l>xezmI)wQ#e_QJTtHMN!7l<#9!g2@T2m)zJYZqbHWIY!da_x63 zf3K)qg#Yzfw^mWN(eS}+US7BnvtWT=@tM*y_Sfw1ZRqeG>tu}lbmZ+njCA$slnd(C z8Y{LcryCcMdtX1>*P+%dimE0AQ_S5tynGOYjI71~+tg;hpqJD<^~>81y1$g}*^dP{ zq|UR)i{mGS+cy9@GUgTmUJdD!Hh=0EJ&`_9$rk%d!dnStNw?iWT|+`qEHiWxbbi7h5Z>;s-8LldRCI?(`l#kbMHdkMb)zqT2vVl)_{d3;3*$@IQpHIJd4I Lw10`EhlTY&n!wH= literal 0 HcmV?d00001 diff --git a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php index 12bd85bee9..8049dbcd4e 100644 --- a/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php +++ b/tests/e2e/Services/Databases/DatabasesConsoleClientTest.php @@ -56,47 +56,47 @@ public function testCreateCollection(): array /** * @depends testCreateCollection */ - public function testGetDatabaseUsage(array $data) - { - $databaseId = $data['databaseId']; - /** - * Test for FAILURE - */ - - $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ - 'range' => '32h' - ]); - - $this->assertEquals(400, $response['headers']['status-code']); - - /** - * Test for SUCCESS - */ - - $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'] - ], $this->getHeaders()), [ - 'range' => '24h' - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertEquals(count($response['body']), 11); - $this->assertEquals($response['body']['range'], '24h'); - $this->assertIsArray($response['body']['documentsCount']); - $this->assertIsArray($response['body']['collectionsCount']); - $this->assertIsArray($response['body']['documentsCreate']); - $this->assertIsArray($response['body']['documentsRead']); - $this->assertIsArray($response['body']['documentsUpdate']); - $this->assertIsArray($response['body']['documentsDelete']); - $this->assertIsArray($response['body']['collectionsCreate']); - $this->assertIsArray($response['body']['collectionsRead']); - $this->assertIsArray($response['body']['collectionsUpdate']); - $this->assertIsArray($response['body']['collectionsDelete']); - } + public function testGetDatabaseUsage(array $data) + { + $databaseId = $data['databaseId']; + /** + * Test for FAILURE + */ + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'] + ], $this->getHeaders()), [ + 'range' => '32h' + ]); + + $this->assertEquals(400, $response['headers']['status-code']); + + /** + * Test for SUCCESS + */ + + $response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/usage', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'] + ], $this->getHeaders()), [ + 'range' => '24h' + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertEquals(count($response['body']), 11); + $this->assertEquals($response['body']['range'], '24h'); + $this->assertIsArray($response['body']['documentsCount']); + $this->assertIsArray($response['body']['collectionsCount']); + $this->assertIsArray($response['body']['documentsCreate']); + $this->assertIsArray($response['body']['documentsRead']); + $this->assertIsArray($response['body']['documentsUpdate']); + $this->assertIsArray($response['body']['documentsDelete']); + $this->assertIsArray($response['body']['collectionsCreate']); + $this->assertIsArray($response['body']['collectionsRead']); + $this->assertIsArray($response['body']['collectionsUpdate']); + $this->assertIsArray($response['body']['collectionsDelete']); + } /** From af25776d952828e9857cf8372c42ec52f7467fe4 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 23 Jan 2023 19:15:03 +0200 Subject: [PATCH 73/87] test adjustments --- tests/e2e/Services/Realtime/RealtimeCustomClientTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index 575a9f8dc1..b534e95ca7 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -108,6 +108,7 @@ public function testChannelParsing() $this->assertEquals($userId, $response['data']['user']['$id']); $client->close(); + } public function testManualAuthentication() @@ -213,6 +214,7 @@ public function testManualAuthentication() $client->close(); + } public function testConnectionPlatform() @@ -231,10 +233,12 @@ public function testConnectionPlatform() \usleep(250000); // 250ms $this->expectException(ConnectionException::class); // Check if server disconnnected client $client->close(); + } public function testChannelAccount() { + $user = $this->getUser(); $userId = $user['$id'] ?? ''; $session = $user['session'] ?? ''; @@ -425,6 +429,7 @@ public function testChannelAccount() $this->assertContains("users.*.verification.*.update", $response['data']['events']); $this->assertContains("users.*.verification.*", $response['data']['events']); $this->assertContains("users.*", $response['data']['events']); + /** * Test Acoount Prefs Update */ From 5dcc4d52a490f5f6a5f886d319a5a89c0d18283e Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:09:24 +0300 Subject: [PATCH 74/87] updates to multi region sync --- Dockerfile | 7 +- app/cli.php | 7 +- app/config/collections.php | 52 +++-- app/config/regions.php | 11 ++ app/config/services.php | 4 +- app/controllers/api/edge.php | 3 +- app/controllers/shared/api.php | 45 +++-- app/init.php | 75 ++++++- app/worker.php | 10 +- bin/worker-sync-in | 2 +- bin/worker-sync-out | 3 - bin/worker-sync-out-aggregation | 3 + bin/worker-sync-out-delivery | 3 + composer.json | 2 +- composer.lock | 41 ++-- docker-compose.yml | 112 +++++++---- src/Appwrite/Platform/Services/Tasks.php | 2 +- src/Appwrite/Platform/Services/Workers.php | 6 + src/Appwrite/Platform/Tasks/EdgeSync.php | 63 +++--- .../Platform/Workers/Certificates.php | 17 +- .../Workers/{sync-in.php => SyncIn.php} | 58 ++++-- .../Platform/Workers/SyncOutAggregation.php | 116 +++++++++++ .../Platform/Workers/SyncOutDelivery.php | 127 ++++++++++++ src/Appwrite/Platform/Workers/sync-out.php | 186 ------------------ src/Appwrite/Utopia/Response.php | 2 +- 25 files changed, 597 insertions(+), 360 deletions(-) delete mode 100644 bin/worker-sync-out create mode 100644 bin/worker-sync-out-aggregation create mode 100644 bin/worker-sync-out-delivery rename src/Appwrite/Platform/Workers/{sync-in.php => SyncIn.php} (65%) create mode 100644 src/Appwrite/Platform/Workers/SyncOutAggregation.php create mode 100644 src/Appwrite/Platform/Workers/SyncOutDelivery.php delete mode 100644 src/Appwrite/Platform/Workers/sync-out.php diff --git a/Dockerfile b/Dockerfile index 79dec5005a..5015ec4504 100755 --- a/Dockerfile +++ b/Dockerfile @@ -64,13 +64,15 @@ RUN mkdir -p /storage/uploads && \ mkdir -p /storage/config && \ mkdir -p /storage/certificates && \ mkdir -p /storage/functions && \ + mkdir -p /storage/syncs && \ mkdir -p /storage/debug && \ chown -Rf www-data.www-data /storage/uploads && chmod -Rf 0755 /storage/uploads && \ chown -Rf www-data.www-data /storage/cache && chmod -Rf 0755 /storage/cache && \ chown -Rf www-data.www-data /storage/config && chmod -Rf 0755 /storage/config && \ chown -Rf www-data.www-data /storage/certificates && chmod -Rf 0755 /storage/certificates && \ chown -Rf www-data.www-data /storage/functions && chmod -Rf 0755 /storage/functions && \ - chown -Rf www-data.www-data /storage/debug && chmod -Rf 0755 /storage/debug + chown -Rf www-data.www-data /storage/debug && chmod -Rf 0755 /storage/debug && \ + chown -Rf www-data.www-data /storage/syncs && chmod -Rf 0755 /storage/syncs # Executables RUN chmod +x /usr/local/bin/doctor && \ @@ -103,7 +105,8 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/worker-webhooks && \ chmod +x /usr/local/bin/worker-usage && \ chmod +x /usr/local/bin/worker-usage-dump && \ - chmod +x /usr/local/bin/worker-sync-out && \ + chmod +x /usr/local/bin/worker-sync-out-aggregation && \ + chmod +x /usr/local/bin/worker-sync-out-delivery && \ chmod +x /usr/local/bin/worker-sync-in # Letsencrypt Permissions diff --git a/app/cli.php b/app/cli.php index 70337a667b..96340869e5 100644 --- a/app/cli.php +++ b/app/cli.php @@ -166,8 +166,11 @@ CLI::setResource('queueForCertificates', function (Connection $queue) { return new Certificate($queue); }, ['queue']); -CLI::setResource('queueForEdgeSyncOut', function (Connection $queue) { - return new Client('v1-sync-out', $queue); +CLI::setResource('SyncOutAggregation', function (Connection $queue) { + return new Client('v1-sync-out-aggregation', $queue); +}, ['queue']); +CLI::setResource('SyncOut~Delivery', function (Connection $queue) { + return new Client('v1-sync-out-delivery', $queue); }, ['queue']); CLI::setResource('logError', function (Registry $register) { return function (Throwable $error, string $namespace, string $action) use ($register) { diff --git a/app/config/collections.php b/app/config/collections.php index 9abe68366d..f0ce987c2d 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4147,16 +4147,16 @@ 'name' => 'Syncs', 'attributes' => [ [ - '$id' => ID::custom('type'), + '$id' => ID::custom('sourceRegion'), 'type' => Database::VAR_STRING, - 'size' => 256, + 'size' => 50, 'required' => true, 'signed' => true, 'array' => false, 'filters' => [], ], [ - '$id' => ID::custom('region'), + '$id' => ID::custom('destRegion'), 'type' => Database::VAR_STRING, 'size' => 50, 'required' => true, @@ -4165,40 +4165,62 @@ 'filters' => [], ], [ - '$id' => ID::custom('target'), + '$id' => ID::custom('filename'), 'type' => Database::VAR_STRING, - 'size' => 50, + 'size' => 150, 'required' => true, 'signed' => true, 'array' => false, 'filters' => [], ], [ - '$id' => ID::custom('key'), - 'type' => Database::VAR_STRING, + '$id' => ID::custom('logCreatedAt'), + 'type' => Database::VAR_DATETIME, 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => true, - 'default' => [], + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, 'array' => false, - 'filters' => ['json'], + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('logSentAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], ], [ '$id' => ID::custom('status'), 'type' => Database::VAR_INTEGER, 'size' => 256, - 'required' => true, + 'required' => false, + 'signed' => true, + 'default' => 0, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('attempts'), + 'type' => Database::VAR_INTEGER, + 'size' => 256, + 'required' => false, 'signed' => true, + 'default' => 0, 'array' => false, 'filters' => [], ], ], 'indexes' => [ [ - '$id' => ID::custom('_key_region_target'), + '$id' => ID::custom('_key_sourceRegion_destRegion_logCreatedAt_status'), 'type' => Database::INDEX_KEY, - 'attributes' => ['region', 'target'], + 'attributes' => ['sourceRegion', 'destRegion','logCreatedAt', 'status'], 'lengths' => [], 'orders' => [], ], diff --git a/app/config/regions.php b/app/config/regions.php index b40667ab5e..f9a03b404d 100644 --- a/app/config/regions.php +++ b/app/config/regions.php @@ -7,6 +7,8 @@ 'disabled' => false, 'flag' => 'de', 'default' => true, + 'domain' => '172.29.0.1' + ], 'fra' => [ '$id' => 'fra', @@ -14,6 +16,7 @@ 'disabled' => false, 'flag' => 'de', 'default' => true, + 'domain' => '172.29.0.1' ], 'nyc' => [ '$id' => 'nyc', @@ -21,6 +24,7 @@ 'disabled' => true, 'flag' => 'us', 'default' => true, + 'domain' => '172.29.0.1' ], 'sfo' => [ '$id' => 'sfo', @@ -28,6 +32,7 @@ 'disabled' => true, 'flag' => 'us', 'default' => true, + 'domain' => '172.29.0.1' ], 'blr' => [ '$id' => 'blr', @@ -35,6 +40,7 @@ 'disabled' => true, 'flag' => 'in', 'default' => true, + 'domain' => '172.29.0.1' ], 'lon' => [ '$id' => 'lon', @@ -42,6 +48,7 @@ 'disabled' => true, 'flag' => 'gb', 'default' => true, + 'domain' => '172.29.0.1' ], 'ams' => [ '$id' => 'ams', @@ -49,6 +56,7 @@ 'disabled' => true, 'flag' => 'nl', 'default' => true, + 'domain' => '172.29.0.1' ], 'sgp' => [ '$id' => 'sgp', @@ -56,6 +64,7 @@ 'disabled' => true, 'flag' => 'sg', 'default' => true, + 'domain' => '172.29.0.1' ], 'tor' => [ '$id' => 'tor', @@ -63,6 +72,7 @@ 'disabled' => true, 'flag' => 'ca', 'default' => true, + 'domain' => '172.29.0.1' ], 'syd' => [ '$id' => 'syd', @@ -70,5 +80,6 @@ 'disabled' => true, 'flag' => 'au', 'default' => true, + 'domain' => '172.29.0.1' ], ]; diff --git a/app/config/services.php b/app/config/services.php index a13c92a922..29fac795d5 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -263,8 +263,8 @@ 'tests' => true, 'optional' => true, 'icon' => '/images/services/messaging.png', - ] - 'syncs' => [ + ], + 'syncs' => [ 'key' => 'edge', 'name' => 'edge', 'subtitle' => 'Appwrite\'s cache edge sync Endpoint', diff --git a/app/controllers/api/edge.php b/app/controllers/api/edge.php index 71b11b9c4d..17531d1563 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/edge.php @@ -9,6 +9,7 @@ use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Queue\Client; +use Utopia\System\System; use Utopia\Validator\ArrayList; use Utopia\Validator\Text; @@ -19,7 +20,7 @@ $token = $request->getHeader('authorization'); $token = str_replace(["Bearer"," "], "", $token); - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + $jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); try { $payload = $jwt->decode($token); } catch (JWTException $error) { diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 1ab0e4f46b..321724ff46 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -28,7 +28,6 @@ use Utopia\Database\Validator\Authorization; use Utopia\System\System; use Utopia\Validator\WhiteList; -use Utopia\Queue\Client; $parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) { preg_match_all('/{(.*?)}/', $label, $matches); @@ -540,8 +539,8 @@ ->inject('queueForFunctions') ->inject('mode') ->inject('dbForConsole') - ->inject('queueForEdgeSyncOut') - ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsoleClient $queueForEdgeSyncOut) use ($parseLabel) { + ->inject('queueForSyncOutAggregation') + ->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsoleClient, $queueForSyncOutAggregation) use ($parseLabel) { $responsePayload = $response->getPayload(); @@ -597,31 +596,31 @@ 'userId' => $queueForEvents->getParam('userId') ] ); - //Sync with other regions - $queueForEdgeSyncOut->enqueue([ - 'type' => 'realtime', - 'key' => [ - 'projectId' => $target['projectId'] ?? $project->getId(), - 'payload' => $events->getPayload(), - 'events' => $allEvents, - 'channels' => $target['channels'], - 'roles' => $target['roles'], - 'options' => [ - 'permissionsChanged' => $target['permissionsChanged'], - 'userId' => $events->getParam('userId') - ] + //Sync with other regions + $queueForSyncOutAggregation->enqueue([ + 'type' => 'realtime', + 'key' => [ + 'projectId' => $target['projectId'] ?? $project->getId(), + 'payload' => $queueForEvents->getPayload(), + 'events' => $allEvents, + 'channels' => $target['channels'], + 'roles' => $target['roles'], + 'options' => [ + 'permissionsChanged' => $target['permissionsChanged'], + 'userId' => $queueForEvents->getParam('userId') ] + ] ]); } } -// $queueForEdgeSyncOut->enqueue([ -// 'type' => 'certificate', -// 'key' => [ -// 'domain' => 'appwrite.io', -// 'contents' => base64_encode(file_get_contents(APP_STORAGE_CERTIFICATES . '/appwrite.io.tar.gz')), -// ] -// ]); + // $queueForSyncOutAggregation->enqueue([ + // 'type' => 'certificate', + // 'key' => [ + // 'domain' => 'appwrite.io', + // 'contents' => base64_encode(file_get_contents(APP_STORAGE_CERTIFICATES . '/appwrite.io.tar.gz')), + // ] + // ]); $route = $utopia->getRoute(); $requestParams = $route->getParamsValues(); diff --git a/app/init.php b/app/init.php index dbbcb1c343..7b0d9d6e34 100644 --- a/app/init.php +++ b/app/init.php @@ -44,7 +44,6 @@ use PHPMailer\PHPMailer\PHPMailer; use Swoole\Database\PDOProxy; use Utopia\App; -use Utopia\Queue\Client; use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Cache\Adapter\Sharding; use Utopia\Cache\Cache; @@ -68,6 +67,7 @@ use Utopia\Pools\Group; use Utopia\Pools\Pool; use Utopia\Queue; +use Utopia\Queue\Client; use Utopia\Queue\Connection; use Utopia\Registry\Registry; use Utopia\Storage\Device; @@ -130,6 +130,7 @@ const APP_STORAGE_CACHE = '/storage/cache'; const APP_STORAGE_CERTIFICATES = '/storage/certificates'; const APP_STORAGE_CONFIG = '/storage/config'; +const APP_STORAGE_SYNCS = '/storage/syncs'; const APP_STORAGE_READ_BUFFER = 20 * (1000 * 1000); //20MB other names `APP_STORAGE_MEMORY_LIMIT`, `APP_STORAGE_MEMORY_BUFFER`, `APP_STORAGE_READ_LIMIT`, `APP_STORAGE_BUFFER_LIMIT` const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite'; const APP_SOCIAL_TWITTER_HANDLE = 'appwrite'; @@ -1039,8 +1040,11 @@ function (mixed $value) { App::setResource('queue', function (Group $pools) { return $pools->get('queue')->pop()->getResource(); }, ['pools']); -App::setResource('queueForEdgeSyncOut', function (Connection $queue) { - return new Client('v1-sync-out', $queue); +App::setResource('queueForSyncOutAggregation', function (Connection $queue) { + return new Client('v1-sync-out-aggregation', $queue); +}, ['queue']); +App::setResource('queueForSyncOutDelivery', function (Connection $queue) { + return new Client('v1-sync-out-delivery', $queue); }, ['queue']); App::setResource('queueForEdgeSyncIn', function (Connection $queue) { return new Client('v1-sync-in', $queue); @@ -1377,7 +1381,60 @@ function (mixed $value) { return $database; }, ['pools', 'cache']); -App::setResource('cache', function (Group $pools, Client $queueForEdgeSyncOut) { +App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole, $cache) { + $databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools + + return function (Document $project) use ($pools, $dbForConsole, $cache, &$databases) { + if ($project->isEmpty() || $project->getId() === 'console') { + return $dbForConsole; + } + + try { + $dsn = new DSN($project->getAttribute('database')); + } catch (\InvalidArgumentException) { + // TODO: Temporary until all projects are using shared tables + $dsn = new DSN('mysql://' . $project->getAttribute('database')); + } + + $configure = (function (Database $database) use ($project, $dsn) { + $database + ->setMetadata('host', \gethostname()) + ->setMetadata('project', $project->getId()) + ->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS); + + if ($dsn->getHost() === DATABASE_SHARED_TABLES) { + $database + ->setSharedTables(true) + ->setTenant($project->getInternalId()) + ->setNamespace($dsn->getParam('namespace')); + } else { + $database + ->setSharedTables(false) + ->setTenant(null) + ->setNamespace('_' . $project->getInternalId()); + } + }); + + if (isset($databases[$dsn->getHost()])) { + $database = $databases[$dsn->getHost()]; + $configure($database); + return $database; + } + + $dbAdapter = $pools + ->get($dsn->getHost()) + ->pop() + ->getResource(); + + $database = new Database($dbAdapter, $cache); + $databases[$dsn->getHost()] = $database; + $configure($database); + + return $database; + }; +}, ['pools', 'dbForConsole', 'cache']); + +App::setResource('cache', function (Group $pools, Client $queueForSyncOutAggregation) { $list = Config::getParam('pools-cache', []); $adapters = []; @@ -1390,16 +1447,16 @@ function (mixed $value) { } $cache = new Cache(new Sharding($adapters)); - $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForEdgeSyncOut) { - $queueForEdgeSyncOut + $cache->on(cache::EVENT_SAVE, function ($key) use ($queueForSyncOutAggregation) { + $queueForSyncOutAggregation ->enqueue([ 'type' => 'cache', 'key' => $key ]); }); - $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForEdgeSyncOut) { - $queueForEdgeSyncOut + $cache->on(cache::EVENT_PURGE, function ($key) use ($queueForSyncOutAggregation) { + $queueForSyncOutAggregation ->enqueue([ 'type' => 'cache', 'key' => $key @@ -1407,7 +1464,7 @@ function (mixed $value) { }); return $cache; -}, ['pools', 'queueForEdgeSyncOut']); +}, ['pools', 'queueForSyncOutAggregation']); App::setResource('deviceForLocal', function () { return new Local(); diff --git a/app/worker.php b/app/worker.php index 1d1b66b9b0..9368fcaa2a 100644 --- a/app/worker.php +++ b/app/worker.php @@ -18,13 +18,13 @@ use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Document; -use Utopia\Queue\Client; use Utopia\Database\Validator\Authorization; use Utopia\DSN\DSN; use Utopia\Logger\Log; use Utopia\Logger\Logger; use Utopia\Platform\Service; use Utopia\Pools\Group; +use Utopia\Queue\Client; use Utopia\Queue\Connection; use Utopia\Queue\Message; use Utopia\Queue\Server; @@ -189,10 +189,12 @@ return new Cache(new Sharding($adapters)); }, ['register']); -Server::setResource('queueForEdgeSyncOut', function (Connection $queue) { - return new Client('v1-sync-out', $queue); +Server::setResource('queueForSyncOutAggregation', function (Connection $queue) { + return new Client('v1-sync-out-aggregation', $queue); +}, ['queue']); +Server::setResource('queueForSyncOutDelivery', function (Connection $queue) { + return new Client('v1-sync-out-delivery', $queue); }, ['queue']); - Server::setResource('log', fn () => new Log()); Server::setResource('queueForUsage', function (Connection $queue) { diff --git a/bin/worker-sync-in b/bin/worker-sync-in index cb688ff7f1..0c2bff5885 100644 --- a/bin/worker-sync-in +++ b/bin/worker-sync-in @@ -1,3 +1,3 @@ #!/bin/sh -QUEUE=v1-sync-in php /usr/src/code/app/workers/sync-in.php $@ \ No newline at end of file +php /usr/src/code/app/worker.php sync-in $@ \ No newline at end of file diff --git a/bin/worker-sync-out b/bin/worker-sync-out deleted file mode 100644 index 2ab76cbfcd..0000000000 --- a/bin/worker-sync-out +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -QUEUE=v1-sync-out php /usr/src/code/app/workers/sync-out.php $@ \ No newline at end of file diff --git a/bin/worker-sync-out-aggregation b/bin/worker-sync-out-aggregation new file mode 100644 index 0000000000..b01c427468 --- /dev/null +++ b/bin/worker-sync-out-aggregation @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/worker.php sync-out-aggregation $@ diff --git a/bin/worker-sync-out-delivery b/bin/worker-sync-out-delivery new file mode 100644 index 0000000000..d3ceec49a1 --- /dev/null +++ b/bin/worker-sync-out-delivery @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/worker.php sync-out-delivery $@ diff --git a/composer.json b/composer.json index cf8ae6f5fc..12b4a8be2c 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "utopia-php/abuse": "0.37.*", "utopia-php/analytics": "0.10.*", "utopia-php/audit": "0.39.*", - "utopia-php/cache": "dev-feat-redis-sync as 0.8.1", + "utopia-php/cache": "dev-feat-redis-sync as 0.9.1", "utopia-php/cli": "0.15.*", "utopia-php/config": "0.2.*", "utopia-php/database": "0.49.*", diff --git a/composer.lock b/composer.lock index 9cff491841..59f6390938 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bee024ec80d546d910563dc166baed9e", + "content-hash": "52996be154364fe3ed18dfd7764d8d18", "packages": [ { "name": "adhocore/jwt", @@ -1569,16 +1569,16 @@ }, { "name": "utopia-php/cache", - "version": "0.9.1", + "version": "dev-feat-redis-sync", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6" + "reference": "e0a88c4a6568a84d40482ebd880e73b040fc0b79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/552b4c554bb14d0c529631ce304cdf4a2b9d06a6", - "reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/e0a88c4a6568a84d40482ebd880e73b040fc0b79", + "reference": "e0a88c4a6568a84d40482ebd880e73b040fc0b79", "shasum": "" }, "require": { @@ -1613,9 +1613,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.9.1" + "source": "https://github.com/utopia-php/cache/tree/feat-redis-sync" }, - "time": "2024-03-19T17:07:20+00:00" + "time": "2024-06-03T07:42:02+00:00" }, { "name": "utopia-php/cli", @@ -3824,16 +3824,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/536889f2b340489d328f5ffb7b02bb6b183ddedc", - "reference": "536889f2b340489d328f5ffb7b02bb6b183ddedc", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -3865,9 +3865,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-05-06T12:04:23+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpunit/php-code-coverage", @@ -5587,9 +5587,18 @@ "time": "2023-11-21T18:54:41+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/cache", + "version": "dev-feat-redis-sync", + "alias": "0.9.1", + "alias_normalized": "0.9.1.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/cache": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -5613,5 +5622,5 @@ "platform-overrides": { "php": "8.3" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" } diff --git a/docker-compose.yml b/docker-compose.yml index ca4d9c4cbc..53282f18e7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -271,18 +271,18 @@ services: - _APP_LOGGING_PROVIDER - _APP_LOGGING_CONFIG - appwrite-worker-sync-out: - entrypoint: worker-sync-out + appwrite-worker-sync-out-aggregation: + entrypoint: worker-sync-out-aggregation <<: *x-logging - container_name: appwrite-worker-sync-out + container_name: worker-sync-out-aggregation image: appwrite-dev networks: - appwrite volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src - - appwrite-certificates:/storage/certificates:rw - #- ./vendor/utopia-php/pools:/usr/src/code/vendor/utopia-php/pools + #- appwrite-certificates:/storage/certificates:rw + - appwrite-syncs:/storage/syncs:rw depends_on: - mariadb - redis @@ -306,6 +306,42 @@ services: - _APP_WORKER_PER_CORE - _APP_REGION + appwrite-worker-sync-out-delivery: + entrypoint: worker-sync-out-delivery + <<: *x-logging + container_name: worker-sync-out-delivery + image: appwrite-dev + networks: + - appwrite + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + #- appwrite-certificates:/storage/certificates:rw + - appwrite-syncs:/storage/syncs:rw + depends_on: + - mariadb + - redis + environment: + - _APP_OPENSSL_KEY_V1 + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_CONNECTIONS_MAX + - _APP_POOL_CLIENTS + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE + - _APP_WORKER_PER_CORE + - _APP_REGION + appwrite-worker-sync-in: entrypoint: worker-sync-in <<: *x-logging @@ -757,39 +793,38 @@ services: - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY -appwrite-edge-sync: - entrypoint: edge-sync - <<: *x-logging - container_name: appwrite-edge-sync - image: appwrite-dev - networks: - - appwrite - volumes: - - ./app:/usr/src/code/app - - ./src:/usr/src/code/src - depends_on: - - mariadb - - redis - environment: - - _APP_CONNECTIONS_MAX - - _APP_CONNECTIONS_DB_PROJECT - - _APP_CONNECTIONS_DB_CONSOLE - - _APP_CONNECTIONS_CACHE - - _APP_CONNECTIONS_QUEUE - - _APP_POOL_CLIENTS - - _APP_ENV - - _APP_REDIS_HOST - - _APP_REDIS_PORT - - _APP_REDIS_USER - - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_SYNC_EDGE_INTERVAL - - _APP_REGION - + appwrite-task-edge-sync: + entrypoint: edge-sync + <<: *x-logging + container_name: appwrite-task-edge-sync + image: appwrite-dev + networks: + - appwrite + volumes: + - ./app:/usr/src/code/app + - ./src:/usr/src/code/src + depends_on: + - mariadb + - redis + environment: + - _APP_CONNECTIONS_MAX + - _APP_CONNECTIONS_DB_PROJECT + - _APP_CONNECTIONS_DB_CONSOLE + - _APP_CONNECTIONS_CACHE + - _APP_CONNECTIONS_QUEUE + - _APP_POOL_CLIENTS + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_SYNC_EDGE_INTERVAL + - _APP_REGION appwrite-worker-usage: entrypoint: worker-usage @@ -1123,3 +1158,4 @@ volumes: appwrite-functions: appwrite-builds: appwrite-config: + appwrite-syncs: diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index a951949d4c..6bffbdb320 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -3,6 +3,7 @@ namespace Appwrite\Platform\Services; use Appwrite\Platform\Tasks\Doctor; +use Appwrite\Platform\Tasks\EdgeSync; use Appwrite\Platform\Tasks\Install; use Appwrite\Platform\Tasks\Maintenance; use Appwrite\Platform\Tasks\Migrate; @@ -17,7 +18,6 @@ use Appwrite\Platform\Tasks\Vars; use Appwrite\Platform\Tasks\Version; use Utopia\Platform\Service; -use Appwrite\Platform\Tasks\EdgeSync; class Tasks extends Service { diff --git a/src/Appwrite/Platform/Services/Workers.php b/src/Appwrite/Platform/Services/Workers.php index 62a7fcf3fb..bb60ccc062 100644 --- a/src/Appwrite/Platform/Services/Workers.php +++ b/src/Appwrite/Platform/Services/Workers.php @@ -11,6 +11,9 @@ use Appwrite\Platform\Workers\Mails; use Appwrite\Platform\Workers\Messaging; use Appwrite\Platform\Workers\Migrations; +use Appwrite\Platform\Workers\SyncIn; +use Appwrite\Platform\Workers\SyncOutAggregation; +use Appwrite\Platform\Workers\SyncOutDelivery; use Appwrite\Platform\Workers\Usage; use Appwrite\Platform\Workers\UsageDump; use Appwrite\Platform\Workers\Webhooks; @@ -34,6 +37,9 @@ public function __construct() ->addAction(UsageDump::getName(), new UsageDump()) ->addAction(Usage::getName(), new Usage()) ->addAction(Migrations::getName(), new Migrations()) + ->addAction(SyncIn::getName(), new SyncIn()) + ->addAction(SyncOutAggregation::getName(), new SyncOutAggregation()) + ->addAction(SyncOutDelivery::getName(), new SyncOutDelivery()) ; } diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index ce30729960..945d9c1563 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -3,13 +3,14 @@ namespace Appwrite\Platform\Tasks; use Utopia\App; -use Utopia\Config\Config; -use Utopia\Platform\Action; use Utopia\CLI\Console; +use Utopia\Config\Config; +use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Database\Query; -use Utopia\Database\Database; +use Utopia\Platform\Action; use Utopia\Queue\Client; +use Utopia\System\System; class EdgeSync extends Action { @@ -23,24 +24,24 @@ public function __construct() $this ->desc('Schedules edge sync tasks') ->inject('dbForConsole') - ->inject('queueForEdgeSyncOut') - ->callback(fn (Database $dbForConsole, Client $queueForEdgeSyncOut) => $this->action($dbForConsole, $queueForEdgeSyncOut)); + ->inject('queueForSyncOutDelivery') + ->callback(fn (Database $dbForConsole, Client $queueForSyncOutDelivery) => $this->action($dbForConsole, $queueForSyncOutDelivery)); } - public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): void + public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): void { Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); $regions = array_filter( Config::getParam('regions', []), - fn ($region) => App::getEnv('_APP_REGION') !== $region + fn ($region) => System::getEnv('_APP_REGION', 'fra') !== $region && $region !== 'default', ARRAY_FILTER_USE_KEY ); $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $dbForConsole, $queueForEdgeSyncOut, $regions) { + Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery, $regions) { $time = DateTime::now(); Console::success("[{$time}] New task every {$interval} seconds"); @@ -49,42 +50,42 @@ public function action(Database $dbForConsole, Client $queueForEdgeSyncOut): voi $chunk = 0; $limit = 500; $sum = $limit; - $keys = []; - $found = false; while ($sum === $limit) { $chunk++; $count = 0; $results = $dbForConsole->find('syncs', [ - Query::equal('region', [App::getEnv('_APP_REGION')]), - Query::equal('target', [$code]), + Query::equal('sourceRegion', [System::getEnv('_APP_REGION', 'fra')]), Query::limit($limit) ]); $sum = count($results); if ($sum > 0) { - $found = true; - foreach ($results as $document) { - $key = $document->getAttribute('key'); - $keys[] = [ - 'type' => $document->getAttribute('type'), - 'key' => $key['key'] - ]; - $dbForConsole->deleteDocument('syncs', $document->getId()); + foreach ($results as $sync) { + + try { + if ($sync->getAttribute('status') === 200) { + $dbForConsole->deleteDocument('syncs', $sync->getId()); + unlink(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); + } else { + Console::log("[{$time}] Enqueueing {$sync->getId()} to {$sync->getAttribute('destRegion')}"); + + $sync->setAttribute('attempts', $sync->getAttribute('attempts')+1); + $dbForConsole->updateDocument('syncs', $sync->getId(), $sync); + + $queueForSyncOutDelivery + ->enqueue([ + 'syncId' => $sync->getId(), + ]); + } + + } catch(\Throwable $th) { + Console::log("[{$time}] Error: {$th->getMessage()}"); + } + $count++; } } - if (!empty($keys)) { - Console::info("[{$time}] Enqueueing chunk {$chunk}, {$count} keys to region {$code}"); - $queueForEdgeSyncOut - ->enqueue([ - 'region' => $code, - 'keys' => $keys - ]); - } - } - if (!$found) { - Console::info("[{$time}] No keys where found for region {$code}."); } } }, $interval); diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index 1cb96ad061..ff254dc2af 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -48,9 +48,9 @@ public function __construct() ->inject('queueForMails') ->inject('queueForEvents') ->inject('queueForFunctions') - ->inject('queueForEdgeSyncOut') + ->inject('queueForSyncOutAggregation') ->inject('log') - ->callback(fn (Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForEdgeSyncOut) => $this->action($message, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log, $queueForEdgeSyncOut)); + ->callback(fn (Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForSyncOutAggregation) => $this->action($message, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log, $queueForSyncOutAggregation)); } /** @@ -64,7 +64,7 @@ public function __construct() * @throws Throwable * @throws \Utopia\Database\Exception */ - public function action(Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log Client $queueForEdgeSyncOut): void + public function action(Message $message, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForSyncOutAggregation): void { $payload = $message->getPayload() ?? []; @@ -78,7 +78,7 @@ public function action(Message $message, Database $dbForConsole, Mail $queueForM $log->addTag('domain', $domain->get()); - $this->execute($domain, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log, $skipRenewCheck, $queueForEdgeSyncOut); + $this->execute($domain, $dbForConsole, $queueForMails, $queueForEvents, $queueForFunctions, $log, $queueForSyncOutAggregation, $skipRenewCheck); } /** @@ -87,12 +87,17 @@ public function action(Message $message, Database $dbForConsole, Mail $queueForM * @param Mail $queueForMails * @param Event $queueForEvents * @param Func $queueForFunctions + * @param Log $log + * @param Client $queueForSyncOutAggregation * @param bool $skipRenewCheck * @return void + * @throws Authorization + * @throws Conflict + * @throws Structure * @throws Throwable * @throws \Utopia\Database\Exception */ - private function execute(Domain $domain, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, bool $skipRenewCheck = false, Client $queueForEdgeSyncOut): void + private function execute(Domain $domain, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForSyncOutAggregation, bool $skipRenewCheck = false): void { /** * 1. Read arguments and validate domain @@ -177,7 +182,7 @@ private function execute(Domain $domain, Database $dbForConsole, Mail $queueForM // Enqueue certificate for regional sync $filename = APP_STORAGE_CERTIFICATES . '/' . $domain . '.tar.gz'; if (file_exists($filename)) { - $queueForEdgeSyncOut->enqueue([ + $queueForSyncOutAggregation->enqueue([ 'type' => 'certificate', 'key' => [ 'domain' => $domain, diff --git a/src/Appwrite/Platform/Workers/sync-in.php b/src/Appwrite/Platform/Workers/SyncIn.php similarity index 65% rename from src/Appwrite/Platform/Workers/sync-in.php rename to src/Appwrite/Platform/Workers/SyncIn.php index 385d2da147..1215457cc6 100644 --- a/src/Appwrite/Platform/Workers/sync-in.php +++ b/src/Appwrite/Platform/Workers/SyncIn.php @@ -1,21 +1,50 @@ job() - ->inject('message') - ->inject('cache') - ->action(function (Message $message, Cache $cache) { - $payload = $message->getPayload(); +class SyncIn extends Action +{ + public static function getName(): string + { + return 'sync-in'; + } + + /** + * @throws Exception + */ + public function __construct() + { + $this + ->desc('Sync in worker') + ->inject('message') + ->inject('cache') + ->callback(fn (Message $message, Cache $cache) => $this->action($message, $cache)); + } + + + /** + * @param Message $message + * @param Cache $cache + * @throws Exception + */ + public function action(Message $message, Cache $cache): void + { + $payload = $message->getPayload() ?? []; + + if (empty($payload)) { + throw new Exception('Missing payload'); + } + $type = $payload['type']; - $key = $payload['key']; + $key = $payload['key']; $time = DateTime::now(); switch ($type) { @@ -45,7 +74,7 @@ mkdir($path, 0755, true); } - $result = file_put_contents($path . '/' . $filename, base64_decode($key['contents'])); + $result = file_put_contents($path . '/' . $filename, base64_decode($key['contents'])); if (empty($result)) { Console::error('Can not write ' . $key['filename']); break; @@ -61,12 +90,5 @@ default: break; } - }); - -$server - ->workerStart() - ->action(function () { - Console::success("[" . App::getEnv('_APP_REGION', 'nyc1') . "] edge sync-in worker Started"); - }); - -$server->start(); + } +} diff --git a/src/Appwrite/Platform/Workers/SyncOutAggregation.php b/src/Appwrite/Platform/Workers/SyncOutAggregation.php new file mode 100644 index 0000000000..7f5c9952e8 --- /dev/null +++ b/src/Appwrite/Platform/Workers/SyncOutAggregation.php @@ -0,0 +1,116 @@ +desc('Sync out aggregation worker') + ->inject('message') + ->inject('dbForConsole') + ->inject('queueForSyncOutDelivery') + ->callback(fn (Message $message, Database $dbForConsole, Client $queueForSyncOutDelivery) => $this->action($message, $dbForConsole, $queueForSyncOutDelivery)); + } + + + /** + * @param Message $message + * @param Database $dbForConsole + * @param Client $queueForSyncOutDelivery + * @throws Exception + * @throws JsonException + * @throws \Utopia\Database\Exception + * @throws Authorization + * @throws Structure + */ + public function action(Message $message, Database $dbForConsole, Client $queueForSyncOutDelivery): void + { + + $payload = $message->getPayload() ?? []; + + if (empty($payload)) { + throw new Exception('Missing payload'); + } + + if (!empty($payload['key'])) { + $this->keys[] = [ + 'time' => time(), + 'type' => $payload['type'], + 'key' => $payload['key'], + ]; + } + + $destRegions = []; + $currentRegion = System::getEnv('_APP_REGION', 'fra'); + foreach(Config::getParam('regions', []) as $destRegion) { + if($currentRegion !== $destRegion['$id'] && $destRegion['disabled'] === false) { + $destRegions[] = $destRegion['$id']; + } + } + + if ( + count($this->keys) >= self::KEYS_THRESHOLD || + (time() - $this->lastTriggeredTime > self::AGGREGATION_INTERVAL) + ) { + $chunk = array_slice($this->keys, 0, self::KEYS_THRESHOLD, true); + array_splice($this->keys, 0, self::KEYS_THRESHOLD); + + $filename = (string)time(); + $chunk = json_encode($chunk, flags: JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT); + $path = APP_STORAGE_SYNCS . '/' . $filename . '.log'; + + Console::log('Writing log '. $path); + + if (\file_put_contents($path, $chunk)) { + foreach($destRegions as $destRegion) { + Console::log('Creating documents to '. $destRegion); + $sync = $dbForConsole->createDocument('syncs', new Document([ + 'sourceRegion' => $currentRegion, + 'destRegion' => $destRegion, + 'filename' => $filename, + 'logCreatedAt' => DateTime::now() + ])); + + $queueForSyncOutDelivery + ->enqueue([ + 'syncId' => $sync->getId(), + ]); + + $this->lastTriggeredTime = time(); + } + } else { + Console::error('Failed to save log : ' . $path); + } + } + } +} diff --git a/src/Appwrite/Platform/Workers/SyncOutDelivery.php b/src/Appwrite/Platform/Workers/SyncOutDelivery.php new file mode 100644 index 0000000000..bf85031654 --- /dev/null +++ b/src/Appwrite/Platform/Workers/SyncOutDelivery.php @@ -0,0 +1,127 @@ +desc('Sync out delivery worker') + ->inject('message') + ->inject('dbForConsole') + ->callback(fn (Message $message, Database $dbForConsole) => $this->action($message, $dbForConsole)); + } + + + /** + * @param Message $message + * @param Database $dbForConsole + * @throws Exception + */ + public function action(Message $message, Database $dbForConsole): void + { + + $payload = $message->getPayload() ?? []; + + if (empty($payload)) { + throw new Exception('Missing payload'); + } + + if (!empty($payload['syncId'])) { + try { + $sync = $dbForConsole->getDocument('syncs', $payload['syncId']); + //$regions = Config::getParam('regions', []); + $destRegion = $sync->getAttribute('destRegion'); + $chunk = file_get_contents(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); + $jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); + $token = $jwt->encode([]); + //$status = $this->send($regions[$destRegion]['domain'] . '/v1/edge/sync', $token, json_decode($chunk)); + $status = $this->send('http://appwrite/v1/edge/sync', $token, json_decode($chunk)); + Console::log('[' . DateTime::now() . '] Request ' . $sync->getId() . ' to ' . $destRegion . ' returned status ' . $status); + + $sync->setAttribute('logSentAt', DateTime::now()); + $sync->setAttribute('status', $status); + $dbForConsole->updateDocument('syncs', $sync->getId(), $sync); + } catch (\Throwable $th) { + Console::log('[' . DateTime::now() . '] Error: ' .$th->getMessage()); + } + } + } + + /** + * @param string $url + * @param string $token + * @param array data + * @return int + */ + public function send(string $url, string $token, array $data): int + { + + $boundary = uniqid(); + $delimiter = '-------------' . $boundary; + $payload = ''; + $eol = "\r\n"; + + console::warning('Sending ' . count($data) . 'to ' . $url); + + foreach ($data as $keys) { + $payload .= "--" . $delimiter . $eol + . 'Content-Disposition: form-data; name="keys[]"' . $eol . $eol + . json_encode($keys) . $eol; + } + $payload .= "--" . $delimiter . "--" . $eol; + $status = 404; + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $token, + 'Origin-edge-url: ' . App::getEnv('_APP_REGION'), + 'Content-type: multipart/form-data; boundary=' . $delimiter, + 'Content-Length: ' . strlen($payload) + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); + //curl_setopt($ch, CURLOPT_VERBOSE, true); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); + + for ($attempts = 0; $attempts < self::MAX_SEND_ATTEMPTS; $attempts++) { + curl_exec($ch); + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($status === 200) { + return $status; + } + + sleep(1); + } + + curl_close($ch); + + return $status; + } +} diff --git a/src/Appwrite/Platform/Workers/sync-out.php b/src/Appwrite/Platform/Workers/sync-out.php deleted file mode 100644 index faf7fa29ef..0000000000 --- a/src/Appwrite/Platform/Workers/sync-out.php +++ /dev/null @@ -1,186 +0,0 @@ - App::getEnv('_APP_REGION') !== $region - && $region !== 'default', - ARRAY_FILTER_USE_KEY -); - -$stack = [ - 'regions' => $regions, - 'keys' => [], -]; -$failures = []; - -const CHUNK_MAX_KEYS = 500; -const MAX_CURL_SEND_ATTEMPTS = 4; - -/** - * @param string $url - * @param string $token - * @param array data - * @return int - */ -function call(string $url, string $token, array $data): int -{ - - $boundary = uniqid(); - $delimiter = '-------------' . $boundary; - $payload = ''; - $eol = "\r\n"; - console::warning('Sending ' . count($data) . 'to ' . $url); - var_dump($data); - foreach ($data as $keys) { - $payload .= "--" . $delimiter . $eol - . 'Content-Disposition: form-data; name="keys[]"' . $eol . $eol - . json_encode($keys) . $eol; - } - $payload .= "--" . $delimiter . "--" . $eol; - - $status = 404; - - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_HTTPHEADER, [ - 'Authorization: Bearer ' . $token, - 'Origin-edge-url: ' . App::getEnv('_APP_REGION'), - 'Content-type: multipart/form-data; boundary=' . $delimiter, - 'Content-Length: ' . strlen($payload) - ]); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 5); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); - curl_setopt($ch, CURLOPT_VERBOSE, true); - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - - for ($attempts = 0; $attempts < MAX_CURL_SEND_ATTEMPTS; $attempts++) { - curl_exec($ch); - $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - if ($status === 200) { - return $status; - } - - sleep(1); - } - - curl_close($ch); - - return $status; -} - - -/** - * @throws Authorization - * @throws Structure - * @throws Exception|\Exception - */ -function handle($dbForConsole, $regions, $data): void -{ - - $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); - $token = $jwt->encode([]); - - foreach ($regions as $code => $region) { - $time = DateTime::now(); - $status = call($region['domain'] . '/v1/edge/sync', $token, $data); - if ($status !== Response::STATUS_CODE_OK) { - Console::error("[{$time}] Request to {$code} has failed"); - foreach ($data as $keys) { - $dbForConsole->createDocument('syncs', new Document([ - 'region' => App::getEnv('_APP_REGION'), - 'target' => $code, - 'type' => $keys['type'], - 'key' => ['key' => $keys['key']], - 'status' => $status, - ])); - } - } - } -} - -$server->job() - ->inject('message') - ->action(function (Message $message) use (&$stack, &$failures) { - - $payload = $message->getPayload() ?? []; - - //Get failed requests - if (!empty($payload['region']) && !empty($payload['keys'])) { - $regions = array_filter( - Config::getParam('regions', []), - fn ($region) => $payload['region'] === $region, - ARRAY_FILTER_USE_KEY - ); - - $failures[] = [ - 'regions' => $regions, - 'keys' => $payload['keys'] - ]; - - return; - } - - if (empty($payload['type'])) { - return; - } - - if (!empty($payload['key'])) { - $stack['keys'][] = [ - 'type' => $payload['type'], - 'key' => $payload['key'], - ]; - } - }); - -$server - ->workerStart() - ->inject('dbForConsole') - ->action(function ($dbForConsole) use (&$stack, &$failures) { - - Timer::tick(5000, function () use ($dbForConsole, &$stack, &$failures) { - $time = DateTime::now(); - - if (empty($stack['keys']) && count($failures) === 0) { - Console::info("[{$time}] Stack is empty"); - return; - } - - //Send failed requests - if (count($failures) > 0) { - $i = 0; - while ($i < count($failures)) { - $failure = array_shift($failures); - Console::info("[{$time}] ReSending " . count($failure['keys']) . " to " . key($failure['regions'])); - handle($dbForConsole, $failure['regions'], $failure['keys']); - $i++; - } - return; - } - - $chunk = array_slice($stack['keys'], 0, CHUNK_MAX_KEYS, true); - array_splice($stack['keys'], 0, CHUNK_MAX_KEYS); - Console::log("[{$time}] Sending " . count($chunk) . " remains " . count($stack['keys'])); - handle($dbForConsole, $stack['regions'], $chunk); - }); - Console::success("[" . App::getEnv('_APP_REGION') . "] edge sync-out worker Started"); - }); - - $server->start(); diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index cff35aee50..3d641363c2 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -39,6 +39,7 @@ use Appwrite\Utopia\Response\Model\Deployment; use Appwrite\Utopia\Response\Model\Detection; use Appwrite\Utopia\Response\Model\Document as ModelDocument; +use Appwrite\Utopia\Response\Model\EdgeSync; use Appwrite\Utopia\Response\Model\Error; use Appwrite\Utopia\Response\Model\ErrorDev; use Appwrite\Utopia\Response\Model\Execution; @@ -100,7 +101,6 @@ use Appwrite\Utopia\Response\Model\UsageUsers; use Appwrite\Utopia\Response\Model\User; use Appwrite\Utopia\Response\Model\Variable; -use Appwrite\Utopia\Response\Model\EdgeSync; use Appwrite\Utopia\Response\Model\Webhook; use Exception; use Swoole\Http\Response as SwooleHTTPResponse; From 749e70e144613737be73fdd9675d0e2fbd786471 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:12:18 +0300 Subject: [PATCH 75/87] updates to multi region sync --- app/config/collections.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index f0ce987c2d..e6ab10000a 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4218,9 +4218,9 @@ ], 'indexes' => [ [ - '$id' => ID::custom('_key_sourceRegion_destRegion_logCreatedAt_status'), + '$id' => ID::custom('_key_sourceRegion'), 'type' => Database::INDEX_KEY, - 'attributes' => ['sourceRegion', 'destRegion','logCreatedAt', 'status'], + 'attributes' => ['sourceRegion'], 'lengths' => [], 'orders' => [], ], From ff1e0652d7a99ced0c268d6c43ea1efbb15b2fcf Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:12:59 +0300 Subject: [PATCH 76/87] updates to multi region sync --- app/cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/cli.php b/app/cli.php index 96340869e5..ab6b99a99e 100644 --- a/app/cli.php +++ b/app/cli.php @@ -169,7 +169,7 @@ CLI::setResource('SyncOutAggregation', function (Connection $queue) { return new Client('v1-sync-out-aggregation', $queue); }, ['queue']); -CLI::setResource('SyncOut~Delivery', function (Connection $queue) { +CLI::setResource('SyncOutDelivery', function (Connection $queue) { return new Client('v1-sync-out-delivery', $queue); }, ['queue']); CLI::setResource('logError', function (Registry $register) { From cf713dd8a096eb1bbaf5e9d3107ad2f73a455398 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:16:32 +0300 Subject: [PATCH 77/87] updates to multi region sync --- app/cli.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/cli.php b/app/cli.php index ab6b99a99e..89467c708d 100644 --- a/app/cli.php +++ b/app/cli.php @@ -166,10 +166,10 @@ CLI::setResource('queueForCertificates', function (Connection $queue) { return new Certificate($queue); }, ['queue']); -CLI::setResource('SyncOutAggregation', function (Connection $queue) { +CLI::setResource('queueForSyncOutAggregation', function (Connection $queue) { return new Client('v1-sync-out-aggregation', $queue); }, ['queue']); -CLI::setResource('SyncOutDelivery', function (Connection $queue) { +CLI::setResource('queueForSyncOutDelivery', function (Connection $queue) { return new Client('v1-sync-out-delivery', $queue); }, ['queue']); CLI::setResource('logError', function (Registry $register) { From c78e158dbc83021595da8bece8007ea753ce5d97 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:20:59 +0300 Subject: [PATCH 78/87] updates to multi region sync --- src/Appwrite/Platform/Tasks/EdgeSync.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index 945d9c1563..b052251f68 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -33,20 +33,12 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); - $regions = array_filter( - Config::getParam('regions', []), - fn ($region) => System::getEnv('_APP_REGION', 'fra') !== $region - && $region !== 'default', - ARRAY_FILTER_USE_KEY - ); - $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); - Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery, $regions) { + Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery) { $time = DateTime::now(); Console::success("[{$time}] New task every {$interval} seconds"); - foreach ($regions as $code => $region) { $chunk = 0; $limit = 500; $sum = $limit; @@ -61,7 +53,6 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): $sum = count($results); if ($sum > 0) { foreach ($results as $sync) { - try { if ($sync->getAttribute('status') === 200) { $dbForConsole->deleteDocument('syncs', $sync->getId()); @@ -87,7 +78,7 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): } } - } + }, $interval); } } From 71801c9f0ece50c41bd6ad84e164dd6fc404086e Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:22:24 +0300 Subject: [PATCH 79/87] updates to multi region sync --- src/Appwrite/Platform/Tasks/EdgeSync.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index b052251f68..fc2f427804 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -57,6 +57,7 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): if ($sync->getAttribute('status') === 200) { $dbForConsole->deleteDocument('syncs', $sync->getId()); unlink(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); + Console::log("[{$time}] Deleting {$sync->getId()}"); } else { Console::log("[{$time}] Enqueueing {$sync->getId()} to {$sync->getAttribute('destRegion')}"); From bb0448d0c6edaeff3dded3ada3f50d2706e909d0 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:26:34 +0300 Subject: [PATCH 80/87] updates to multi region sync --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 53282f18e7..dc0883723b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -803,6 +803,7 @@ services: volumes: - ./app:/usr/src/code/app - ./src:/usr/src/code/src + - appwrite-syncs:/storage/syncs:rw depends_on: - mariadb - redis From 126dd5a58a6fe4eb7cea614c5a7b3c6bcd11c680 Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:27:29 +0300 Subject: [PATCH 81/87] updates to multi region sync --- src/Appwrite/Platform/Tasks/EdgeSync.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index fc2f427804..e265f17386 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -37,8 +37,6 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery) { $time = DateTime::now(); - Console::success("[{$time}] New task every {$interval} seconds"); - $chunk = 0; $limit = 500; $sum = $limit; From f5fad930285d25117f4cef21b3499eacfb7be7ea Mon Sep 17 00:00:00 2001 From: shimon Date: Tue, 4 Jun 2024 17:32:52 +0300 Subject: [PATCH 82/87] updates to multi region sync --- src/Appwrite/Platform/Tasks/EdgeSync.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php index e265f17386..f638da1460 100644 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ b/src/Appwrite/Platform/Tasks/EdgeSync.php @@ -33,10 +33,12 @@ public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): Console::title('Edge-sync V1'); Console::success(APP_NAME . ' Edge-sync v1 has started'); - $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '180'); + $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '60'); Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery) { $time = DateTime::now(); + Console::success("[{$time}] New task every {$interval} seconds"); + $chunk = 0; $limit = 500; $sum = $limit; From b030c02a8cc0c0f16f51d98e865ce09e746918ea Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 5 Jun 2024 10:41:42 +0300 Subject: [PATCH 83/87] updates to multi region sync --- Dockerfile | 2 +- app/config/services.php | 10 +-- app/controllers/api/{edge.php => region.php} | 10 +-- bin/edge-sync | 3 - bin/region-sync | 3 + docker-compose.yml | 6 +- src/Appwrite/Platform/Services/Tasks.php | 4 +- src/Appwrite/Platform/Tasks/EdgeSync.php | 85 ------------------- src/Appwrite/Platform/Tasks/RegionSync.php | 84 ++++++++++++++++++ .../Platform/Workers/SyncOutDelivery.php | 8 +- src/Appwrite/Utopia/Response.php | 6 +- .../Model/{EdgeSync.php => RegionSync.php} | 4 +- 12 files changed, 112 insertions(+), 113 deletions(-) rename app/controllers/api/{edge.php => region.php} (90%) delete mode 100644 bin/edge-sync create mode 100644 bin/region-sync delete mode 100644 src/Appwrite/Platform/Tasks/EdgeSync.php create mode 100644 src/Appwrite/Platform/Tasks/RegionSync.php rename src/Appwrite/Utopia/Response/Model/{EdgeSync.php => RegionSync.php} (87%) diff --git a/Dockerfile b/Dockerfile index 5015ec4504..16fb77c434 100755 --- a/Dockerfile +++ b/Dockerfile @@ -80,7 +80,7 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/maintenance && \ chmod +x /usr/local/bin/migrate && \ chmod +x /usr/local/bin/realtime && \ - chmod +x /usr/local/bin/edge-sync && \ + chmod +x /usr/local/bin/region-sync && \ chmod +x /usr/local/bin/schedule-functions && \ chmod +x /usr/local/bin/schedule-messages && \ chmod +x /usr/local/bin/sdks && \ diff --git a/app/config/services.php b/app/config/services.php index 29fac795d5..59f304a2c8 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -265,11 +265,11 @@ 'icon' => '/images/services/messaging.png', ], 'syncs' => [ - 'key' => 'edge', - 'name' => 'edge', - 'subtitle' => 'Appwrite\'s cache edge sync Endpoint', - 'description' => 'Cache edge sync Endpoint', - 'controller' => 'api/edge.php', + 'key' => 'region', + 'name' => 'region', + 'subtitle' => 'Appwrite\'s region resources sync Endpoint', + 'description' => 'region resources sync Endpoint', + 'controller' => 'api/region.php', 'sdk' => false, 'docs' => false, 'docsUrl' => '', diff --git a/app/controllers/api/edge.php b/app/controllers/api/region.php similarity index 90% rename from app/controllers/api/edge.php rename to app/controllers/api/region.php index 17531d1563..28c4378023 100644 --- a/app/controllers/api/edge.php +++ b/app/controllers/api/region.php @@ -14,7 +14,7 @@ use Utopia\Validator\Text; App::init() - ->groups(['edge']) + ->groups(['region']) ->inject('request') ->action(function (Request $request) { @@ -28,9 +28,9 @@ } }); -App::post('/v1/edge/sync') +App::post('/v1/region/sync') ->desc('Purge cache keys') - ->groups(['edge']) + ->groups(['region']) ->label('scope', 'public') ->param('keys', '', new ArrayList(new Text(9012), 600), 'Cache keys. an array containing alphanumerical cache keys') ->inject('request') @@ -42,7 +42,7 @@ throw new Exception(Exception::KEY_NOT_FOUND); } - $originEdgeUrl = $request->getHeader('origin-edge-url'); + $originEdgeUrl = $request->getHeader('origin-region-url'); $time = DateTime::now(); var_dump('[' . $time . '] incoming request from:' . $originEdgeUrl); @@ -59,5 +59,5 @@ $response->dynamic(new Document([ 'keys' => $keys - ]), Response::MODEL_EDGE_SYNC); + ]), Response::MODEL_REGION_SYNC); }); diff --git a/bin/edge-sync b/bin/edge-sync deleted file mode 100644 index b1ffc7647a..0000000000 --- a/bin/edge-sync +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php /usr/src/code/app/cli.php edge-sync $@ \ No newline at end of file diff --git a/bin/region-sync b/bin/region-sync new file mode 100644 index 0000000000..c1cbc8ba9d --- /dev/null +++ b/bin/region-sync @@ -0,0 +1,3 @@ +#!/bin/sh + +php /usr/src/code/app/cli.php region-sync $@ \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index dc0883723b..9df7ced06e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -793,10 +793,10 @@ services: - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_MAINTENANCE_DELAY - appwrite-task-edge-sync: - entrypoint: edge-sync + appwrite-task-region-sync: + entrypoint: region-sync <<: *x-logging - container_name: appwrite-task-edge-sync + container_name: appwrite-task-region-sync image: appwrite-dev networks: - appwrite diff --git a/src/Appwrite/Platform/Services/Tasks.php b/src/Appwrite/Platform/Services/Tasks.php index 6bffbdb320..f96d7b761e 100644 --- a/src/Appwrite/Platform/Services/Tasks.php +++ b/src/Appwrite/Platform/Services/Tasks.php @@ -3,12 +3,12 @@ namespace Appwrite\Platform\Services; use Appwrite\Platform\Tasks\Doctor; -use Appwrite\Platform\Tasks\EdgeSync; use Appwrite\Platform\Tasks\Install; use Appwrite\Platform\Tasks\Maintenance; use Appwrite\Platform\Tasks\Migrate; use Appwrite\Platform\Tasks\QueueCount; use Appwrite\Platform\Tasks\QueueRetry; +use Appwrite\Platform\Tasks\RegionSync; use Appwrite\Platform\Tasks\ScheduleFunctions; use Appwrite\Platform\Tasks\ScheduleMessages; use Appwrite\Platform\Tasks\SDKs; @@ -39,7 +39,7 @@ public function __construct() ->addAction(Upgrade::getName(), new Upgrade()) ->addAction(Vars::getName(), new Vars()) ->addAction(Version::getName(), new Version()) - ->addAction(EdgeSync::getName(), new EdgeSync()); + ->addAction(RegionSync::getName(), new RegionSync()); ; } diff --git a/src/Appwrite/Platform/Tasks/EdgeSync.php b/src/Appwrite/Platform/Tasks/EdgeSync.php deleted file mode 100644 index f638da1460..0000000000 --- a/src/Appwrite/Platform/Tasks/EdgeSync.php +++ /dev/null @@ -1,85 +0,0 @@ -desc('Schedules edge sync tasks') - ->inject('dbForConsole') - ->inject('queueForSyncOutDelivery') - ->callback(fn (Database $dbForConsole, Client $queueForSyncOutDelivery) => $this->action($dbForConsole, $queueForSyncOutDelivery)); - } - - public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): void - { - Console::title('Edge-sync V1'); - Console::success(APP_NAME . ' Edge-sync v1 has started'); - - $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '60'); - Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery) { - $time = DateTime::now(); - - Console::success("[{$time}] New task every {$interval} seconds"); - - $chunk = 0; - $limit = 500; - $sum = $limit; - while ($sum === $limit) { - $chunk++; - $count = 0; - $results = $dbForConsole->find('syncs', [ - Query::equal('sourceRegion', [System::getEnv('_APP_REGION', 'fra')]), - Query::limit($limit) - ]); - - $sum = count($results); - if ($sum > 0) { - foreach ($results as $sync) { - try { - if ($sync->getAttribute('status') === 200) { - $dbForConsole->deleteDocument('syncs', $sync->getId()); - unlink(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); - Console::log("[{$time}] Deleting {$sync->getId()}"); - } else { - Console::log("[{$time}] Enqueueing {$sync->getId()} to {$sync->getAttribute('destRegion')}"); - - $sync->setAttribute('attempts', $sync->getAttribute('attempts')+1); - $dbForConsole->updateDocument('syncs', $sync->getId(), $sync); - - $queueForSyncOutDelivery - ->enqueue([ - 'syncId' => $sync->getId(), - ]); - } - - } catch(\Throwable $th) { - Console::log("[{$time}] Error: {$th->getMessage()}"); - } - - $count++; - } - } - - } - - }, $interval); - } -} diff --git a/src/Appwrite/Platform/Tasks/RegionSync.php b/src/Appwrite/Platform/Tasks/RegionSync.php new file mode 100644 index 0000000000..2648b53fc0 --- /dev/null +++ b/src/Appwrite/Platform/Tasks/RegionSync.php @@ -0,0 +1,84 @@ +desc('Region sync task, resend failed payloads and delete successful ones') + ->inject('dbForConsole') + ->inject('queueForSyncOutDelivery') + ->callback(fn (Database $dbForConsole, Client $queueForSyncOutDelivery) => $this->action($dbForConsole, $queueForSyncOutDelivery)); + } + + public function action(Database $dbForConsole, Client $queueForSyncOutDelivery): void + { + Console::title('Edge-sync V1'); + Console::success(APP_NAME . ' Region sync v1 has started'); + + $interval = (int) App::getEnv('_APP_SYNC_EDGE_INTERVAL', '20'); + Console::loop(function () use ($interval, $dbForConsole, $queueForSyncOutDelivery) { + $time = DateTime::now(); + + Console::success("[{$time}] New task every {$interval} seconds"); + + $chunk = 0; + $limit = 500; + $sum = $limit; + while ($sum === $limit) { + $chunk++; + $count = 0; + $results = $dbForConsole->find('syncs', [ + Query::equal('sourceRegion', [System::getEnv('_APP_REGION', 'fra')]), + Query::limit($limit) + ]); + + $sum = count($results); + if ($sum > 0) { + foreach ($results as $sync) { + try { + if ($sync->getAttribute('status') === 200) { + $dbForConsole->deleteDocument('syncs', $sync->getId()); + unlink(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); + Console::log("[{$time}] Deleting {$sync->getId()}"); + } else { + Console::log("[{$time}] Enqueueing {$sync->getId()} to {$sync->getAttribute('destRegion')}"); + + $sync->setAttribute('attempts', $sync->getAttribute('attempts') + 1); + $dbForConsole->updateDocument('syncs', $sync->getId(), $sync); + + $queueForSyncOutDelivery + ->enqueue([ + 'syncId' => $sync->getId(), + ]); + } + + } catch(\Throwable $th) { + Console::log("[{$time}] Error: {$th->getMessage()}"); + } + + $count++; + } + } + + } + + }, $interval); + } +} diff --git a/src/Appwrite/Platform/Workers/SyncOutDelivery.php b/src/Appwrite/Platform/Workers/SyncOutDelivery.php index bf85031654..1c37ff919c 100644 --- a/src/Appwrite/Platform/Workers/SyncOutDelivery.php +++ b/src/Appwrite/Platform/Workers/SyncOutDelivery.php @@ -29,7 +29,7 @@ public function __construct() { $this - ->desc('Sync out delivery worker') + ->desc('Region Syncs out worker') ->inject('message') ->inject('dbForConsole') ->callback(fn (Message $message, Database $dbForConsole) => $this->action($message, $dbForConsole)); @@ -58,8 +58,8 @@ public function action(Message $message, Database $dbForConsole): void $chunk = file_get_contents(APP_STORAGE_SYNCS . '/' . $sync->getAttribute('filename') . '.log'); $jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 600, 10); $token = $jwt->encode([]); - //$status = $this->send($regions[$destRegion]['domain'] . '/v1/edge/sync', $token, json_decode($chunk)); - $status = $this->send('http://appwrite/v1/edge/sync', $token, json_decode($chunk)); + //$status = $this->send($regions[$destRegion]['domain'] . '/v1/region/sync', $token, json_decode($chunk)); + $status = $this->send('http://appwrite/v1/region/sync', $token, json_decode($chunk)); Console::log('[' . DateTime::now() . '] Request ' . $sync->getId() . ' to ' . $destRegion . ' returned status ' . $status); $sync->setAttribute('logSentAt', DateTime::now()); @@ -97,7 +97,7 @@ public function send(string $url, string $token, array $data): int $ch = curl_init($url); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, - 'Origin-edge-url: ' . App::getEnv('_APP_REGION'), + 'Origin-region-url: ' . App::getEnv('_APP_REGION'), 'Content-type: multipart/form-data; boundary=' . $delimiter, 'Content-Length: ' . strlen($payload) ]); diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 3d641363c2..d12fc5d364 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -39,7 +39,6 @@ use Appwrite\Utopia\Response\Model\Deployment; use Appwrite\Utopia\Response\Model\Detection; use Appwrite\Utopia\Response\Model\Document as ModelDocument; -use Appwrite\Utopia\Response\Model\EdgeSync; use Appwrite\Utopia\Response\Model\Error; use Appwrite\Utopia\Response\Model\ErrorDev; use Appwrite\Utopia\Response\Model\Execution; @@ -80,6 +79,7 @@ use Appwrite\Utopia\Response\Model\Project; use Appwrite\Utopia\Response\Model\Provider; use Appwrite\Utopia\Response\Model\ProviderRepository; +use Appwrite\Utopia\Response\Model\RegionSync; use Appwrite\Utopia\Response\Model\Rule; use Appwrite\Utopia\Response\Model\Runtime; use Appwrite\Utopia\Response\Model\Session; @@ -276,7 +276,7 @@ class Response extends SwooleResponse public const MODEL_VCS = 'vcs'; public const MODEL_SMS_TEMPLATE = 'smsTemplate'; public const MODEL_EMAIL_TEMPLATE = 'emailTemplate'; - public const MODEL_EDGE_SYNC = 'edgeSync'; + public const MODEL_REGION_SYNC = 'regionSync'; // Health public const MODEL_HEALTH_STATUS = 'healthStatus'; @@ -458,7 +458,7 @@ public function __construct(SwooleHTTPResponse $response) ->setModel(new Migration()) ->setModel(new MigrationReport()) ->setModel(new MigrationFirebaseProject()) - ->setModel(new EdgeSync()) + ->setModel(new RegionSync()) // Tests (keep last) ->setModel(new Mock()); diff --git a/src/Appwrite/Utopia/Response/Model/EdgeSync.php b/src/Appwrite/Utopia/Response/Model/RegionSync.php similarity index 87% rename from src/Appwrite/Utopia/Response/Model/EdgeSync.php rename to src/Appwrite/Utopia/Response/Model/RegionSync.php index dde34d3bfc..5c7e980502 100644 --- a/src/Appwrite/Utopia/Response/Model/EdgeSync.php +++ b/src/Appwrite/Utopia/Response/Model/RegionSync.php @@ -5,7 +5,7 @@ use Appwrite\Utopia\Response; use Appwrite\Utopia\Response\Model; -class EdgeSync extends Model +class RegionSync extends Model { public function __construct() { @@ -13,7 +13,7 @@ public function __construct() $this ->addRule('keys', [ 'type' => self::TYPE_STRING, - 'description' => 'Cache keys array to be purged.', + 'description' => 'Resources keys array to be purged.', 'default' => '', 'example' => '["cache-console:_metadata:users", "cache-console:_metadata:buckets"]', ]) From 55a22e642bc7207478db2e872f01ba863e6335f0 Mon Sep 17 00:00:00 2001 From: shimon Date: Wed, 5 Jun 2024 10:44:19 +0300 Subject: [PATCH 84/87] updates to multi region sync --- src/Appwrite/Platform/Workers/SyncOutDelivery.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Appwrite/Platform/Workers/SyncOutDelivery.php b/src/Appwrite/Platform/Workers/SyncOutDelivery.php index 1c37ff919c..5c3d49bd1e 100644 --- a/src/Appwrite/Platform/Workers/SyncOutDelivery.php +++ b/src/Appwrite/Platform/Workers/SyncOutDelivery.php @@ -6,7 +6,6 @@ use Appwrite\Extend\Exception; use Utopia\App; use Utopia\CLI\Console; -use Utopia\Config\Config; use Utopia\Database\Database; use Utopia\Database\DateTime; use Utopia\Platform\Action; From 1bb93bcae701c31894efeb1abc9b29383c78975a Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 13 Jun 2024 14:16:20 +0300 Subject: [PATCH 85/87] response fix --- src/Appwrite/Utopia/Response/Model/RegionSync.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Appwrite/Utopia/Response/Model/RegionSync.php b/src/Appwrite/Utopia/Response/Model/RegionSync.php index 5c7e980502..d568016447 100644 --- a/src/Appwrite/Utopia/Response/Model/RegionSync.php +++ b/src/Appwrite/Utopia/Response/Model/RegionSync.php @@ -38,6 +38,6 @@ public function getName(): string */ public function getType(): string { - return Response::MODEL_EDGE_SYNC; + return Response::MODEL_REGION_SYNC; } } From 8545190fcd1ee8b2af341be3a4c130b5627799a9 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 17 Jun 2024 20:05:34 +0300 Subject: [PATCH 86/87] Delete user update --- composer.lock | 100 +++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/composer.lock b/composer.lock index 59f6390938..7973fa57ab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "52996be154364fe3ed18dfd7764d8d18", + "content-hash": "eb71c276dc4c579c30d72b8ec4ff9f08", "packages": [ { "name": "adhocore/jwt", @@ -1427,16 +1427,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.37.0", + "version": "0.37.1", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062" + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/2de5c12886cbd516e511e559afdd9e615d871062", - "reference": "2de5c12886cbd516e511e559afdd9e615d871062", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981", + "reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981", "shasum": "" }, "require": { @@ -1470,9 +1470,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.37.0" + "source": "https://github.com/utopia-php/abuse/tree/0.37.1" }, - "time": "2024-03-06T21:20:27+00:00" + "time": "2024-06-05T18:03:59+00:00" }, { "name": "utopia-php/analytics", @@ -1522,16 +1522,16 @@ }, { "name": "utopia-php/audit", - "version": "0.39.0", + "version": "0.39.1", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c" + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/f0bc15012e05cc0b9dde012ab27d25f193768a2c", - "reference": "f0bc15012e05cc0b9dde012ab27d25f193768a2c", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2", + "reference": "7ea91e0ceea7b94293612fea94022b73315677c2", "shasum": "" }, "require": { @@ -1563,9 +1563,9 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.39.0" + "source": "https://github.com/utopia-php/audit/tree/0.39.1" }, - "time": "2024-03-06T21:20:37+00:00" + "time": "2024-06-05T19:28:22+00:00" }, { "name": "utopia-php/cache", @@ -1719,23 +1719,23 @@ }, { "name": "utopia-php/database", - "version": "0.49.11", + "version": "0.49.12", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030" + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/4f4b35d99ecdee971c3042279bb1ac8264825030", - "reference": "4f4b35d99ecdee971c3042279bb1ac8264825030", + "url": "https://api.github.com/repos/utopia-php/database/zipball/45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", + "reference": "45def2f7c6bc5f631dbb67e5df0e8e7331af5f63", "shasum": "" }, "require": { "ext-mbstring": "*", "ext-pdo": "*", "php": ">=8.0", - "utopia-php/cache": "0.9.*", + "utopia-php/cache": "0.10.*", "utopia-php/framework": "0.33.*", "utopia-php/mongo": "0.3.*" }, @@ -1769,9 +1769,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/0.49.11" + "source": "https://github.com/utopia-php/database/tree/0.49.12" }, - "time": "2024-05-30T12:40:27+00:00" + "time": "2024-06-05T16:52:59+00:00" }, { "name": "utopia-php/domains", @@ -2327,16 +2327,16 @@ }, { "name": "utopia-php/platform", - "version": "0.5.2", + "version": "0.7.0", "source": { "type": "git", "url": "https://github.com/utopia-php/platform.git", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3" + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/platform/zipball/b9feabc79b92dc2b05683a986ad43bce5c1583e3", - "reference": "b9feabc79b92dc2b05683a986ad43bce5c1583e3", + "url": "https://api.github.com/repos/utopia-php/platform/zipball/beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", + "reference": "beeea0f2c9bce14a6869fc5c87a1047cdecb5c52", "shasum": "" }, "require": { @@ -2344,7 +2344,8 @@ "ext-redis": "*", "php": ">=8.0", "utopia-php/cli": "0.15.*", - "utopia-php/framework": "0.33.*" + "utopia-php/framework": "0.33.*", + "utopia-php/queue": "0.7.*" }, "require-dev": { "laravel/pint": "1.2.*", @@ -2370,9 +2371,9 @@ ], "support": { "issues": "https://github.com/utopia-php/platform/issues", - "source": "https://github.com/utopia-php/platform/tree/0.5.2" + "source": "https://github.com/utopia-php/platform/tree/0.7.0" }, - "time": "2024-05-22T12:50:35+00:00" + "time": "2024-05-08T17:00:55+00:00" }, { "name": "utopia-php/pools", @@ -2755,22 +2756,22 @@ }, { "name": "utopia-php/vcs", - "version": "0.6.6", + "version": "0.6.7", "source": { "type": "git", "url": "https://github.com/utopia-php/vcs.git", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4" + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/vcs/zipball/e538264cfee5e3efdfe1771efba04750cf20b2c4", - "reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4", + "url": "https://api.github.com/repos/utopia-php/vcs/zipball/8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", + "reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974", "shasum": "" }, "require": { "adhocore/jwt": "^1.1", "php": ">=8.0", - "utopia-php/cache": "^0.9.0", + "utopia-php/cache": "^0.10.0", "utopia-php/framework": "0.*.*" }, "require-dev": { @@ -2798,9 +2799,9 @@ ], "support": { "issues": "https://github.com/utopia-php/vcs/issues", - "source": "https://github.com/utopia-php/vcs/tree/0.6.6" + "source": "https://github.com/utopia-php/vcs/tree/0.6.7" }, - "time": "2024-05-17T09:36:30+00:00" + "time": "2024-06-05T17:38:29+00:00" }, { "name": "utopia-php/websocket", @@ -2987,16 +2988,16 @@ "packages-dev": [ { "name": "appwrite/sdk-generator", - "version": "0.38.6", + "version": "0.38.7", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699" + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699", - "reference": "d7016d6d72545e84709892faca972eb4bf5bd699", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", + "reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a", "shasum": "" }, "require": { @@ -3032,9 +3033,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/0.38.6" + "source": "https://github.com/appwrite/sdk-generator/tree/0.38.7" }, - "time": "2024-05-20T18:00:16+00:00" + "time": "2024-06-10T00:23:02+00:00" }, { "name": "doctrine/deprecations", @@ -3345,16 +3346,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -3362,11 +3363,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "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", @@ -3392,7 +3394,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -3400,7 +3402,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "nikic/php-parser", @@ -5591,8 +5593,8 @@ { "package": "utopia-php/cache", "version": "dev-feat-redis-sync", - "alias": "0.9.1", - "alias_normalized": "0.9.1.0" + "alias": "0.10.0", + "alias_normalized": "0.10.0.0" } ], "minimum-stability": "stable", From 498b31bd698e3d61ec594865223a8181abffab47 Mon Sep 17 00:00:00 2001 From: shimon Date: Mon, 1 Jul 2024 16:08:27 +0300 Subject: [PATCH 87/87] private to protected scope --- .../Platform/Workers/Certificates.php | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Appwrite/Platform/Workers/Certificates.php b/src/Appwrite/Platform/Workers/Certificates.php index ff254dc2af..dd09bfeb0b 100644 --- a/src/Appwrite/Platform/Workers/Certificates.php +++ b/src/Appwrite/Platform/Workers/Certificates.php @@ -60,7 +60,11 @@ public function __construct() * @param Event $queueForEvents * @param Func $queueForFunctions * @param Log $log + * @param Client $queueForSyncOutAggregation * @return void + * @throws Authorization + * @throws Conflict + * @throws Structure * @throws Throwable * @throws \Utopia\Database\Exception */ @@ -97,7 +101,7 @@ public function action(Message $message, Database $dbForConsole, Mail $queueForM * @throws Throwable * @throws \Utopia\Database\Exception */ - private function execute(Domain $domain, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForSyncOutAggregation, bool $skipRenewCheck = false): void + protected function execute(Domain $domain, Database $dbForConsole, Mail $queueForMails, Event $queueForEvents, Func $queueForFunctions, Log $log, Client $queueForSyncOutAggregation, bool $skipRenewCheck = false): void { /** * 1. Read arguments and validate domain @@ -233,7 +237,7 @@ private function execute(Domain $domain, Database $dbForConsole, Mail $queueForM * @throws Conflict * @throws Structure */ - private function saveCertificateDocument(string $domain, Document $certificate, bool $success, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions): void + protected function saveCertificateDocument(string $domain, Document $certificate, bool $success, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions): void { // Check if update or insert required $certificateDocument = $dbForConsole->findOne('certificates', [Query::equal('domain', [$domain])]); @@ -255,7 +259,7 @@ private function saveCertificateDocument(string $domain, Document $certificate, * * @return null|string Returns main domain. If null, there is no main domain yet. */ - private function getMainDomain(): ?string + protected function getMainDomain(): ?string { $envDomain = System::getEnv('_APP_DOMAIN', ''); if (!empty($envDomain) && $envDomain !== 'localhost') { @@ -276,7 +280,7 @@ private function getMainDomain(): ?string * @return void * @throws Exception */ - private function validateDomain(Domain $domain, bool $isMainDomain, Log $log): void + protected function validateDomain(Domain $domain, bool $isMainDomain, Log $log): void { if (empty($domain->get())) { throw new Exception('Missing certificate domain.'); @@ -320,7 +324,7 @@ private function validateDomain(Domain $domain, bool $isMainDomain, Log $log): v * @return bool True, if certificate needs to be renewed * @throws Exception */ - private function isRenewRequired(string $domain, Log $log): bool + protected function isRenewRequired(string $domain, Log $log): bool { $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; if (\file_exists($certPath)) { @@ -354,7 +358,7 @@ private function isRenewRequired(string $domain, Log $log): bool * @return array Named array with keys 'stdout' and 'stderr', both string * @throws Exception */ - private function issueCertificate(string $folder, string $domain, string $email): array + protected function issueCertificate(string $folder, string $domain, string $email): array { $stdout = ''; $stderr = ''; @@ -384,7 +388,7 @@ private function issueCertificate(string $folder, string $domain, string $email) * @return string * @throws \Utopia\Database\Exception */ - private function getRenewDate(string $domain): string + protected function getRenewDate(string $domain): string { $certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem'; $certData = openssl_x509_parse(file_get_contents($certPath)); @@ -402,7 +406,7 @@ private function getRenewDate(string $domain): string * @return void * @throws Exception */ - private function applyCertificateFiles(string $folder, string $domain, array $letsEncryptData): void + protected function applyCertificateFiles(string $folder, string $domain, array $letsEncryptData): void { // Prepare folder in storage for domain @@ -453,7 +457,7 @@ private function applyCertificateFiles(string $folder, string $domain, array $le * @return void * @throws Exception */ - private function notifyError(string $domain, string $errorMessage, int $attempt, Mail $queueForMails): void + protected function notifyError(string $domain, string $errorMessage, int $attempt, Mail $queueForMails): void { // Log error into console Console::warning('Cannot renew domain (' . $domain . ') on attempt no. ' . $attempt . ' certificate: ' . $errorMessage); @@ -512,7 +516,7 @@ private function notifyError(string $domain, string $errorMessage, int $attempt, * * @return void */ - private function updateDomainDocuments(string $certificateId, string $domain, bool $success, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions): void + protected function updateDomainDocuments(string $certificateId, string $domain, bool $success, Database $dbForConsole, Event $queueForEvents, Func $queueForFunctions): void { $rule = $dbForConsole->findOne('rules', [