diff --git a/app/config/collections2.php b/app/config/collections2.php index 4122cd9f0..6f82e972f 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -1916,7 +1916,7 @@ $collections = [ ], [ 'array' => false, - '$id' => 'command', + '$id' => 'entrypoint', 'type' => Database::VAR_STRING, 'format' => '', 'size' => 2048, @@ -1959,6 +1959,50 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'status', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 128, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'builtPath', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'buildStdout', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 4096, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => 'buildStderr', + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 4096, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ] ], 'indexes' => [ [ diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 9383e7010..1520ea689 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -24,7 +24,6 @@ use Utopia\Validator\Range; use Utopia\Validator\WhiteList; use Utopia\Config\Config; use Cron\CronExpression; -use Utopia\Exception; use Utopia\Validator\Boolean; include_once __DIR__ . '/../shared/api.php'; @@ -446,7 +445,7 @@ App::post('/v1/functions/:functionId/tags') ->inject('response') ->inject('dbForInternal') ->inject('usage') - ->action(function ($functionId, $command, $file, $request, $response, $dbForInternal, $usage) { + ->action(function ($functionId, $entrypoint, $file, $request, $response, $dbForInternal, $usage) { /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal */ diff --git a/app/executor.php b/app/executor.php index 54936917d..3e8f22e59 100644 --- a/app/executor.php +++ b/app/executor.php @@ -9,6 +9,8 @@ use Appwrite\Database\Validator\Authorization; use Appwrite\Database\Validator\UID; use Appwrite\Event\Event; use Appwrite\Utopia\Response\Model\Execution; +use Appwrite\Messaging\Adapter\Realtime; +use Appwrite\Stats\Stats; use Utopia\App; use Utopia\Swoole\Request; use Appwrite\Utopia\Response; @@ -17,10 +19,9 @@ use Swoole\Process; use Swoole\Http\Server; use Swoole\Http\Request as SwooleRequest; use Swoole\Http\Response as SwooleResponse; -use Utopia\Orchestration\Adapter\DockerAPI; use Utopia\Orchestration\Orchestration; -use Utopia\Orchestration\Container; -use Utopia\Orchestration\Exception\Timeout as TimeoutException; +use Utopia\Database\Adapter\MariaDB; +use Utopia\Cache\Adapter\Redis as RedisCache; use Utopia\Config\Config; use Utopia\Validator\ArrayList; use Utopia\Validator\JSON; @@ -29,9 +30,10 @@ use Cron\CronExpression; use Utopia\Storage\Device\Local; use Utopia\Storage\Storage; use Swoole\Coroutine as Co; +use Utopia\Cache\Cache; use Utopia\Orchestration\Adapter\DockerCLI; -require_once __DIR__ . '/workers.php'; +require_once __DIR__ . '/init.php'; $dockerUser = App::getEnv('DOCKERHUB_PULL_USERNAME', null); $dockerPass = App::getEnv('DOCKERHUB_PULL_PASSWORD', null); @@ -100,21 +102,11 @@ App::post('/v1/execute') // Define Route ->param('userId', '', new Text(1024), '', true) ->param('jwt', '', new Text(1024), '', true) ->inject('response') + ->inject('dbForInternal') ->action( - function ($trigger, $projectId, $executionId, $functionId, $event, $eventData, $data, $webhooks, $userId, $jwt, $request, $response) { - global $register; - - $db = $register->get('dbPool')->get(); - $cache = $register->get('redisPool')->get(); - - // Create new Database Instance - $database = new Database(); - $database->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache)); - $database->setNamespace('app_' . $projectId); - $database->setMocks(Config::getParam('collections', [])); - + function ($trigger, $projectId, $executionId, $functionId, $event, $eventData, $data, $webhooks, $userId, $jwt, $request, $response, $dbForInternal) { try { - $data = execute($trigger, $projectId, $executionId, $functionId, $database, $event, $eventData, $data, $webhooks, $userId, $jwt); + $data = execute($trigger, $projectId, $executionId, $functionId, $dbForInternal, $event, $eventData, $data, $webhooks, $userId, $jwt); $response->json($data); } catch (Exception $e) { $response @@ -122,9 +114,6 @@ App::post('/v1/execute') // Define Route ->addHeader('Expires', '0') ->addHeader('Pragma', 'no-cache') ->json(['error' => $e->getMessage()]); - } finally { - $register->get('dbPool')->put($db); - $register->get('redisPool')->put($cache); } } ); @@ -134,19 +123,19 @@ App::post('/v1/execute') // Define Route App::post('/v1/cleanup/function') ->param('functionId', '', new UID()) ->inject('response') - ->inject('projectDB') + ->inject('dbForInternal') ->inject('projectID') - ->action(function ($functionId, $response, $projectDB, $projectID) { + ->action(function ($functionId, $response, $dbForInternal, $projectID) { /** @var string $functionId */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Database $projectDB */ + /** @var Appwrite\Database\Database $dbForInternal */ /** @var string $projectID */ global $orchestration; try { Authorization::disable(); - $function = $projectDB->getDocument($functionId); + $function = $dbForInternal->getDocument($functionId); Authorization::reset(); if (\is_null($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) { @@ -154,7 +143,7 @@ App::post('/v1/cleanup/function') } Authorization::disable(); - $results = $projectDB->getCollection([ + $results = $dbForInternal->getCollection([ 'limit' => 999, 'offset' => 0, 'orderType' => 'ASC', @@ -190,19 +179,19 @@ App::post('/v1/cleanup/function') App::post('/v1/cleanup/tag') ->param('tagId', '', new UID(), 'Tag unique ID.') ->inject('response') - ->inject('projectDB') + ->inject('dbForInternal') ->inject('projectID') - ->action(function ($tagId, $response, $projectDB, $projectID) { + ->action(function ($tagId, $response, $dbForInternal, $projectID) { /** @var string $tagId */ /** @var Appwrite\Utopia\Response $response */ - /** @var Appwrite\Database\Database $projectDB */ + /** @var Appwrite\Database\Database $dbForInternal */ /** @var string $projectID */ global $orchestration; try { Authorization::disable(); - $tag = $projectDB->getDocument($tagId); + $tag = $dbForInternal->getDocument($tagId); Authorization::reset(); if (\is_null($tag->getId()) || Database::SYSTEM_COLLECTION_TAGS != $tag->getCollection()) { @@ -227,13 +216,12 @@ App::post('/v1/tag') ->param('functionId', '', new UID(), 'Function unique ID.') ->param('tagId', '', new UID(), 'Tag unique ID.') ->inject('response') - ->inject('projectDB') + ->inject('dbForInternal') ->inject('projectID') - ->action(function ($functionId, $tagId, $response, $projectDB, $projectID) { + ->action(function ($functionId, $tagId, $response, $dbForInternal, $projectID) { Authorization::disable(); - $project = $projectDB->getDocument($projectID); - $function = $projectDB->getDocument($functionId); - $tag = $projectDB->getDocument($tagId); + $function = $dbForInternal->getDocument('functions', $functionId); + $tag = $dbForInternal->getDocument('tags', $tagId); Authorization::reset(); if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) { @@ -246,34 +234,24 @@ App::post('/v1/tag') $schedule = $function->getAttribute('schedule', ''); $cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null; - $next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : null; + $next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0; Authorization::disable(); - $function = $projectDB->updateDocument(array_merge($function->getArrayCopy(), [ + $function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [ 'tag' => $tag->getId(), - 'scheduleNext' => $next - ])); + 'scheduleNext' => (int)$next, + ]))); Authorization::reset(); // Build Code - go(function () use ($projectDB, $projectID, $function, $tagId, $functionId) { + go(function () use ($dbForInternal, $projectID, $function, $tagId, $functionId) { // Build Code - $tag = runBuildStage($tagId, $function, $projectID, $projectDB); + $tag = runBuildStage($tagId, $function, $projectID, $dbForInternal); // Deploy Runtime Server - createRuntimeServer($functionId, $projectID, $tag, $projectDB); + createRuntimeServer($functionId, $projectID, $tag, $dbForInternal); }); - if ($next) { // Init first schedule - ResqueScheduler::enqueueAt($next, 'v1-functions', 'FunctionsV1', [ - 'projectId' => $projectID, - 'webhooks' => $project->getAttribute('webhooks', []), - 'functionId' => $function->getId(), - 'executionId' => null, - 'trigger' => 'schedule', - ]); // Async task reschedule - } - if (false === $function) { throw new Exception('Failed saving function to DB', 500); } @@ -613,8 +591,9 @@ function createRuntimeServer(string $functionId, string $projectId, Document $ta $orchestration->setCpus(App::getEnv('_APP_FUNCTIONS_CPUS', '1')); $orchestration->setMemory(App::getEnv('_APP_FUNCTIONS_MEMORY', '256')); $orchestration->setSwap(App::getEnv('_APP_FUNCTIONS_MEMORY_SWAP', '256')); - foreach ($vars as &$value) { - $value = strval($value); + + foreach ($vars as $key => $value) { + $vars[$key] = strval($value); } $id = $orchestration->run( @@ -654,6 +633,7 @@ function execute(string $trigger, string $projectId, string $executionId, string global $activeFunctions; global $runtimes; + global $register; // Grab Tag Document Authorization::disable(); @@ -861,7 +841,7 @@ function execute(string $trigger, string $projectId, string $executionId, string // 110 is the Swoole error code for timeout, see: https://www.swoole.co.uk/docs/swoole-error-code if ($errNo !== 0 && $errNo != CURLE_COULDNT_CONNECT && $errNo != CURLE_OPERATION_TIMEDOUT && $errNo != 110) { - Console::error('A internal curl error has occoured within the executor! Error Msg: '. $error); + Console::error('A internal curl error has occoured within the executor! Error Msg: ' . $error); throw new Exception('Curl error: ' . $error, 500); } @@ -885,22 +865,16 @@ function execute(string $trigger, string $projectId, string $executionId, string Console::info('Function executed in ' . ($executionEnd - $executionStart) . ' seconds, status: ' . $functionStatus); - Authorization::disable(); - - $execution = $database->updateDocument(array_merge($execution->getArrayCopy(), [ - 'tagId' => $tag->getId(), - 'status' => $functionStatus, - 'exitCode' => $exitCode, - 'stdout' => \utf8_encode(\mb_substr($stdout, -4000)), // log last 4000 chars output - 'stderr' => \utf8_encode(\mb_substr($stderr, -4000)), // log last 4000 chars output - 'time' => $executionTime - ])); - - Authorization::reset(); - - if (false === $function) { - throw new Exception('Failed saving execution to DB', 500); - } + $execution = Authorization::skip(function () use ($database, $execution, $tag, $functionStatus, $exitCode, $stdout, $stderr, $executionTime) { + return $database->updateDocument('executions', $execution->getId(), new Document(array_merge($execution->getArrayCopy(), [ + 'tagId' => $tag->getId(), + 'status' => $functionStatus, + 'exitCode' => $exitCode, + 'stdout' => \utf8_encode(\mb_substr($stdout, -8000)), // log last 8000 chars output + 'stderr' => \utf8_encode(\mb_substr($stderr, -8000)), // log last 8000 chars output + 'time' => (float)$executionTime, + ]))); + }); $executionModel = new Execution(); $executionUpdate = new Event('v1-webhooks', 'WebhooksV1'); @@ -914,16 +888,33 @@ function execute(string $trigger, string $projectId, string $executionId, string $executionUpdate->trigger(); - $usage = new Event('v1-usage', 'UsageV1'); + $target = Realtime::fromPayload('functions.executions.update', $execution); - $usage - ->setParam('projectId', $projectId) - ->setParam('functionId', $function->getId()) - ->setParam('functionExecution', 1) - ->setParam('functionStatus', $functionStatus) - ->setParam('functionExecutionTime', $executionTime * 1000) // ms - ->setParam('networkRequestSize', 0) - ->setParam('networkResponseSize', 0); + Realtime::send( + projectId: $projectId, + payload: $execution->getArrayCopy(), + event: 'functions.executions.update', + channels: $target['channels'], + roles: $target['roles'] + ); + + if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { + $statsd = $register->get('statsd'); + + $usage = new Stats($statsd); + + $usage + ->setParam('projectId', $projectId) + ->setParam('functionId', $function->getId()) + ->setParam('functionExecution', 1) + ->setParam('functionStatus', $functionStatus) + ->setParam('functionExecutionTime', $executionTime * 1000) // ms + ->setParam('networkRequestSize', 0) + ->setParam('networkResponseSize', 0) + ->submit(); + + $usage->submit(); + } if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') { $usage->trigger(); @@ -969,19 +960,52 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo $response = new Response($swooleResponse); $app = new App('UTC'); - $db = $register->get('dbPool')->get(); - $redis = $register->get('redisPool')->get(); - App::setResource('db', function () use (&$db) { - return $db; + $dbHost = App::getEnv('_APP_DB_HOST', ''); + $dbUser = App::getEnv('_APP_DB_USER', ''); + $dbPass = App::getEnv('_APP_DB_PASS', ''); + $dbScheme = App::getEnv('_APP_DB_SCHEMA', ''); + + $pdo = new PDO("mysql:host={$dbHost};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array( + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', + PDO::ATTR_TIMEOUT => 3, // Seconds + PDO::ATTR_PERSISTENT => true, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + )); + + return $pdo; }); App::setResource('cache', function () use (&$redis) { + $redis = new Redis(); + $redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', '')); + $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); + return $redis; }); + App::setResource('dbForConsole', function($db, $cache) { + $cache = new Cache(new RedisCache($cache)); + + $database = new Database(new MariaDB($db), $cache); + $database->setNamespace('project_console_internal'); + + return $database; + }, ['db', 'cache']); + $projectId = $request->getHeader('x-appwrite-project', ''); + App::setResource('project', function ($dbForConsole) use ($projectId) { + Authorization::disable(); + + $project = $dbForConsole->getDocument('projects', $projectId); + + Authorization::reset(); + + return $project; + }, ['dbForConsole']); + Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId)); // Check environment variable key @@ -997,14 +1021,16 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo return $swooleResponse->end('401: Authentication Error'); } - App::setResource('projectDB', function ($db, $cache) use ($projectId) { - $projectDB = new Database(); - $projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache)); - $projectDB->setNamespace('app_' . $projectId); - $projectDB->setMocks(Config::getParam('collections', [])); + App::setResource('dbForInternal', function ($db, $cache, $project) { + $cache = new Cache(new RedisCache($cache)); - return $projectDB; - }, ['db', 'cache']); + $test = $project->getId(); + + $database = new Database(new MariaDB($db), $cache); + $database->setNamespace('project_' . $project->getId() . '_internal'); + + return $database; + }, ['db', 'cache', 'project']); App::error(function ($error, $utopia, $request, $response) { /** @var Exception $error */ diff --git a/composer.lock b/composer.lock index 53e7296a8..2f5b9cd04 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": "5a286ad3333879ad6087d3ff97f2858b", + "content-hash": "263916aa1e178a0da009a87f9c4ff49f", "packages": [ { "name": "adhocore/jwt", @@ -119,7 +119,7 @@ "source": { "type": "git", "url": "https://github.com/PineappleIOnic/php-runtimes.git", - "reference": "fd85bad3c975ccfe4e7f35bafbc8c606fc3fdf79" + "reference": "f6dbfb76cbf52934085d4e119f5de28f33b69aa1" }, "require": { "php": ">=8.0", @@ -156,7 +156,7 @@ "php", "runtimes" ], - "time": "2021-09-29T15:50:27+00:00" + "time": "2021-10-11T10:57:42+00:00" }, { "name": "chillerlan/php-qrcode", @@ -343,6 +343,79 @@ }, "time": "2020-11-06T16:09:14+00:00" }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.4", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b174585d1fe49ceed21928a945138948cb394600" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", + "reference": "b174585d1fe49ceed21928a945138948cb394600", + "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.4" + }, + "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": "2021-09-13T08:41:34+00:00" + }, { "name": "dragonmantank/cron-expression", "version": "v3.1.0", @@ -509,16 +582,16 @@ }, { "name": "guzzlehttp/promises", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" + "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "url": "https://api.github.com/repos/guzzle/promises/zipball/136a635e2b4a49b9d79e9c8fee267ffb257fdba0", + "reference": "136a635e2b4a49b9d79e9c8fee267ffb257fdba0", "shasum": "" }, "require": { @@ -530,7 +603,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.5-dev" } }, "autoload": { @@ -546,10 +619,25 @@ "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", @@ -558,22 +646,36 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" + "source": "https://github.com/guzzle/promises/tree/1.5.0" }, - "time": "2021-03-07T09:25:29+00:00" + "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": "2021-10-07T13:05:22+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7" + "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/1dc8d9cba3897165e16d12bb13d813afb1eb3fe7", - "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/089edd38f5b8abba6cb01567c2a8aaa47cec4c72", + "reference": "089edd38f5b8abba6cb01567c2a8aaa47cec4c72", "shasum": "" }, "require": { @@ -597,7 +699,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -610,13 +712,34 @@ "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" }, { @@ -638,9 +761,23 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.0.0" + "source": "https://github.com/guzzle/psr7/tree/2.1.0" }, - "time": "2021-06-30T20:03:07+00:00" + "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": "2021-10-06T17:43:30+00:00" }, { "name": "influxdb/influxdb-php", @@ -708,6 +845,61 @@ }, "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": "4.2.3", @@ -777,6 +969,74 @@ }, "time": "2021-05-12T14:14:25+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": { + "psr-4": { + "MongoDB\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "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", @@ -1376,22 +1636,106 @@ "time": "2021-02-19T12:13:01+00:00" }, { - "name": "utopia-php/abuse", - "version": "0.5.0", + "name": "symfony/polyfill-php80", + "version": "v1.23.1", "source": { "type": "git", - "url": "https://github.com/utopia-php/abuse.git", - "reference": "339c1720e5aa5314276128170463594b81f84760" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/339c1720e5aa5314276128170463594b81f84760", - "reference": "339c1720e5aa5314276128170463594b81f84760", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "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.23.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": "2021-07-28T13:41:28+00:00" + }, + { + "name": "utopia-php/abuse", + "version": "0.6.3", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/abuse.git", + "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/d63e928c2c50b367495a499a85ba9806ee274c5e", + "reference": "d63e928c2c50b367495a499a85ba9806ee274c5e", "shasum": "" }, "require": { "ext-pdo": "*", - "php": ">=7.4" + "php": ">=7.4", + "utopia-php/database": ">=0.6 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.4", @@ -1423,9 +1767,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.5.0" + "source": "https://github.com/utopia-php/abuse/tree/0.6.3" }, - "time": "2021-06-28T10:11:01+00:00" + "time": "2021-08-16T18:38:31+00:00" }, { "name": "utopia-php/analytics", @@ -1484,21 +1828,22 @@ }, { "name": "utopia-php/audit", - "version": "0.5.2", + "version": "0.6.3", "source": { "type": "git", "url": "https://github.com/utopia-php/audit.git", - "reference": "57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4" + "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/audit/zipball/57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4", - "reference": "57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4", + "url": "https://api.github.com/repos/utopia-php/audit/zipball/d79b467fbc7d03e5e02f12cdeb08761507a60ca0", + "reference": "d79b467fbc7d03e5e02f12cdeb08761507a60ca0", "shasum": "" }, "require": { "ext-pdo": "*", - "php": ">=7.4" + "php": ">=7.4", + "utopia-php/database": ">=0.6 <1.0" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1530,27 +1875,28 @@ ], "support": { "issues": "https://github.com/utopia-php/audit/issues", - "source": "https://github.com/utopia-php/audit/tree/0.5.2" + "source": "https://github.com/utopia-php/audit/tree/0.6.3" }, - "time": "2021-06-23T16:02:40+00:00" + "time": "2021-08-16T18:49:55+00:00" }, { "name": "utopia-php/cache", - "version": "0.2.3", + "version": "0.4.1", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "a44b904127f88fa64673e402e5c0732ff6687d47" + "reference": "8c48eff73219c8c1ac2807909f0a38f3480c8938" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/a44b904127f88fa64673e402e5c0732ff6687d47", - "reference": "a44b904127f88fa64673e402e5c0732ff6687d47", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/8c48eff73219c8c1ac2807909f0a38f3480c8938", + "reference": "8c48eff73219c8c1ac2807909f0a38f3480c8938", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.3" + "ext-redis": "*", + "php": ">=7.4" }, "require-dev": { "phpunit/phpunit": "^9.3", @@ -1582,9 +1928,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/0.2.3" + "source": "https://github.com/utopia-php/cache/tree/0.4.1" }, - "time": "2020-10-24T10:11:01+00:00" + "time": "2021-04-29T18:41:43+00:00" }, { "name": "utopia-php/cli", @@ -1690,6 +2036,69 @@ }, "time": "2020-10-24T09:49:09+00:00" }, + { + "name": "utopia-php/database", + "version": "0.10.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/database.git", + "reference": "b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/database/zipball/b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8", + "reference": "b7c60b0ec769a9050dd2b939b78ff1f5d4fa27e8", + "shasum": "" + }, + "require": { + "ext-mongodb": "*", + "ext-pdo": "*", + "ext-redis": "*", + "mongodb/mongodb": "1.8.0", + "php": ">=7.1", + "utopia-php/cache": "0.4.*", + "utopia-php/framework": "0.*.*" + }, + "require-dev": { + "fakerphp/faker": "^1.14", + "phpunit/phpunit": "^9.4", + "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.10.0" + }, + "time": "2021-10-04T17:23:25+00:00" + }, { "name": "utopia-php/domains", "version": "v1.1.0", @@ -2500,16 +2909,16 @@ }, { "name": "appwrite/sdk-generator", - "version": "0.14.3", + "version": "0.15.2", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "a1075a59db33fe2bba9e648bf67b3ece1debcfa4" + "reference": "f42e70737d3b63fb8440111022c9509529a16479" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/a1075a59db33fe2bba9e648bf67b3ece1debcfa4", - "reference": "a1075a59db33fe2bba9e648bf67b3ece1debcfa4", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/f42e70737d3b63fb8440111022c9509529a16479", + "reference": "f42e70737d3b63fb8440111022c9509529a16479", "shasum": "" }, "require": { @@ -2543,82 +2952,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.14.3" + "source": "https://github.com/appwrite/sdk-generator/tree/0.15.2" }, - "time": "2021-09-06T09:32:51+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.4", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b174585d1fe49ceed21928a945138948cb394600" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", - "reference": "b174585d1fe49ceed21928a945138948cb394600", - "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.4" - }, - "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": "2021-09-13T08:41:34+00:00" + "time": "2021-09-24T16:14:17+00:00" }, { "name": "composer/semver", @@ -3543,16 +3879,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30f38bffc6f24293dadd1823936372dfa9e86e2f", - "reference": "30f38bffc6f24293dadd1823936372dfa9e86e2f", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -3587,9 +3923,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.5.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" }, - "time": "2021-09-17T15:28:14+00:00" + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", @@ -5633,89 +5969,6 @@ ], "time": "2021-02-19T12:13:01+00:00" }, - { - "name": "symfony/polyfill-php80", - "version": "v1.23.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "files": [ - "bootstrap.php" - ], - "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.23.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": "2021-07-28T13:41:28+00:00" - }, { "name": "symfony/service-contracts", "version": "v2.4.0",