Merge branch 'feat-265-realtime' of https://github.com/appwrite/appwrite into feat-265-realtime-usage
This commit is contained in:
commit
81cf991695
31
CHANGES.md
31
CHANGES.md
|
@ -2,26 +2,47 @@
|
|||
|
||||
## Features
|
||||
|
||||
- Added file created date to file info on the console
|
||||
- Added file size to file info on the console
|
||||
- Refactored Devices page in Console:
|
||||
- Added support for Android
|
||||
- Added a new gravity option when croping storage images using the file preview endpoint (#1260)
|
||||
- Upgraded GEOIP DB file to Jun 2021 release (#1256)
|
||||
- Added file created date to file info on the console (#1183)
|
||||
- Added file size to file info on the console (#1183)
|
||||
- Added internal support for connection pools for improved performance (#1278)
|
||||
- Added new abstraction for workers executable files (#1276)
|
||||
- Added a new API in the Users API to allow you to force update your user verification status (#1223)
|
||||
- Using a fixed commit to avoid breaking changes for imagemagick extenstion (#1274)
|
||||
- Updated the design of all the email templates (#1225)
|
||||
- Refactored Devices page in Console: (#1167)
|
||||
- Renamed *Devices* to *Sessions*
|
||||
- Add Provider Icon to each Session
|
||||
- Add Anonymous Account Placeholder
|
||||
- Upgraded phpmailer version to 6.5.0 (#1317)
|
||||
- Upgraded telegraf docker image version to v1.2.0
|
||||
- Added new environment variables to the `telegraf` service:
|
||||
- Added new environment variables to the `telegraf` service: (#1202)
|
||||
- _APP_INFLUXDB_HOST
|
||||
- _APP_INFLUXDB_PORT
|
||||
- Added new endpoint to get a session based on it's ID (#1294)
|
||||
|
||||
## Breaking Changes (Read before upgrading!)
|
||||
- Renamed `env` param on `/v1/functions` to `runtime` (#1314)
|
||||
- Renamed `deleteUser` method in all SDKs to `delete` (#1216)
|
||||
|
||||
## Bugs
|
||||
|
||||
- Fixed bug when removing a project member on the Appwrite console (#1214)
|
||||
- Fixed bug causing runtimes conflict and hanging executions when max Functions containers limit passed (#1288)
|
||||
- Fixed 404 error when removing a project member on the Appwrite console (#1214)
|
||||
- Fixed Swoole buffer output size to allow downloading files bigger than allowed size (#1189)
|
||||
- Fixed ClamAV status when anti virus is not running (#1188)
|
||||
- Fixed deleteSession which was removing cookieFallback from the localstorage on any logout instead of current session (#1206)
|
||||
- Fixed Nepal flag (#1173)
|
||||
- Fixed a bug in the Twitch OAuth adapter (#1209)
|
||||
- Fixed missing session object when OAuth session creation event is triggered (#1208)
|
||||
- Fixed bug where we didn't ignore the email case, converted all emails to lowercase internally (#1243)
|
||||
- Fixed a console bug where you can't click a user with no name, added a placehoder for anonyomous users (#1220)
|
||||
|
||||
## Security
|
||||
|
||||
- Fixed potential XSS injection on the console
|
||||
|
||||
# Version 0.8.0
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
|
|||
FROM php:8.0-cli-alpine as step1
|
||||
|
||||
ENV PHP_REDIS_VERSION=5.3.4 \
|
||||
PHP_SWOOLE_VERSION=v4.6.6 \
|
||||
PHP_SWOOLE_VERSION=v4.6.7 \
|
||||
PHP_IMAGICK_VERSION=master \
|
||||
PHP_YAML_VERSION=2.2.1 \
|
||||
PHP_MAXMINDDB_VERSION=v1.10.1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/init.php';
|
||||
require_once __DIR__.'/workers.php';
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\CLI;
|
||||
|
|
|
@ -1481,8 +1481,8 @@ $collections = [
|
|||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Env',
|
||||
'key' => 'env',
|
||||
'label' => 'Runtime',
|
||||
'key' => 'runtime',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
|
1
app/config/specs/0.9.x.client.json
Normal file
1
app/config/specs/0.9.x.client.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/0.9.x.console.json
Normal file
1
app/config/specs/0.9.x.console.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/0.9.x.server.json
Normal file
1
app/config/specs/0.9.x.server.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -67,7 +67,7 @@ return [
|
|||
'introduction' => '',
|
||||
'default' => 'localhost',
|
||||
'required' => true,
|
||||
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.\nYou can use the same value as used for the Appwrite hostname.',
|
||||
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.' . PHP_EOL . 'You can use the same value as used for the Appwrite hostname.',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
|
|
|
@ -254,9 +254,13 @@ App::post('/v1/account/sessions')
|
|||
|
||||
$countries = $locale->getText('countries');
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'))
|
||||
->setAttribute('countryName', $countryName)
|
||||
;
|
||||
|
||||
$response->dynamic($session, Response::MODEL_SESSION);
|
||||
|
@ -753,9 +757,13 @@ App::post('/v1/account/sessions/anonymous')
|
|||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
;
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
->setAttribute('countryName', (isset($countries[$session->getAttribute('countryCode')])) ? $countries[$session->getAttribute('countryCode')] : $locale->getText('locale.country.unknown'))
|
||||
->setAttribute('countryName', $countryName)
|
||||
;
|
||||
|
||||
$response->dynamic($session, Response::MODEL_SESSION);
|
||||
|
@ -878,9 +886,11 @@ App::get('/v1/account/sessions')
|
|||
foreach ($sessions as $key => $session) {
|
||||
/** @var Document $session */
|
||||
|
||||
$session->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown'));
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
|
||||
$session->setAttribute('countryName', $countryName);
|
||||
$session->setAttribute('current', ($current == $session->getId()) ? true : false);
|
||||
|
||||
$sessions[$key] = $session;
|
||||
|
@ -904,19 +914,20 @@ App::get('/v1/account/logs')
|
|||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LOG_LIST)
|
||||
->inject('response')
|
||||
->inject('register')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function ($response, $register, $project, $user, $locale, $geodb) {
|
||||
->inject('app')
|
||||
->action(function ($response, $project, $user, $locale, $geodb, $app) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Utopia\App $app */
|
||||
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter = new AuditAdapter($app->getResource('db'));
|
||||
$adapter->setNamespace('app_'.$project->getId());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
@ -968,6 +979,47 @@ App::get('/v1/account/logs')
|
|||
$response->dynamic(new Document(['logs' => $output]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/account/sessions/:sessionId')
|
||||
->desc('Get Session By ID')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'account')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'getSession')
|
||||
->label('sdk.description', '/docs/references/account/get-session.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION)
|
||||
->param('sessionId', null, new UID(), 'Session unique ID. Use the string \'current\' to get the current device session.')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
->inject('projectDB')
|
||||
->action(function ($sessionId, $response, $user, $locale, $projectDB) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
$sessionId = ($sessionId === 'current')
|
||||
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret)
|
||||
: $sessionId;
|
||||
|
||||
$session = $projectDB->getDocument($sessionId); // get user by session ID
|
||||
|
||||
if ($session->isEmpty() || Database::SYSTEM_COLLECTION_SESSIONS != $session->getCollection()) {
|
||||
throw new Exception('Session not found', 404);
|
||||
};
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
|
||||
$session->setAttribute('countryName', $countryName);
|
||||
|
||||
$response->dynamic($session, Response::MODEL_SESSION);
|
||||
});
|
||||
|
||||
App::patch('/v1/account/name')
|
||||
->desc('Update Account Name')
|
||||
->groups(['api', 'account'])
|
||||
|
|
|
@ -39,14 +39,14 @@ App::post('/v1/functions')
|
|||
->label('sdk.response.model', Response::MODEL_FUNCTION)
|
||||
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
|
||||
->param('execute', [], new ArrayList(new Text(64)), 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('env', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution enviornment.')
|
||||
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
|
||||
->param('vars', [], new Assoc(), 'Key-value JSON object.', true)
|
||||
->param('events', [], new ArrayList(new WhiteList(array_keys(Config::getParam('events')), true)), 'Events list.', true)
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($name, $execute, $env, $vars, $events, $schedule, $timeout, $response, $projectDB) {
|
||||
->action(function ($name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $projectDB) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
|
@ -59,7 +59,7 @@ App::post('/v1/functions')
|
|||
'dateUpdated' => time(),
|
||||
'status' => 'disabled',
|
||||
'name' => $name,
|
||||
'env' => $env,
|
||||
'runtime' => $runtime,
|
||||
'tag' => '',
|
||||
'vars' => $vars,
|
||||
'events' => $events,
|
||||
|
|
|
@ -42,12 +42,11 @@ App::get('/v1/health/db')
|
|||
->label('sdk.method', 'getDB')
|
||||
->label('sdk.description', '/docs/references/health/get-db.md')
|
||||
->inject('response')
|
||||
->inject('register')
|
||||
->action(function ($response, $register) {
|
||||
->inject('app')
|
||||
->action(function ($response, $app) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
|
||||
$register->get('db'); /* @var $db PDO */
|
||||
/** @var Utopia\App $app */
|
||||
$app->getResource('db');
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
});
|
||||
|
@ -61,11 +60,11 @@ App::get('/v1/health/cache')
|
|||
->label('sdk.method', 'getCache')
|
||||
->label('sdk.description', '/docs/references/health/get-cache.md')
|
||||
->inject('response')
|
||||
->inject('register')
|
||||
->action(function ($response, $register) {
|
||||
->inject('app')
|
||||
->action(function ($response, $app) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
$register->get('cache'); /* @var $cache Predis\Client */
|
||||
/** @var Utopia\App $register */
|
||||
$app->getResource('cache');
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
});
|
||||
|
|
|
@ -242,7 +242,7 @@ App::get('/v1/storage/files/:fileId/preview')
|
|||
->param('fileId', '', new UID(), 'File unique ID')
|
||||
->param('width', 0, new Range(0, 4000), 'Resize preview image width, Pass an integer between 0 to 4000.', true)
|
||||
->param('height', 0, new Range(0, 4000), 'Resize preview image height, Pass an integer between 0 to 4000.', true)
|
||||
->param('gravity', Image::GRAVITY_CENTER, new WhiteList([Image::GRAVITY_CENTER, Image::GRAVITY_NORTH, Image::GRAVITY_NORTHWEST, Image::GRAVITY_NORTHEAST, Image::GRAVITY_WEST, Image::GRAVITY_EAST, Image::GRAVITY_SOUTHWEST, Image::GRAVITY_SOUTH, Image::GRAVITY_SOUTHEAST]), 'Image crop gravity', true)
|
||||
->param('gravity', Image::GRAVITY_CENTER, new WhiteList(Image::getGravityTypes()), 'Image crop gravity. Can be one of ' . implode(",", Image::getGravityTypes()), true)
|
||||
->param('quality', 100, new Range(0, 100), 'Preview image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
->param('borderWidth', 0, new Range(0, 100), 'Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0.', true)
|
||||
->param('borderColor', '', new HexColor(), 'Preview image border color. Use a valid HEX color, no # is needed for prefix.', true)
|
||||
|
|
|
@ -218,7 +218,8 @@ App::delete('/v1/teams/:teamId')
|
|||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('events')
|
||||
->action(function ($teamId, $response, $projectDB, $events) {
|
||||
->inject('deletes')
|
||||
->action(function ($teamId, $response, $projectDB, $events, $deletes) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
@ -229,25 +230,15 @@ App::delete('/v1/teams/:teamId')
|
|||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$memberships = $projectDB->getCollection([
|
||||
'limit' => 2000, // TODO add members limit
|
||||
'offset' => 0,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'teamId='.$teamId,
|
||||
],
|
||||
]);
|
||||
|
||||
foreach ($memberships as $member) {
|
||||
if (!$projectDB->deleteDocument($member->getId())) {
|
||||
throw new Exception('Failed to remove membership for team from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$projectDB->deleteDocument($teamId)) {
|
||||
throw new Exception('Failed to remove team from DB', 500);
|
||||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $team)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
|
||||
;
|
||||
|
|
|
@ -232,18 +232,18 @@ App::get('/v1/users/:userId/logs')
|
|||
->label('sdk.response.model', Response::MODEL_LOG_LIST)
|
||||
->param('userId', '', new UID(), 'User unique ID.')
|
||||
->inject('response')
|
||||
->inject('register')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function ($userId, $response, $register, $project, $projectDB, $locale, $geodb) {
|
||||
->inject('app')
|
||||
->action(function ($userId, $response, $project, $projectDB, $locale, $geodb, $app) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Utopia\App $app */
|
||||
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
|
@ -251,7 +251,7 @@ App::get('/v1/users/:userId/logs')
|
|||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter = new AuditAdapter($app->getResource('db'));
|
||||
$adapter->setNamespace('app_'.$project->getId());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
|
|
@ -236,26 +236,15 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
|||
$role = Auth::USER_ROLE_APP;
|
||||
$scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', []));
|
||||
|
||||
Authorization::setRole('role:'.Auth::USER_ROLE_APP);
|
||||
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->getId()) {
|
||||
Authorization::setRole('user:'.$user->getId());
|
||||
foreach (Auth::getRoles($user) as $role) {
|
||||
Authorization::setRole($role);
|
||||
}
|
||||
|
||||
Authorization::setRole('role:'.$role);
|
||||
|
||||
\array_map(function ($node) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
Authorization::setRole('team:'.$node['teamId']);
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole);
|
||||
}
|
||||
}
|
||||
}, $user->getAttribute('memberships', []));
|
||||
|
||||
// TDOO Check if user is root
|
||||
|
||||
if (!\in_array($scope, $scopes)) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Abuse\Abuse;
|
||||
|
@ -9,7 +11,7 @@ use Utopia\Abuse\Adapters\TimeLimit;
|
|||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
|
||||
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes) {
|
||||
App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes, $db) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
@ -21,6 +23,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
|
|||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $functions */
|
||||
/** @var PDO $db */
|
||||
|
||||
Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId()));
|
||||
Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId()));
|
||||
|
@ -34,9 +37,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
|
|||
/*
|
||||
* Abuse Check
|
||||
*/
|
||||
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) {
|
||||
return $register->get('db');
|
||||
});
|
||||
$timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), $db);
|
||||
$timeLimit->setNamespace('app_'.$project->getId());
|
||||
$timeLimit
|
||||
->setParam('{userId}', $user->getId())
|
||||
|
@ -111,7 +112,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e
|
|||
->setParam('projectId', $project->getId())
|
||||
;
|
||||
|
||||
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api');
|
||||
}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes', 'db'], 'api');
|
||||
|
||||
App::init(function ($utopia, $request, $response, $project, $user) {
|
||||
/** @var Utopia\App $utopia */
|
||||
|
@ -167,7 +168,7 @@ App::init(function ($utopia, $request, $response, $project, $user) {
|
|||
|
||||
}, ['utopia', 'request', 'response', 'project', 'user'], 'auth');
|
||||
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $realtime, $mode) {
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $mode) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
@ -176,8 +177,6 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Realtime $realtime */
|
||||
/** @var Appwrite\Event\Event $functions */
|
||||
/** @var bool $mode */
|
||||
|
||||
if (!empty($events->getParam('event'))) {
|
||||
|
@ -199,12 +198,20 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
->trigger();
|
||||
|
||||
if ($project->getId() !== 'console') {
|
||||
$realtime
|
||||
->setEvent($events->getParam('event'))
|
||||
->setUserId($events->getParam('userId'))
|
||||
->setProject($project->getId())
|
||||
->setPayload($response->getPayload())
|
||||
->trigger();
|
||||
$payload = new Document($response->getPayload());
|
||||
$target = Realtime::fromPayload($events->getParam('event'), $payload);
|
||||
|
||||
Realtime::send(
|
||||
$project->getId(),
|
||||
$response->getPayload(),
|
||||
$events->getParam('event'),
|
||||
$target['channels'],
|
||||
$target['permissions'],
|
||||
[
|
||||
'permissionsChanged' => $target['permissionsChanged'],
|
||||
'userId' => $events->getParam('userId')
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,4 +236,4 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
;
|
||||
}
|
||||
|
||||
}, ['utopia', 'request', 'response', 'project', 'events', 'audits', 'usage', 'deletes', 'realtime', 'mode'], 'api');
|
||||
}, ['utopia', 'request', 'response', 'project', 'events', 'audits', 'usage', 'deletes', 'mode'], 'api');
|
||||
|
|
14
app/http.php
14
app/http.php
|
@ -4,14 +4,14 @@ require_once __DIR__.'/../vendor/autoload.php';
|
|||
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Swoole\Files;
|
||||
use Utopia\Swoole\Request;
|
||||
use Swoole\Process;
|
||||
use Swoole\Http\Server;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Swoole\Files;
|
||||
use Utopia\Swoole\Request;
|
||||
|
||||
$http = new Server("0.0.0.0", App::getEnv('PORT', 80));
|
||||
|
||||
|
@ -75,18 +75,22 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
|||
return;
|
||||
}
|
||||
|
||||
$app = new App('UTC');
|
||||
|
||||
$db = $register->get('dbPool')->get();
|
||||
$redis = $register->get('redisPool')->get();
|
||||
|
||||
$register->set('db', function () use (&$db) {
|
||||
App::setResource('db', function () use (&$db) {
|
||||
return $db;
|
||||
});
|
||||
|
||||
$register->set('cache', function () use (&$redis) {
|
||||
App::setResource('cache', function () use (&$redis) {
|
||||
return $redis;
|
||||
});
|
||||
|
||||
$app = new App('UTC');
|
||||
App::setResource('app', function() use (&$app) {
|
||||
return $app;
|
||||
});
|
||||
|
||||
try {
|
||||
Authorization::cleanRoles();
|
||||
|
|
59
app/init.php
59
app/init.php
|
@ -24,8 +24,6 @@ use Appwrite\Database\Database;
|
|||
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
||||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Pool\PDOPool;
|
||||
use Appwrite\Database\Pool\RedisPool;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Realtime;
|
||||
|
@ -37,6 +35,10 @@ use Utopia\Locale\Locale;
|
|||
use Utopia\Registry\Registry;
|
||||
use MaxMind\Db\Reader;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Swoole\Database\PDOConfig;
|
||||
use Swoole\Database\PDOPool;
|
||||
use Swoole\Database\RedisConfig;
|
||||
use Swoole\Database\RedisPool;
|
||||
|
||||
const APP_NAME = 'Appwrite';
|
||||
const APP_DOMAIN = 'appwrite.io';
|
||||
|
@ -155,10 +157,21 @@ Database::addFilter('encrypt',
|
|||
*/
|
||||
$register->set('dbPool', function () { // Register DB connection
|
||||
$dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = App::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
$pool = new PDOPool(10, $dbHost, $dbScheme, $dbUser, $dbPass);
|
||||
|
||||
|
||||
$pool = new PDOPool((new PDOConfig())
|
||||
->withHost($dbHost)
|
||||
->withPort($dbPort)
|
||||
// ->withUnixSocket('/tmp/mysql.sock')
|
||||
->withDbName($dbScheme)
|
||||
->withCharset('utf8mb4')
|
||||
->withUsername($dbUser)
|
||||
->withPassword($dbPass)
|
||||
);
|
||||
|
||||
return $pool;
|
||||
});
|
||||
|
@ -167,16 +180,18 @@ $register->set('redisPool', function () {
|
|||
$redisPort = App::getEnv('_APP_REDIS_PORT', '');
|
||||
$redisUser = App::getEnv('_APP_REDIS_USER', '');
|
||||
$redisPass = App::getEnv('_APP_REDIS_PASS', '');
|
||||
$redisAuth = [];
|
||||
$redisAuth = '';
|
||||
|
||||
if ($redisUser) {
|
||||
$redisAuth[] = $redisUser;
|
||||
}
|
||||
if ($redisPass) {
|
||||
$redisAuth[] = $redisPass;
|
||||
if ($redisUser && $redisPass) {
|
||||
$redisAuth = $redisUser.':'.$redisPass;
|
||||
}
|
||||
|
||||
$pool = new RedisPool(10, $redisHost, $redisPort, $redisAuth);
|
||||
$pool = new RedisPool((new RedisConfig)
|
||||
->withHost($redisHost)
|
||||
->withPort($redisPort)
|
||||
->withAuth($redisAuth)
|
||||
->withDbIndex(0)
|
||||
);
|
||||
|
||||
return $pool;
|
||||
});
|
||||
|
@ -327,10 +342,6 @@ App::setResource('events', function($register) {
|
|||
return new Event('', '');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('realtime', function($register) {
|
||||
return new Realtime('', '', []);
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('audits', function($register) {
|
||||
return new Event(Event::AUDITS_QUEUE_NAME, Event::AUDITS_CLASS_NAME);
|
||||
}, ['register']);
|
||||
|
@ -418,10 +429,9 @@ App::setResource('user', function($mode, $project, $console, $request, $response
|
|||
|
||||
if (APP_MODE_ADMIN !== $mode) {
|
||||
$user = $projectDB->getDocument(Auth::$unique);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$user = $consoleDB->getDocument(Auth::$unique);
|
||||
|
||||
|
||||
$user
|
||||
->setAttribute('$id', 'admin-'.$user->getAttribute('$id'))
|
||||
;
|
||||
|
@ -436,8 +446,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
|
|||
if (APP_MODE_ADMIN === $mode) {
|
||||
if (!empty($user->search('teamId', $project->getAttribute('teamId'), $user->getAttribute('memberships')))) {
|
||||
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]);
|
||||
}
|
||||
}
|
||||
|
@ -486,23 +495,23 @@ App::setResource('console', function($consoleDB) {
|
|||
return $consoleDB->getDocument('console');
|
||||
}, ['consoleDB']);
|
||||
|
||||
App::setResource('consoleDB', function($register) {
|
||||
App::setResource('consoleDB', function($db, $cache) {
|
||||
$consoleDB = new Database();
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$consoleDB->setNamespace('app_console'); // Should be replaced with param if we want to have parent projects
|
||||
$consoleDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
return $consoleDB;
|
||||
}, ['register']);
|
||||
}, ['db', 'cache']);
|
||||
|
||||
App::setResource('projectDB', function($register, $project) {
|
||||
App::setResource('projectDB', function($db, $cache, $project) {
|
||||
$projectDB = new Database();
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$projectDB->setNamespace('app_'.$project->getId());
|
||||
$projectDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
return $projectDB;
|
||||
}, ['register', 'project']);
|
||||
}, ['db', 'cache', 'project']);
|
||||
|
||||
App::setResource('mode', function($request) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
|
|
|
@ -32,6 +32,7 @@ foreach ([
|
|||
realpath(__DIR__ . '/../vendor/psr/log'),
|
||||
realpath(__DIR__ . '/../vendor/matomo'),
|
||||
realpath(__DIR__ . '/../vendor/symfony'),
|
||||
realpath(__DIR__ . '/../vendor/utopia-php/websocket'), // TODO: remove workerman autoload
|
||||
] as $key => $value) {
|
||||
if($value !== false) {
|
||||
$preloader->ignore($value);
|
||||
|
|
330
app/realtime.php
330
app/realtime.php
|
@ -1,39 +1,317 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Extend\PDO;
|
||||
use Appwrite\Realtime\Server;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Swoole\Runtime;
|
||||
use Swoole\Table;
|
||||
use Swoole\Timer;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Swoole\Request;
|
||||
use Utopia\Swoole\Response;
|
||||
use Utopia\WebSocket\Server;
|
||||
use Utopia\WebSocket\Adapter;
|
||||
|
||||
require_once __DIR__ . '/init.php';
|
||||
|
||||
Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
|
||||
$config = [
|
||||
'package_max_length' => 64000 // Default maximum Package Size (64kb)
|
||||
];
|
||||
$adapter = new Adapter\Swoole(port: App::getEnv('PORT', 80));
|
||||
$adapter->setPackageMaxLength(64000); // Default maximum Package Size (64kb)
|
||||
|
||||
$register->set('db', function () {
|
||||
$dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
$dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
$subscriptions = [];
|
||||
$connections = [];
|
||||
|
||||
$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,
|
||||
));
|
||||
$stats = new Table(4096, 1);
|
||||
$stats->column('projectId', Table::TYPE_STRING, 64);
|
||||
$stats->column('connections', Table::TYPE_INT);
|
||||
$stats->column('connectionsTotal', Table::TYPE_INT);
|
||||
$stats->column('messages', Table::TYPE_INT);
|
||||
$stats->create();
|
||||
|
||||
return $pdo;
|
||||
});
|
||||
$register->set('cache', function () { // Register cache connection
|
||||
$redis = new Redis();
|
||||
$redis->pconnect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
||||
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
|
||||
$server = new Server($adapter);
|
||||
|
||||
return $redis;
|
||||
$realtime = new Realtime();
|
||||
|
||||
$server->onStart(function () use ($stats) {
|
||||
Console::success('Server started succefully');
|
||||
|
||||
Timer::tick(10000, function () use ($stats) {
|
||||
foreach ($stats as $projectId => $value) {
|
||||
if (empty($value['connections']) && empty($value['messages'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$connections = $value['connections'];
|
||||
$messages = $value['messages'];
|
||||
|
||||
$usage = new Event('v1-usage', 'UsageV1');
|
||||
$usage
|
||||
->setParam('projectId', $projectId)
|
||||
->setParam('realtimeConnections', $connections)
|
||||
->setParam('realtimeMessages', $messages)
|
||||
->setParam('networkRequestSize', 0)
|
||||
->setParam('networkResponseSize', 0);
|
||||
|
||||
$stats->set($projectId, [
|
||||
'projectId' => $projectId,
|
||||
'messages' => 0,
|
||||
'connections' => 0
|
||||
]);
|
||||
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$usage->trigger();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$realtimeServer = new Server($register, port: App::getEnv('PORT', 80), config: $config);
|
||||
$server->onWorkerStart(function (int $workerId) use ($server, $register, $stats, $realtime) {
|
||||
Console::success('Worker ' . $workerId . ' started succefully');
|
||||
|
||||
$attempts = 0;
|
||||
$start = time();
|
||||
$redisPool = $register->get('redisPool');
|
||||
|
||||
/**
|
||||
* Sending current connections to project channels on the console project every 5 seconds.
|
||||
*/
|
||||
Timer::tick(5000, function () use ($server, $stats, $realtime) {
|
||||
if ($realtime->hasSubscriber('console', 'role:member', 'project')) {
|
||||
$payload = [];
|
||||
foreach ($stats as $projectId => $value) {
|
||||
$payload[$projectId] = $value['connectionsTotal'];
|
||||
}
|
||||
|
||||
$event = [
|
||||
'event' => 'stats.connections',
|
||||
'channels' => ['project'],
|
||||
'permissions' => ['role:member'],
|
||||
'timestamp' => time(),
|
||||
'payload' => $payload
|
||||
];
|
||||
|
||||
$server->send($realtime->getReceivers($event), json_encode($event));
|
||||
}
|
||||
});
|
||||
|
||||
while ($attempts < 300) {
|
||||
try {
|
||||
if ($attempts > 0) {
|
||||
Console::error('Pub/sub connection lost (lasted ' . (time() - $start) . ' seconds, worker: ' . $workerId . ').
|
||||
Attempting restart in 5 seconds (attempt #' . $attempts . ')');
|
||||
sleep(5); // 5 sec delay between connection attempts
|
||||
}
|
||||
$start = time();
|
||||
|
||||
/** @var Redis $redis */
|
||||
$redis = $redisPool->get();
|
||||
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
if ($redis->ping(true)) {
|
||||
$attempts = 0;
|
||||
Console::success('Pub/sub connection established (worker: ' . $workerId . ')');
|
||||
} else {
|
||||
Console::error('Pub/sub failed (worker: ' . $workerId . ')');
|
||||
}
|
||||
|
||||
$redis->subscribe(['realtime'], function ($redis, $channel, $payload) use ($server, $workerId, $stats, $register, $realtime) {
|
||||
$event = json_decode($payload, true);
|
||||
|
||||
if ($event['permissionsChanged'] && isset($event['userId'])) {
|
||||
$projectId = $event['project'];
|
||||
$userId = $event['userId'];
|
||||
|
||||
if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) {
|
||||
$connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId]));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = $register->get('dbPool')->get();
|
||||
$cache = $register->get('redisPool')->get();
|
||||
|
||||
$projectDB = new Database();
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$projectDB->setNamespace('app_' . $projectId);
|
||||
$projectDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
$user = $projectDB->getDocument($userId);
|
||||
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
$realtime->subscribe($projectId, $connection, $roles, $realtime->connections[$connection]['channels']);
|
||||
|
||||
$register->get('dbPool')->put($db);
|
||||
$register->get('redisPool')->put($cache);
|
||||
}
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
// Temporarily print debug logs by default for Alpha testing.
|
||||
// if (App::isDevelopment() && !empty($receivers)) {
|
||||
if (!empty($receivers)) {
|
||||
Console::log("[Debug][Worker {$workerId}] Receivers: " . count($receivers));
|
||||
Console::log("[Debug][Worker {$workerId}] Receivers Connection IDs: " . json_encode($receivers));
|
||||
Console::log("[Debug][Worker {$workerId}] Event: " . $payload);
|
||||
}
|
||||
|
||||
$server->send(
|
||||
$receivers,
|
||||
json_encode($event['data'])
|
||||
);
|
||||
|
||||
if (($num = count($receivers)) > 0) {
|
||||
$stats->incr($event['project'], 'messages', $num);
|
||||
}
|
||||
});
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Pub/sub error: ' . $th->getMessage());
|
||||
$redisPool->put($redis);
|
||||
$attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$attempts++;
|
||||
}
|
||||
|
||||
Console::error('Failed to restart pub/sub...');
|
||||
});
|
||||
|
||||
$server->onOpen(function (int $connection, SwooleRequest $request) use ($server, $register, $stats, &$realtime) {
|
||||
$app = new App('UTC');
|
||||
$request = new Request($request);
|
||||
|
||||
/** @var PDO $db */
|
||||
$db = $register->get('dbPool')->get();
|
||||
/** @var Redis $redis */
|
||||
$redis = $register->get('redisPool')->get();
|
||||
|
||||
Console::info("Connection open (user: {$connection})");
|
||||
|
||||
App::setResource('db', function () use (&$db) {
|
||||
return $db;
|
||||
});
|
||||
|
||||
App::setResource('cache', function () use (&$redis) {
|
||||
return $redis;
|
||||
});
|
||||
|
||||
App::setResource('request', function () use ($request) {
|
||||
return $request;
|
||||
});
|
||||
|
||||
App::setResource('response', function () {
|
||||
return new Response(new SwooleResponse());
|
||||
});
|
||||
|
||||
try {
|
||||
/** @var \Appwrite\Database\Document $user */
|
||||
$user = $app->getResource('user');
|
||||
|
||||
/** @var \Appwrite\Database\Document $project */
|
||||
$project = $app->getResource('project');
|
||||
|
||||
/** @var \Appwrite\Database\Document $console */
|
||||
$console = $app->getResource('console');
|
||||
|
||||
/*
|
||||
* Project Check
|
||||
*/
|
||||
if (empty($project->getId())) {
|
||||
throw new Exception('Missing or unknown project ID', 1008);
|
||||
}
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
*
|
||||
* Abuse limits are connecting 128 times per minute and ip address.
|
||||
*/
|
||||
$timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, $db);
|
||||
$timeLimit
|
||||
->setNamespace('app_' . $project->getId())
|
||||
->setParam('{ip}', $request->getIP())
|
||||
->setParam('{url}', $request->getURI());
|
||||
|
||||
$abuse = new Abuse($timeLimit);
|
||||
|
||||
if ($abuse->check() && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
|
||||
throw new Exception('Too many requests', 1013);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate Client Domain - Check to avoid CSRF attack.
|
||||
* Adding Appwrite API domains to allow XDOMAIN communication.
|
||||
* Skip this check for non-web platforms which are not required to send an origin header.
|
||||
*/
|
||||
$origin = $request->getOrigin();
|
||||
$originValidator = new Origin(\array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', [])));
|
||||
|
||||
if (!$originValidator->isValid($origin) && $project->getId() !== 'console') {
|
||||
throw new Exception($originValidator->getDescription(), 1008);
|
||||
}
|
||||
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
$channels = Realtime::convertChannels($request->getQuery('channels', []), $user);
|
||||
|
||||
/**
|
||||
* Channels Check
|
||||
*/
|
||||
if (empty($channels)) {
|
||||
throw new Exception('Missing channels', 1008);
|
||||
}
|
||||
|
||||
$realtime->subscribe($project->getId(), $connection, $roles, $channels);
|
||||
|
||||
$server->send([$connection], json_encode($channels));
|
||||
|
||||
$stats->incr($project->getId(), 'connections');
|
||||
$stats->incr($project->getId(), 'connectionsTotal');
|
||||
} catch (\Throwable $th) {
|
||||
$response = [
|
||||
'code' => $th->getCode(),
|
||||
'message' => $th->getMessage()
|
||||
];
|
||||
// Temporarily print debug logs by default for Alpha testing.
|
||||
//if (App::isDevelopment()) {
|
||||
Console::error("[Error] Connection Error");
|
||||
Console::error("[Error] Code: " . $response['code']);
|
||||
Console::error("[Error] Message: " . $response['message']);
|
||||
//}
|
||||
$server->send([$connection], json_encode($response));
|
||||
$server->close($connection, $th->getCode());
|
||||
} finally {
|
||||
/**
|
||||
* Put used PDO and Redis Connections back into their pools.
|
||||
*/
|
||||
$register->get('dbPool')->put($db);
|
||||
$register->get('redisPool')->put($redis);
|
||||
}
|
||||
});
|
||||
|
||||
$server->onMessage(function (int $connection, string $message) use ($server) {
|
||||
$server->send([$connection], 'Sending messages is not allowed.');
|
||||
$server->close($connection, 1003);
|
||||
});
|
||||
|
||||
$server->onClose(function (int $connection) use ($realtime, $stats) {
|
||||
if (array_key_exists($connection, $realtime->connections)) {
|
||||
$stats->decr($realtime->connections[$connection]['projectId'], 'connectionsTotal');
|
||||
}
|
||||
$realtime->unsubscribe($connection);
|
||||
|
||||
Console::info('Connection close: ' . $connection);
|
||||
});
|
||||
|
||||
$server->start();
|
||||
|
|
|
@ -17,13 +17,13 @@ $cli
|
|||
|
||||
$consoleDB = new Database();
|
||||
$consoleDB
|
||||
->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register))
|
||||
->setAdapter(new RedisAdapter(new MySQLAdapter($register->get('db'), $register->get('cache')), $register->get('cache')))
|
||||
->setNamespace('app_console') // Main DB
|
||||
->setMocks(Config::getParam('collections', []));
|
||||
|
||||
$projectDB = new Database();
|
||||
$projectDB
|
||||
->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register))
|
||||
->setAdapter(new RedisAdapter(new MySQLAdapter($register->get('db'), $register->get('cache')), $register->get('cache')))
|
||||
->setMocks(Config::getParam('collections', []));
|
||||
|
||||
$console = $consoleDB->getDocument('console');
|
||||
|
|
|
@ -28,7 +28,7 @@ $cli
|
|||
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
|
||||
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
|
||||
|
||||
if(!in_array($version, ['0.6.x', '0.7.x', '0.8.x'])) {
|
||||
if(!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x'])) {
|
||||
throw new Exception('Unknown version given');
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,8 @@
|
|||
|
||||
<input type="hidden" id="collection-read" name="read" required data-cast-to="json" value="<?php echo htmlentities(json_encode([])); ?>" />
|
||||
<input type="hidden" id="collection-write" name="write" required data-cast-to="json" value="<?php echo htmlentities(json_encode([])); ?>" />
|
||||
|
||||
<input type="hidden" id="collection-rules" name="rules" required data-cast-to="json" value="{}" />
|
||||
|
||||
<hr />
|
||||
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
|
|
|
@ -46,9 +46,9 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled',true);
|
|||
|
||||
<div class="box margin-bottom-large">
|
||||
<div class="text-align-center">
|
||||
<img src="" data-ls-attrs="src=/images/runtimes/{{project-function.env|envLogo}}" alt="Function Env." class="avatar huge margin-top-negative-xxl" />
|
||||
<img src="" data-ls-attrs="src=/images/runtimes/{{project-function.runtime|runtimeLogo}}" alt="Function Runtime" class="avatar huge margin-top-negative-xxl" />
|
||||
|
||||
<p class="text-fade margin-bottom-small" data-ls-bind="{{project-function.env|envName}} {{project-function.env|envVersion}}">
|
||||
<p class="text-fade margin-bottom-small" data-ls-bind="{{project-function.runtime|runtimeName}} {{project-function.runtime|runtimeVersion}}">
|
||||
</p>
|
||||
<div data-ls-if="{{project-function.tag}} !== ''" class="margin-top">
|
||||
<button data-ls-ui-trigger="execute-now">Execute Now</button> <a data-ls-attrs="href=/console/functions/function/logs?id={{router.params.id}}&project={{router.params.project}}" class="button reverse" style="vertical-align: top;">View Logs</a>
|
||||
|
|
|
@ -40,14 +40,14 @@ $runtimes = $this->getParam('runtimes', []);
|
|||
<ul data-ls-loop="project-functions.functions" data-ls-as="function" class="list">
|
||||
<li class="clear">
|
||||
<div class="pull-start margin-end avatar-container">
|
||||
<img src="" data-ls-attrs="src=/images/runtimes/{{function.env|envLogo}}?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Function Env." class="avatar" loading="lazy" width="60" height="60" />
|
||||
<img src="" data-ls-attrs="src=/images/runtimes/{{function.runtime|runtimeLogo}}?v=<?php echo APP_CACHE_BUSTER; ?>" alt="Function Runtime" class="avatar" loading="lazy" width="60" height="60" />
|
||||
</div>
|
||||
|
||||
<a data-ls-attrs="href=/console/functions/function?id={{function.$id}}&project={{router.params.project}}" class="button pull-end">Settings</a>
|
||||
|
||||
<span data-ls-bind="{{function.name}}"></span>
|
||||
|
||||
<p class="text-fade margin-bottom-no" data-ls-bind="{{function.env|envName}} {{function.env|envVersion}}"></p>
|
||||
<p class="text-fade margin-bottom-no" data-ls-bind="{{function.runtime|runtimeName}} {{function.runtime|runtimeVersion}}"></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -109,13 +109,15 @@ $runtimes = $this->getParam('runtimes', []);
|
|||
<label for="name">Name</label>
|
||||
<input type="text" id="name" name="name" required autocomplete="off" class="margin-bottom" maxlength="128" />
|
||||
|
||||
<label for="env">Runtimes</label>
|
||||
<select name="env" id="env" required class="margin-bottom-xl">
|
||||
<label for="runtime">Runtimes</label>
|
||||
<select name="runtime" id="runtime" required class="margin-bottom-xl">
|
||||
<?php foreach($runtimes as $key => $runtime): ?>
|
||||
<option value="<?php echo $this->escape($key); ?>"><?php echo $this->escape($runtime['name']); ?> <?php echo $this->escape($runtime['version']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<input id="execute" name="execute" value="" hidden/>
|
||||
|
||||
<footer>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
</footer>
|
||||
|
|
|
@ -28,8 +28,11 @@ class CertificatesV1 extends Worker
|
|||
{
|
||||
global $register;
|
||||
|
||||
$db = $register->get('db');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
$consoleDB = new Database();
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$consoleDB->setNamespace('app_console'); // Main DB
|
||||
$consoleDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class DeletesV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
$projectId = isset($this->args['projectId']) ? $this->args['projectId'] : '';
|
||||
$projectId = isset($this->args['projectId']) ? $this->args['projectId'] : '';
|
||||
$type = $this->args['type'];
|
||||
|
||||
switch (strval($type)) {
|
||||
|
@ -51,6 +51,9 @@ class DeletesV1 extends Worker
|
|||
case Database::SYSTEM_COLLECTION_COLLECTIONS:
|
||||
$this->deleteDocuments($document, $projectId);
|
||||
break;
|
||||
case Database::SYSTEM_COLLECTION_TEAMS:
|
||||
$this->deleteMemberships($document, $projectId);
|
||||
break;
|
||||
default:
|
||||
Console::error('No lazy delete operation available for document of type: '.$document->getCollection());
|
||||
break;
|
||||
|
@ -99,6 +102,14 @@ class DeletesV1 extends Worker
|
|||
], $this->getProjectDB($projectId));
|
||||
}
|
||||
|
||||
protected function deleteMemberships(Document $document, $projectId) {
|
||||
// Delete Memberships
|
||||
$this->deleteByGroup([
|
||||
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'teamId='.$document->getId(),
|
||||
], $this->getProjectDB($projectId));
|
||||
}
|
||||
|
||||
protected function deleteProject(Document $document)
|
||||
{
|
||||
// Delete all DBs
|
||||
|
@ -169,9 +180,7 @@ class DeletesV1 extends Worker
|
|||
throw new Exception('Failed to delete audit logs. No timestamp provided');
|
||||
}
|
||||
|
||||
$timeLimit = new TimeLimit("", 0, 1, function () use ($register) {
|
||||
return $register->get('db');
|
||||
});
|
||||
$timeLimit = new TimeLimit("", 0, 1, $register->get('db'));
|
||||
|
||||
$this->deleteForProjectIds(function($projectId) use ($timeLimit, $timestamp){
|
||||
$timeLimit->setNamespace('app_'.$projectId);
|
||||
|
@ -229,7 +238,7 @@ class DeletesV1 extends Worker
|
|||
Console::success('Delete code tag: '.$document->getAttribute('path', ''));
|
||||
}
|
||||
else {
|
||||
Console::error('Dailed to delete code tag: '.$document->getAttribute('path', ''));
|
||||
Console::error('Failed to delete code tag: '.$document->getAttribute('path', ''));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -277,7 +286,6 @@ class DeletesV1 extends Worker
|
|||
Authorization::disable();
|
||||
$projects = $this->getConsoleDB()->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $count,
|
||||
'orderType' => 'ASC',
|
||||
'orderCast' => 'string',
|
||||
'filters' => [
|
||||
|
@ -320,7 +328,6 @@ class DeletesV1 extends Worker
|
|||
|
||||
$results = $database->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $count,
|
||||
'orderField' => '$id',
|
||||
'orderType' => 'ASC',
|
||||
'orderCast' => 'string',
|
||||
|
@ -366,9 +373,12 @@ class DeletesV1 extends Worker
|
|||
{
|
||||
global $register;
|
||||
|
||||
$db = $register->get('db');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
if($this->consoleDB === null) {
|
||||
$this->consoleDB = new Database();
|
||||
$this->consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$this->consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));;
|
||||
$this->consoleDB->setNamespace('app_console'); // Main DB
|
||||
$this->consoleDB->setMocks(Config::getParam('collections', []));
|
||||
}
|
||||
|
@ -382,9 +392,12 @@ class DeletesV1 extends Worker
|
|||
protected function getProjectDB($projectId): Database
|
||||
{
|
||||
global $register;
|
||||
|
||||
|
||||
$db = $register->get('db');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
$projectDB = new Database();
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$projectDB->setNamespace('app_'.$projectId); // Main DB
|
||||
$projectDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
|||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Appwrite\Resque\Worker;
|
||||
use Appwrite\Utopia\Response\Model\Execution;
|
||||
use Cron\CronExpression;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\App;
|
||||
|
@ -72,9 +73,6 @@ Console::success('Finished warmup in '.$warmupTime.' seconds');
|
|||
$stdout = '';
|
||||
$stderr = '';
|
||||
|
||||
$exitCode = Console::execute('docker ps --all --format "name={{.Names}}&status={{.Status}}&labels={{.Labels}}" --filter label=appwrite-type=function'
|
||||
, '', $stdout, $stderr, 30);
|
||||
|
||||
$executionStart = \microtime(true);
|
||||
|
||||
$exitCode = Console::execute('docker ps --all --format "name={{.Names}}&status={{.Status}}&labels={{.Labels}}" --filter label=appwrite-type=function'
|
||||
|
@ -141,6 +139,9 @@ class FunctionsV1 extends Worker
|
|||
{
|
||||
global $register;
|
||||
|
||||
$db = $register->get('db');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
$projectId = $this->args['projectId'] ?? '';
|
||||
$functionId = $this->args['functionId'] ?? '';
|
||||
$webhooks = $this->args['webhooks'] ?? [];
|
||||
|
@ -154,7 +155,7 @@ class FunctionsV1 extends Worker
|
|||
$jwt = $this->args['jwt'] ?? '';
|
||||
|
||||
$database = new Database();
|
||||
$database->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$database->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$database->setNamespace('app_'.$projectId);
|
||||
$database->setMocks(Config::getParam('collections', []));
|
||||
|
||||
|
@ -332,12 +333,12 @@ class FunctionsV1 extends Worker
|
|||
|
||||
Authorization::reset();
|
||||
|
||||
$runtime = (isset($runtimes[$function->getAttribute('env', '')]))
|
||||
? $runtimes[$function->getAttribute('env', '')]
|
||||
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')]))
|
||||
? $runtimes[$function->getAttribute('runtime', '')]
|
||||
: null;
|
||||
|
||||
if(\is_null($runtime)) {
|
||||
throw new Exception('Environment "'.$function->getAttribute('env', '').' is not supported');
|
||||
throw new Exception('Runtime "'.$function->getAttribute('runtime', '').' is not supported');
|
||||
}
|
||||
|
||||
$vars = \array_merge($function->getAttribute('vars', []), [
|
||||
|
@ -481,6 +482,7 @@ class FunctionsV1 extends Worker
|
|||
throw new Exception('Failed saving execution to DB', 500);
|
||||
}
|
||||
|
||||
$executionModel = new Execution();
|
||||
$executionUpdate = new Event('v1-webhooks', 'WebhooksV1');
|
||||
|
||||
$executionUpdate
|
||||
|
@ -488,13 +490,19 @@ class FunctionsV1 extends Worker
|
|||
->setParam('userId', $userId)
|
||||
->setParam('webhooks', $webhooks)
|
||||
->setParam('event', 'functions.executions.update')
|
||||
->setParam('payload', $execution->getArrayCopy());
|
||||
->setParam('eventData', $execution->getArrayCopy(array_keys($executionModel->getRules())));
|
||||
|
||||
$executionUpdate->trigger();
|
||||
|
||||
$realtimeUpdate = new Realtime($projectId, 'functions.executions.update', $execution->getArrayCopy());
|
||||
$target = Realtime::fromPayload('functions.executions.update', $execution);
|
||||
|
||||
$realtimeUpdate->trigger();
|
||||
Realtime::send(
|
||||
$projectId,
|
||||
$execution->getArrayCopy(),
|
||||
'functions.executions.update',
|
||||
$target['channels'],
|
||||
$target['permissions']
|
||||
);
|
||||
|
||||
$usage = new Event('v1-usage', 'UsageV1');
|
||||
|
||||
|
@ -531,7 +539,7 @@ class FunctionsV1 extends Worker
|
|||
if(\count($list) > $max) {
|
||||
Console::info('Starting containers cleanup');
|
||||
|
||||
\usort($list, function ($item1, $item2) {
|
||||
\uasort($list, function ($item1, $item2) {
|
||||
return (int)($item1['appwrite-created'] ?? 0) <=> (int)($item2['appwrite-created'] ?? 0);
|
||||
});
|
||||
|
||||
|
|
|
@ -30,8 +30,11 @@ class TasksV1 extends Worker
|
|||
{
|
||||
global $register;
|
||||
|
||||
$db = $register->get('db');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
$consoleDB = new Database();
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$consoleDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
|
||||
$consoleDB->setNamespace('app_console'); // Main DB
|
||||
$consoleDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
REDIS_BACKEND=$REDIS_BACKEND RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler
|
||||
INTERVAL=1 REDIS_BACKEND=$REDIS_BACKEND RESQUE_PHP='/usr/src/code/vendor/autoload.php' php /usr/src/code/vendor/bin/resque-scheduler
|
||||
|
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=1 QUEUE='v1-audits' APP_INCLUDE='/usr/src/code/app/workers/audits.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
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
|
||||
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
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
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
|
||||
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
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=0.1 QUEUE='v1-functions' APP_INCLUDE='/usr/src/code/app/workers/functions.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=1 QUEUE='v1-mails' APP_INCLUDE='/usr/src/code/app/workers/mails.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=0.1 QUEUE='v1-tasks' APP_INCLUDE='/usr/src/code/app/workers/tasks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=1 QUEUE='v1-usage' APP_INCLUDE='/usr/src/code/app/workers/usage.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -7,4 +7,4 @@ else
|
|||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=0.1 QUEUE='v1-webhooks' APP_INCLUDE='/usr/src/code/app/workers/webhooks.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
|
@ -36,10 +36,10 @@
|
|||
"ext-sockets": "*",
|
||||
|
||||
"appwrite/php-clamav": "1.1.*",
|
||||
"appwrite/php-runtimes": "0.2.*",
|
||||
"appwrite/php-runtimes": "0.3.*",
|
||||
|
||||
"utopia-php/framework": "0.14.*",
|
||||
"utopia-php/abuse": "0.4.*",
|
||||
"utopia-php/abuse": "0.5.*",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"utopia-php/audit": "0.5.*",
|
||||
"utopia-php/cache": "0.2.*",
|
||||
|
@ -51,23 +51,30 @@
|
|||
"utopia-php/domains": "1.1.*",
|
||||
"utopia-php/swoole": "0.2.*",
|
||||
"utopia-php/storage": "0.5.*",
|
||||
"utopia-php/image": "0.3.*",
|
||||
"utopia-php/websocket": "dev-fix-adapter-interface",
|
||||
"utopia-php/image": "0.5.*",
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "4.2.2",
|
||||
"matomo/device-detector": "4.2.3",
|
||||
"dragonmantank/cron-expression": "3.1.0",
|
||||
"influxdb/influxdb-php": "1.15.2",
|
||||
"phpmailer/phpmailer": "6.4.1",
|
||||
"phpmailer/phpmailer": "6.5.0",
|
||||
"chillerlan/php-qrcode": "4.3.0",
|
||||
"adhocore/jwt": "1.1.2",
|
||||
"slickdeals/statsd": "3.0.2"
|
||||
"slickdeals/statsd": "3.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"appwrite/sdk-generator": "0.10.11",
|
||||
"swoole/ide-helper": "4.6.6",
|
||||
"textalk/websocket": "1.5.2",
|
||||
"phpunit/phpunit": "9.5.4",
|
||||
"swoole/ide-helper": "4.6.7",
|
||||
"phpunit/phpunit": "9.5.6",
|
||||
"vimeo/psalm": "4.7.2"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/websocket.git"
|
||||
}
|
||||
],
|
||||
"provide": {
|
||||
"ext-phpiredis": "*"
|
||||
},
|
||||
|
|
192
composer.lock
generated
192
composer.lock
generated
|
@ -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": "ecfe641507c78e5e886eeece09c01d50",
|
||||
"content-hash": "9ad1f9e6ce5583eb13ea6ffa9a93cb97",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -115,16 +115,16 @@
|
|||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/php-runtimes.git",
|
||||
"reference": "43ec4e91cecb9bba0015ef26ab3736cbee2055f5"
|
||||
"reference": "39be003cdff22c8447de151921001eb5d3bf2319"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/php-runtimes/zipball/43ec4e91cecb9bba0015ef26ab3736cbee2055f5",
|
||||
"reference": "43ec4e91cecb9bba0015ef26ab3736cbee2055f5",
|
||||
"url": "https://api.github.com/repos/appwrite/php-runtimes/zipball/39be003cdff22c8447de151921001eb5d3bf2319",
|
||||
"reference": "39be003cdff22c8447de151921001eb5d3bf2319",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -164,9 +164,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/php-runtimes/issues",
|
||||
"source": "https://github.com/appwrite/php-runtimes/tree/0.2.0"
|
||||
"source": "https://github.com/appwrite/php-runtimes/tree/0.3.0"
|
||||
},
|
||||
"time": "2021-04-22T20:47:42+00:00"
|
||||
"time": "2021-06-15T07:52:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
|
@ -715,16 +715,16 @@
|
|||
},
|
||||
{
|
||||
"name": "matomo/device-detector",
|
||||
"version": "4.2.2",
|
||||
"version": "4.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matomo-org/device-detector.git",
|
||||
"reference": "dc270e7645d286d6f01d516a6634aba8b31ad668"
|
||||
"reference": "d879f07496d6e6ee89cef5bcd925383d9b0c2cc0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/dc270e7645d286d6f01d516a6634aba8b31ad668",
|
||||
"reference": "dc270e7645d286d6f01d516a6634aba8b31ad668",
|
||||
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/d879f07496d6e6ee89cef5bcd925383d9b0c2cc0",
|
||||
"reference": "d879f07496d6e6ee89cef5bcd925383d9b0c2cc0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -780,7 +780,7 @@
|
|||
"source": "https://github.com/matomo-org/matomo",
|
||||
"wiki": "https://dev.matomo.org/"
|
||||
},
|
||||
"time": "2021-02-26T07:31:42+00:00"
|
||||
"time": "2021-05-12T14:14:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mustangostang/spyc",
|
||||
|
@ -834,16 +834,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.4.1",
|
||||
"version": "v6.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d"
|
||||
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d",
|
||||
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c",
|
||||
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -898,7 +898,7 @@
|
|||
"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.4.1"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -906,7 +906,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-29T12:25:04+00:00"
|
||||
"time": "2021-06-16T14:33:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
|
@ -1192,31 +1192,33 @@
|
|||
},
|
||||
{
|
||||
"name": "slickdeals/statsd",
|
||||
"version": "3.0.2",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Slickdeals/statsd-php.git",
|
||||
"reference": "393c6565efbfb23c8296ae3099a62fb6366c6ce3"
|
||||
"reference": "225588a0a079e145359049f6e5e23eedb1b4c17f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/393c6565efbfb23c8296ae3099a62fb6366c6ce3",
|
||||
"reference": "393c6565efbfb23c8296ae3099a62fb6366c6ce3",
|
||||
"url": "https://api.github.com/repos/Slickdeals/statsd-php/zipball/225588a0a079e145359049f6e5e23eedb1b4c17f",
|
||||
"reference": "225588a0a079e145359049f6e5e23eedb1b4c17f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">= 7.2"
|
||||
"php": ">= 7.3 || ^8"
|
||||
},
|
||||
"replace": {
|
||||
"domnikl/statsd": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"flyeralarm/php-code-validator": "^2.2",
|
||||
"phpunit/phpunit": "~8.0",
|
||||
"vimeo/psalm": "^3.4"
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"phpunit/phpunit": "^9",
|
||||
"vimeo/psalm": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Domnikl\\Statsd\\": "src/",
|
||||
"Domnikl\\Test\\Statsd\\": "tests/unit"
|
||||
"Domnikl\\Statsd\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
|
@ -1230,7 +1232,7 @@
|
|||
}
|
||||
],
|
||||
"description": "a PHP client for statsd",
|
||||
"homepage": "https://domnikl.github.com/statsd-php",
|
||||
"homepage": "https://github.com/Slickdeals/statsd-php",
|
||||
"keywords": [
|
||||
"Metrics",
|
||||
"monitoring",
|
||||
|
@ -1239,9 +1241,10 @@
|
|||
"udp"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/Slickdeals/statsd-php/tree/3.0.2"
|
||||
"issues": "https://github.com/Slickdeals/statsd-php/issues",
|
||||
"source": "https://github.com/Slickdeals/statsd-php/tree/3.1.0"
|
||||
},
|
||||
"time": "2020-01-03T14:24:58+00:00"
|
||||
"time": "2021-06-04T20:33:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
|
@ -1324,16 +1327,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "8b7973aae4b02489bd22ffea45b985608f13b6d9"
|
||||
"reference": "339c1720e5aa5314276128170463594b81f84760"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/8b7973aae4b02489bd22ffea45b985608f13b6d9",
|
||||
"reference": "8b7973aae4b02489bd22ffea45b985608f13b6d9",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/339c1720e5aa5314276128170463594b81f84760",
|
||||
"reference": "339c1720e5aa5314276128170463594b81f84760",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1370,9 +1373,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.4.1"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.5.0"
|
||||
},
|
||||
"time": "2021-06-05T14:31:33+00:00"
|
||||
"time": "2021-06-28T10:11:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
|
@ -1431,21 +1434,21 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.5.1",
|
||||
"version": "0.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "154a850170a58667a15e4b65fbabb6cd0b709dd9"
|
||||
"reference": "57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/154a850170a58667a15e4b65fbabb6cd0b709dd9",
|
||||
"reference": "154a850170a58667a15e4b65fbabb6cd0b709dd9",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4",
|
||||
"reference": "57e4f8f932164bdfd48ec32bf8d7d3f1bf7518e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pdo": "*",
|
||||
"php": ">=7.1"
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3",
|
||||
|
@ -1477,9 +1480,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.5.1"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.5.2"
|
||||
},
|
||||
"time": "2020-12-21T17:28:53+00:00"
|
||||
"time": "2021-06-23T16:02:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
|
@ -1742,16 +1745,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.3.2",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "2044fdd44d87c4253cfe929cca975fd037461b00"
|
||||
"reference": "5b4ac25e70a95fa10b39c129b742ac66748d40b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/2044fdd44d87c4253cfe929cca975fd037461b00",
|
||||
"reference": "2044fdd44d87c4253cfe929cca975fd037461b00",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/5b4ac25e70a95fa10b39c129b742ac66748d40b8",
|
||||
"reference": "5b4ac25e70a95fa10b39c129b742ac66748d40b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1789,9 +1792,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.3.2"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.5.0"
|
||||
},
|
||||
"time": "2021-06-10T09:16:11+00:00"
|
||||
"time": "2021-06-25T03:40:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
|
@ -2003,16 +2006,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/swoole.git",
|
||||
"reference": "45c42aae7e7d3f9f82bf194c2cfa5499b674aefe"
|
||||
"reference": "37d8c64b536d6bc7da4f0f5a934a0ec44885abf4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/45c42aae7e7d3f9f82bf194c2cfa5499b674aefe",
|
||||
"reference": "45c42aae7e7d3f9f82bf194c2cfa5499b674aefe",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/37d8c64b536d6bc7da4f0f5a934a0ec44885abf4",
|
||||
"reference": "37d8c64b536d6bc7da4f0f5a934a0ec44885abf4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2053,9 +2056,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/swoole/issues",
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.2.3"
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.2.4"
|
||||
},
|
||||
"time": "2021-03-22T22:39:24+00:00"
|
||||
"time": "2021-06-22T10:49:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/system",
|
||||
|
@ -2112,6 +2115,53 @@
|
|||
},
|
||||
"time": "2021-02-04T14:14:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
"version": "dev-fix-adapter-interface",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/websocket.git",
|
||||
"reference": "0cff9078e8acdb99f2bb8b30a578d0137bd460de"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
],
|
||||
"time": "2021-06-29T16:04:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.10.0",
|
||||
|
@ -3817,16 +3867,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.4",
|
||||
"version": "9.5.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "c73c6737305e779771147af66c96ca6a7ed8a741"
|
||||
"reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741",
|
||||
"reference": "c73c6737305e779771147af66c96ca6a7ed8a741",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
|
||||
"reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3856,7 +3906,7 @@
|
|||
"sebastian/global-state": "^5.0.1",
|
||||
"sebastian/object-enumerator": "^4.0.3",
|
||||
"sebastian/resource-operations": "^3.0.3",
|
||||
"sebastian/type": "^2.3",
|
||||
"sebastian/type": "^2.3.4",
|
||||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -3904,7 +3954,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.4"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3916,7 +3966,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-23T07:16:29+00:00"
|
||||
"time": "2021-06-23T05:14:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
@ -4932,16 +4982,16 @@
|
|||
},
|
||||
{
|
||||
"name": "swoole/ide-helper",
|
||||
"version": "4.6.6",
|
||||
"version": "4.6.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swoole/ide-helper.git",
|
||||
"reference": "d29d71267f8ed4e4993dc057ca53ffdb5d2703b7"
|
||||
"reference": "0d1409b8274117addfe64d3ea412812a69807411"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/d29d71267f8ed4e4993dc057ca53ffdb5d2703b7",
|
||||
"reference": "d29d71267f8ed4e4993dc057ca53ffdb5d2703b7",
|
||||
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/0d1409b8274117addfe64d3ea412812a69807411",
|
||||
"reference": "0d1409b8274117addfe64d3ea412812a69807411",
|
||||
"shasum": ""
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -4964,7 +5014,7 @@
|
|||
"description": "IDE help files for Swoole.",
|
||||
"support": {
|
||||
"issues": "https://github.com/swoole/ide-helper/issues",
|
||||
"source": "https://github.com/swoole/ide-helper/tree/4.6.6"
|
||||
"source": "https://github.com/swoole/ide-helper/tree/4.6.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -4980,7 +5030,7 @@
|
|||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-22T16:38:11+00:00"
|
||||
"time": "2021-05-14T16:05:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
@ -6052,7 +6102,9 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"utopia-php/websocket": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Use this endpoint to allow a new user to register an anonymous account in your project. This route will also create a new session for the user. To allow the new user to convert an anonymous account to a normal account account, you need to update its [email and password](/docs/client/account#accountUpdateEmail).
|
||||
Use this endpoint to allow a new user to register an anonymous account in your project. This route will also create a new session for the user. To allow the new user to convert an anonymous account to a normal account, you need to update its [email and password](/docs/client/account#accountUpdateEmail) or create an [OAuth2 session](/docs/client/account#accountCreateOAuth2Session).
|
1
docs/references/account/get-session.md
Normal file
1
docs/references/account/get-session.md
Normal file
|
@ -0,0 +1 @@
|
|||
Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used.
|
5658
package-lock.json
generated
5658
package-lock.json
generated
File diff suppressed because it is too large
Load diff
566
public/dist/scripts/app-all.js
vendored
566
public/dist/scripts/app-all.js
vendored
File diff suppressed because one or more lines are too long
554
public/dist/scripts/app-dep.js
vendored
554
public/dist/scripts/app-dep.js
vendored
|
@ -1,195 +1,195 @@
|
|||
|
||||
var Appwrite=(function(exports,isomorphicFormData,crossFetch){'use strict';function __awaiter(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value);});}
|
||||
(function(exports,isomorphicFormData,crossFetch){'use strict';function __awaiter(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value);});}
|
||||
return new(P||(P=Promise))(function(resolve,reject){function fulfilled(value){try{step(generator.next(value));}catch(e){reject(e);}}
|
||||
function rejected(value){try{step(generator["throw"](value));}catch(e){reject(e);}}
|
||||
function step(result){result.done?resolve(result.value):adopt(result.value).then(fulfilled,rejected);}
|
||||
step((generator=generator.apply(thisArg,_arguments||[])).next());});}
|
||||
class AppwriteException extends Error{constructor(message,code=0,response=''){super(message);this.name='AppwriteException';this.message=message;this.code=code;this.response=response;}}
|
||||
class Appwrite{constructor(){this.config={endpoint:'https://appwrite.io/v1',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:2.0.0','X-Appwrite-Response-Format':'0.8.0',};this.account={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/account';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(email,password,name='')=>__awaiter(this,void 0,void 0,function*(){if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
class Appwrite{constructor(){this.config={endpoint:'https://appwrite.io/v1',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-version':'appwrite:web:2.0.0','X-Appwrite-Response-Format':'0.8.0',};this.account={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/account';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(email,password,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/account';let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),delete:()=>__awaiter(this,void 0,void 0,function*(){let path='/account';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateEmail:(email,password)=>__awaiter(this,void 0,void 0,function*(){if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),delete:()=>__awaiter(this,void 0,void 0,function*(){let path='/account';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateEmail:(email,password)=>__awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/account/email';let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),createJWT:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/jwt';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getLogs:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateName:(name)=>__awaiter(this,void 0,void 0,function*(){if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),createJWT:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/jwt';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getLogs:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateName:(name)=>__awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/account/name';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),updatePassword:(password,oldPassword='')=>__awaiter(this,void 0,void 0,function*(){if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),updatePassword:(password,oldPassword)=>__awaiter(this,void 0,void 0,function*(){if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/account/password';let payload={};if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof oldPassword!=='undefined'){payload['oldPassword']=oldPassword;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getPrefs:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/prefs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePrefs:(prefs)=>__awaiter(this,void 0,void 0,function*(){if(prefs===undefined){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getPrefs:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/prefs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePrefs:(prefs)=>__awaiter(this,void 0,void 0,function*(){if(typeof prefs==='undefined'){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
let path='/account/prefs';let payload={};if(typeof prefs!=='undefined'){payload['prefs']=prefs;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),createRecovery:(email,url)=>__awaiter(this,void 0,void 0,function*(){if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),createRecovery:(email,url)=>__awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/account/recovery';let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateRecovery:(userId,secret,password,passwordAgain)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(secret===undefined){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
if(passwordAgain===undefined){throw new AppwriteException('Missing required parameter: "passwordAgain"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateRecovery:(userId,secret,password,passwordAgain)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof secret==='undefined'){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
if(typeof passwordAgain==='undefined'){throw new AppwriteException('Missing required parameter: "passwordAgain"');}
|
||||
let path='/account/recovery';let payload={};if(typeof userId!=='undefined'){payload['userId']=userId;}
|
||||
if(typeof secret!=='undefined'){payload['secret']=secret;}
|
||||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof passwordAgain!=='undefined'){payload['passwordAgain']=passwordAgain;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),getSessions:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createSession:(email,password)=>__awaiter(this,void 0,void 0,function*(){if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),getSessions:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createSession:(email,password)=>__awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/account/sessions';let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),deleteSessions:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createAnonymousSession:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions/anonymous';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createOAuth2Session:(provider,success='https://appwrite.io/auth/oauth2/success',failure='https://appwrite.io/auth/oauth2/failure',scopes=[])=>{if(provider===undefined){throw new AppwriteException('Missing required parameter: "provider"');}
|
||||
let path='/account/sessions/oauth2/{provider}'.replace('{provider}',provider);let payload={};if(success){payload['success']=success;}
|
||||
if(failure){payload['failure']=failure;}
|
||||
if(scopes){payload['scopes']=scopes;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),deleteSessions:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createAnonymousSession:()=>__awaiter(this,void 0,void 0,function*(){let path='/account/sessions/anonymous';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createOAuth2Session:(provider,success,failure,scopes)=>{if(typeof provider==='undefined'){throw new AppwriteException('Missing required parameter: "provider"');}
|
||||
let path='/account/sessions/oauth2/{provider}'.replace('{provider}',provider);let payload={};if(typeof success!=='undefined'){payload['success']=success;}
|
||||
if(typeof failure!=='undefined'){payload['failure']=failure;}
|
||||
if(typeof scopes!=='undefined'){payload['scopes']=scopes;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
if(typeof window!=='undefined'&&(window===null||window===void 0?void 0:window.location)){window.location.href=uri.toString();}
|
||||
else{return uri;}},deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(sessionId===undefined){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createVerification:(url)=>__awaiter(this,void 0,void 0,function*(){if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
else{return uri;}},deleteSession:(sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/account/sessions/{sessionId}'.replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),createVerification:(url)=>__awaiter(this,void 0,void 0,function*(){if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/account/verification';let payload={};if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateVerification:(userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(secret===undefined){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateVerification:(userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof secret==='undefined'){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
let path='/account/verification';let payload={};if(typeof userId!=='undefined'){payload['userId']=userId;}
|
||||
if(typeof secret!=='undefined'){payload['secret']=secret;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);})};this.avatars={getBrowser:(code,width=100,height=100,quality=100)=>{if(code===undefined){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/browsers/{code}'.replace('{code}',code);let payload={};if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
if(quality){payload['quality']=quality;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);})};this.avatars={getBrowser:(code,width,height,quality)=>{if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/browsers/{code}'.replace('{code}',code);let payload={};if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof quality!=='undefined'){payload['quality']=quality;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getCreditCard:(code,width=100,height=100,quality=100)=>{if(code===undefined){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/credit-cards/{code}'.replace('{code}',code);let payload={};if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
if(quality){payload['quality']=quality;}
|
||||
return uri;},getCreditCard:(code,width,height,quality)=>{if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/credit-cards/{code}'.replace('{code}',code);let payload={};if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof quality!=='undefined'){payload['quality']=quality;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getFavicon:(url)=>{if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/avatars/favicon';let payload={};if(url){payload['url']=url;}
|
||||
return uri;},getFavicon:(url)=>{if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/avatars/favicon';let payload={};if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getFlag:(code,width=100,height=100,quality=100)=>{if(code===undefined){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/flags/{code}'.replace('{code}',code);let payload={};if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
if(quality){payload['quality']=quality;}
|
||||
return uri;},getFlag:(code,width,height,quality)=>{if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/avatars/flags/{code}'.replace('{code}',code);let payload={};if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof quality!=='undefined'){payload['quality']=quality;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getImage:(url,width=400,height=400)=>{if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/avatars/image';let payload={};if(url){payload['url']=url;}
|
||||
if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
return uri;},getImage:(url,width,height)=>{if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/avatars/image';let payload={};if(typeof url!=='undefined'){payload['url']=url;}
|
||||
if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getInitials:(name='',width=500,height=500,color='',background='')=>{let path='/avatars/initials';let payload={};if(name){payload['name']=name;}
|
||||
if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
if(color){payload['color']=color;}
|
||||
if(background){payload['background']=background;}
|
||||
return uri;},getInitials:(name,width,height,color,background)=>{let path='/avatars/initials';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof color!=='undefined'){payload['color']=color;}
|
||||
if(typeof background!=='undefined'){payload['background']=background;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getQR:(text,size=400,margin=1,download=false)=>{if(text===undefined){throw new AppwriteException('Missing required parameter: "text"');}
|
||||
let path='/avatars/qr';let payload={};if(text){payload['text']=text;}
|
||||
if(size){payload['size']=size;}
|
||||
if(margin){payload['margin']=margin;}
|
||||
if(download){payload['download']=download;}
|
||||
return uri;},getQR:(text,size,margin,download)=>{if(typeof text==='undefined'){throw new AppwriteException('Missing required parameter: "text"');}
|
||||
let path='/avatars/qr';let payload={};if(typeof text!=='undefined'){payload['text']=text;}
|
||||
if(typeof size!=='undefined'){payload['size']=size;}
|
||||
if(typeof margin!=='undefined'){payload['margin']=margin;}
|
||||
if(typeof download!=='undefined'){payload['download']=download;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}};this.database={listCollections:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createCollection:(name,read,write,rules)=>__awaiter(this,void 0,void 0,function*(){if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(read===undefined){throw new AppwriteException('Missing required parameter: "read"');}
|
||||
if(write===undefined){throw new AppwriteException('Missing required parameter: "write"');}
|
||||
if(rules===undefined){throw new AppwriteException('Missing required parameter: "rules"');}
|
||||
return uri;}};this.database={listCollections:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createCollection:(name,read,write,rules)=>__awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof read==='undefined'){throw new AppwriteException('Missing required parameter: "read"');}
|
||||
if(typeof write==='undefined'){throw new AppwriteException('Missing required parameter: "write"');}
|
||||
if(typeof rules==='undefined'){throw new AppwriteException('Missing required parameter: "rules"');}
|
||||
let path='/database/collections';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
if(typeof rules!=='undefined'){payload['rules']=rules;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateCollection:(collectionId,name,read=[],write=[],rules=[])=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateCollection:(collectionId,name,read,write,rules)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
if(typeof rules!=='undefined'){payload['rules']=rules;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,filters=[],limit=25,offset=0,orderField='',orderType='ASC',orderCast='string',search='')=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}/documents'.replace('{collectionId}',collectionId);let payload={};if(filters){payload['filters']=filters;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderField){payload['orderField']=orderField;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
if(orderCast){payload['orderCast']=orderCast;}
|
||||
if(search){payload['search']=search;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDocument:(collectionId,data,read=[],write=[],parentDocument='',parentProperty='',parentPropertyType='assign')=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(data===undefined){throw new AppwriteException('Missing required parameter: "data"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,filters,limit,offset,orderField,orderType,orderCast,search)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/database/collections/{collectionId}/documents'.replace('{collectionId}',collectionId);let payload={};if(typeof filters!=='undefined'){payload['filters']=filters;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderField!=='undefined'){payload['orderField']=orderField;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
if(typeof orderCast!=='undefined'){payload['orderCast']=orderCast;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDocument:(collectionId,data,read,write,parentDocument,parentProperty,parentPropertyType)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof data==='undefined'){throw new AppwriteException('Missing required parameter: "data"');}
|
||||
let path='/database/collections/{collectionId}/documents'.replace('{collectionId}',collectionId);let payload={};if(typeof data!=='undefined'){payload['data']=data;}
|
||||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
if(typeof parentDocument!=='undefined'){payload['parentDocument']=parentDocument;}
|
||||
if(typeof parentProperty!=='undefined'){payload['parentProperty']=parentProperty;}
|
||||
if(typeof parentPropertyType!=='undefined'){payload['parentPropertyType']=parentPropertyType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(documentId===undefined){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateDocument:(collectionId,documentId,data,read=[],write=[])=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(documentId===undefined){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
if(data===undefined){throw new AppwriteException('Missing required parameter: "data"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateDocument:(collectionId,documentId,data,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
if(typeof data==='undefined'){throw new AppwriteException('Missing required parameter: "data"');}
|
||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};if(typeof data!=='undefined'){payload['data']=data;}
|
||||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(collectionId===undefined){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(documentId===undefined){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);})};this.functions={list:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,execute,env,vars={},events=[],schedule='',timeout=15)=>__awaiter(this,void 0,void 0,function*(){if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(execute===undefined){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
if(env===undefined){throw new AppwriteException('Missing required parameter: "env"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteDocument:(collectionId,documentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof documentId==='undefined'){throw new AppwriteException('Missing required parameter: "documentId"');}
|
||||
let path='/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}',collectionId).replace('{documentId}',documentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);})};this.functions={list:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,execute,runtime,vars,events,schedule,timeout)=>__awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
if(typeof runtime==='undefined'){throw new AppwriteException('Missing required parameter: "runtime"');}
|
||||
let path='/functions';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof execute!=='undefined'){payload['execute']=execute;}
|
||||
if(typeof env!=='undefined'){payload['env']=env;}
|
||||
if(typeof runtime!=='undefined'){payload['runtime']=runtime;}
|
||||
if(typeof vars!=='undefined'){payload['vars']=vars;}
|
||||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(functionId,name,execute,vars={},events=[],schedule='',timeout=15)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(execute===undefined){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(functionId,name,execute,vars,events,schedule,timeout)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof execute!=='undefined'){payload['execute']=execute;}
|
||||
if(typeof vars!=='undefined'){payload['vars']=vars;}
|
||||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/executions'.replace('{functionId}',functionId);let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createExecution:(functionId,data='')=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/executions'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createExecution:(functionId,data)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/executions'.replace('{functionId}',functionId);let payload={};if(typeof data!=='undefined'){payload['data']=data;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getExecution:(functionId,executionId)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(executionId===undefined){throw new AppwriteException('Missing required parameter: "executionId"');}
|
||||
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTag:(functionId,tag)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(tag===undefined){throw new AppwriteException('Missing required parameter: "tag"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getExecution:(functionId,executionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof executionId==='undefined'){throw new AppwriteException('Missing required parameter: "executionId"');}
|
||||
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTag:(functionId,tag)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tag==='undefined'){throw new AppwriteException('Missing required parameter: "tag"');}
|
||||
let path='/functions/{functionId}/tag'.replace('{functionId}',functionId);let payload={};if(typeof tag!=='undefined'){payload['tag']=tag;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTag:(functionId,command,code)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(command===undefined){throw new AppwriteException('Missing required parameter: "command"');}
|
||||
if(code===undefined){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTag:(functionId,command,code)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof command==='undefined'){throw new AppwriteException('Missing required parameter: "command"');}
|
||||
if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
|
||||
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof command!=='undefined'){payload['command']=command;}
|
||||
if(typeof code!=='undefined'){payload['code']=code;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(tagId===undefined){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(tagId===undefined){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range='30d')=>__awaiter(this,void 0,void 0,function*(){if(functionId===undefined){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/usage'.replace('{functionId}',functionId);let payload={};if(range){payload['range']=range;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.health={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/health';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getAntiVirus:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/anti-virus';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCache:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/cache';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getDB:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/db';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueCertificates:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/certificates';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueFunctions:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/functions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueLogs:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/logs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueTasks:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/tasks';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueUsage:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/usage';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueWebhooks:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/webhooks';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getStorageLocal:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/storage/local';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getTime:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/time';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.locale={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getContinents:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountries:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountriesEU:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountriesPhones:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCurrencies:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getLanguages:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.projects={list:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,teamId,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId='')=>__awaiter(this,void 0,void 0,function*(){if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
|
||||
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/usage'.replace('{functionId}',functionId);let payload={};if(typeof range!=='undefined'){payload['range']=range;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.health={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/health';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getAntiVirus:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/anti-virus';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCache:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/cache';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getDB:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/db';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueCertificates:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/certificates';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueFunctions:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/functions';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueLogs:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/logs';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueTasks:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/tasks';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueUsage:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/usage';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getQueueWebhooks:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/queue/webhooks';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getStorageLocal:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/storage/local';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getTime:()=>__awaiter(this,void 0,void 0,function*(){let path='/health/time';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.locale={get:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getContinents:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountries:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountriesEU:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCountriesPhones:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getCurrencies:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getLanguages:()=>__awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.projects={list:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,teamId,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId)=>__awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/projects';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof teamId!=='undefined'){payload['teamId']=teamId;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
|
@ -201,9 +201,9 @@ if(typeof legalState!=='undefined'){payload['legalState']=legalState;}
|
|||
if(typeof legalCity!=='undefined'){payload['legalCity']=legalCity;}
|
||||
if(typeof legalAddress!=='undefined'){payload['legalAddress']=legalAddress;}
|
||||
if(typeof legalTaxId!=='undefined'){payload['legalTaxId']=legalTaxId;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(projectId,name,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(projectId,name,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
if(typeof logo!=='undefined'){payload['logo']=logo;}
|
||||
|
@ -214,75 +214,75 @@ if(typeof legalState!=='undefined'){payload['legalState']=legalState;}
|
|||
if(typeof legalCity!=='undefined'){payload['legalCity']=legalCity;}
|
||||
if(typeof legalAddress!=='undefined'){payload['legalAddress']=legalAddress;}
|
||||
if(typeof legalTaxId!=='undefined'){payload['legalTaxId']=legalTaxId;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),delete:(projectId,password)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),delete:(projectId,password)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};if(typeof password!=='undefined'){payload['password']=password;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateAuthLimit:(projectId,limit)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(limit===undefined){throw new AppwriteException('Missing required parameter: "limit"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateAuthLimit:(projectId,limit)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof limit==='undefined'){throw new AppwriteException('Missing required parameter: "limit"');}
|
||||
let path='/projects/{projectId}/auth/limit'.replace('{projectId}',projectId);let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),updateAuthStatus:(projectId,method,status)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(method===undefined){throw new AppwriteException('Missing required parameter: "method"');}
|
||||
if(status===undefined){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),updateAuthStatus:(projectId,method,status)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof method==='undefined'){throw new AppwriteException('Missing required parameter: "method"');}
|
||||
if(typeof status==='undefined'){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
let path='/projects/{projectId}/auth/{method}'.replace('{projectId}',projectId).replace('{method}',method);let payload={};if(typeof status!=='undefined'){payload['status']=status;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listDomains:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/domains'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDomain:(projectId,domain)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(domain===undefined){throw new AppwriteException('Missing required parameter: "domain"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listDomains:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/domains'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDomain:(projectId,domain)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof domain==='undefined'){throw new AppwriteException('Missing required parameter: "domain"');}
|
||||
let path='/projects/{projectId}/domains'.replace('{projectId}',projectId);let payload={};if(typeof domain!=='undefined'){payload['domain']=domain;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getDomain:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(domainId===undefined){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteDomain:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(domainId===undefined){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateDomainVerification:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(domainId===undefined){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}/verification'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listKeys:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/keys'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createKey:(projectId,name,scopes)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(scopes===undefined){throw new AppwriteException('Missing required parameter: "scopes"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getDomain:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof domainId==='undefined'){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteDomain:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof domainId==='undefined'){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateDomainVerification:(projectId,domainId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof domainId==='undefined'){throw new AppwriteException('Missing required parameter: "domainId"');}
|
||||
let path='/projects/{projectId}/domains/{domainId}/verification'.replace('{projectId}',projectId).replace('{domainId}',domainId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listKeys:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/keys'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createKey:(projectId,name,scopes)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof scopes==='undefined'){throw new AppwriteException('Missing required parameter: "scopes"');}
|
||||
let path='/projects/{projectId}/keys'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof scopes!=='undefined'){payload['scopes']=scopes;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getKey:(projectId,keyId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(keyId===undefined){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
let path='/projects/{projectId}/keys/{keyId}'.replace('{projectId}',projectId).replace('{keyId}',keyId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateKey:(projectId,keyId,name,scopes)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(keyId===undefined){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(scopes===undefined){throw new AppwriteException('Missing required parameter: "scopes"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getKey:(projectId,keyId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof keyId==='undefined'){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
let path='/projects/{projectId}/keys/{keyId}'.replace('{projectId}',projectId).replace('{keyId}',keyId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateKey:(projectId,keyId,name,scopes)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof keyId==='undefined'){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof scopes==='undefined'){throw new AppwriteException('Missing required parameter: "scopes"');}
|
||||
let path='/projects/{projectId}/keys/{keyId}'.replace('{projectId}',projectId).replace('{keyId}',keyId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof scopes!=='undefined'){payload['scopes']=scopes;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteKey:(projectId,keyId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(keyId===undefined){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
let path='/projects/{projectId}/keys/{keyId}'.replace('{projectId}',projectId).replace('{keyId}',keyId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateOAuth2:(projectId,provider,appId='',secret='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(provider===undefined){throw new AppwriteException('Missing required parameter: "provider"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteKey:(projectId,keyId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof keyId==='undefined'){throw new AppwriteException('Missing required parameter: "keyId"');}
|
||||
let path='/projects/{projectId}/keys/{keyId}'.replace('{projectId}',projectId).replace('{keyId}',keyId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateOAuth2:(projectId,provider,appId,secret)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof provider==='undefined'){throw new AppwriteException('Missing required parameter: "provider"');}
|
||||
let path='/projects/{projectId}/oauth2'.replace('{projectId}',projectId);let payload={};if(typeof provider!=='undefined'){payload['provider']=provider;}
|
||||
if(typeof appId!=='undefined'){payload['appId']=appId;}
|
||||
if(typeof secret!=='undefined'){payload['secret']=secret;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listPlatforms:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/platforms'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createPlatform:(projectId,type,name,key='',store='',hostname='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(type===undefined){throw new AppwriteException('Missing required parameter: "type"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listPlatforms:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/platforms'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createPlatform:(projectId,type,name,key,store,hostname)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof type==='undefined'){throw new AppwriteException('Missing required parameter: "type"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/projects/{projectId}/platforms'.replace('{projectId}',projectId);let payload={};if(typeof type!=='undefined'){payload['type']=type;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof key!=='undefined'){payload['key']=key;}
|
||||
if(typeof store!=='undefined'){payload['store']=store;}
|
||||
if(typeof hostname!=='undefined'){payload['hostname']=hostname;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getPlatform:(projectId,platformId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(platformId===undefined){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
let path='/projects/{projectId}/platforms/{platformId}'.replace('{projectId}',projectId).replace('{platformId}',platformId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePlatform:(projectId,platformId,name,key='',store='',hostname='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(platformId===undefined){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getPlatform:(projectId,platformId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof platformId==='undefined'){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
let path='/projects/{projectId}/platforms/{platformId}'.replace('{projectId}',projectId).replace('{platformId}',platformId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePlatform:(projectId,platformId,name,key,store,hostname)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof platformId==='undefined'){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/projects/{projectId}/platforms/{platformId}'.replace('{projectId}',projectId).replace('{platformId}',platformId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof key!=='undefined'){payload['key']=key;}
|
||||
if(typeof store!=='undefined'){payload['store']=store;}
|
||||
if(typeof hostname!=='undefined'){payload['hostname']=hostname;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deletePlatform:(projectId,platformId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(platformId===undefined){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
let path='/projects/{projectId}/platforms/{platformId}'.replace('{projectId}',projectId).replace('{platformId}',platformId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listTasks:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/tasks'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTask:(projectId,name,status,schedule,security,httpMethod,httpUrl,httpHeaders=[],httpUser='',httpPass='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(status===undefined){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
if(schedule===undefined){throw new AppwriteException('Missing required parameter: "schedule"');}
|
||||
if(security===undefined){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
if(httpMethod===undefined){throw new AppwriteException('Missing required parameter: "httpMethod"');}
|
||||
if(httpUrl===undefined){throw new AppwriteException('Missing required parameter: "httpUrl"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deletePlatform:(projectId,platformId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof platformId==='undefined'){throw new AppwriteException('Missing required parameter: "platformId"');}
|
||||
let path='/projects/{projectId}/platforms/{platformId}'.replace('{projectId}',projectId).replace('{platformId}',platformId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listTasks:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/tasks'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTask:(projectId,name,status,schedule,security,httpMethod,httpUrl,httpHeaders,httpUser,httpPass)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof status==='undefined'){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
if(typeof schedule==='undefined'){throw new AppwriteException('Missing required parameter: "schedule"');}
|
||||
if(typeof security==='undefined'){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
if(typeof httpMethod==='undefined'){throw new AppwriteException('Missing required parameter: "httpMethod"');}
|
||||
if(typeof httpUrl==='undefined'){throw new AppwriteException('Missing required parameter: "httpUrl"');}
|
||||
let path='/projects/{projectId}/tasks'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof status!=='undefined'){payload['status']=status;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
|
@ -292,16 +292,16 @@ if(typeof httpUrl!=='undefined'){payload['httpUrl']=httpUrl;}
|
|||
if(typeof httpHeaders!=='undefined'){payload['httpHeaders']=httpHeaders;}
|
||||
if(typeof httpUser!=='undefined'){payload['httpUser']=httpUser;}
|
||||
if(typeof httpPass!=='undefined'){payload['httpPass']=httpPass;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getTask:(projectId,taskId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(taskId===undefined){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
let path='/projects/{projectId}/tasks/{taskId}'.replace('{projectId}',projectId).replace('{taskId}',taskId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTask:(projectId,taskId,name,status,schedule,security,httpMethod,httpUrl,httpHeaders=[],httpUser='',httpPass='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(taskId===undefined){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(status===undefined){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
if(schedule===undefined){throw new AppwriteException('Missing required parameter: "schedule"');}
|
||||
if(security===undefined){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
if(httpMethod===undefined){throw new AppwriteException('Missing required parameter: "httpMethod"');}
|
||||
if(httpUrl===undefined){throw new AppwriteException('Missing required parameter: "httpUrl"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getTask:(projectId,taskId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof taskId==='undefined'){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
let path='/projects/{projectId}/tasks/{taskId}'.replace('{projectId}',projectId).replace('{taskId}',taskId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTask:(projectId,taskId,name,status,schedule,security,httpMethod,httpUrl,httpHeaders,httpUser,httpPass)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof taskId==='undefined'){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof status==='undefined'){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
if(typeof schedule==='undefined'){throw new AppwriteException('Missing required parameter: "schedule"');}
|
||||
if(typeof security==='undefined'){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
if(typeof httpMethod==='undefined'){throw new AppwriteException('Missing required parameter: "httpMethod"');}
|
||||
if(typeof httpUrl==='undefined'){throw new AppwriteException('Missing required parameter: "httpUrl"');}
|
||||
let path='/projects/{projectId}/tasks/{taskId}'.replace('{projectId}',projectId).replace('{taskId}',taskId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof status!=='undefined'){payload['status']=status;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
|
@ -311,129 +311,133 @@ if(typeof httpUrl!=='undefined'){payload['httpUrl']=httpUrl;}
|
|||
if(typeof httpHeaders!=='undefined'){payload['httpHeaders']=httpHeaders;}
|
||||
if(typeof httpUser!=='undefined'){payload['httpUser']=httpUser;}
|
||||
if(typeof httpPass!=='undefined'){payload['httpPass']=httpPass;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteTask:(projectId,taskId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(taskId===undefined){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
let path='/projects/{projectId}/tasks/{taskId}'.replace('{projectId}',projectId).replace('{taskId}',taskId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(projectId,range='30d')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/usage'.replace('{projectId}',projectId);let payload={};if(range){payload['range']=range;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),listWebhooks:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/webhooks'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createWebhook:(projectId,name,events,url,security,httpUser='',httpPass='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(events===undefined){throw new AppwriteException('Missing required parameter: "events"');}
|
||||
if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
if(security===undefined){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteTask:(projectId,taskId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof taskId==='undefined'){throw new AppwriteException('Missing required parameter: "taskId"');}
|
||||
let path='/projects/{projectId}/tasks/{taskId}'.replace('{projectId}',projectId).replace('{taskId}',taskId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(projectId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/usage'.replace('{projectId}',projectId);let payload={};if(typeof range!=='undefined'){payload['range']=range;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),listWebhooks:(projectId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
let path='/projects/{projectId}/webhooks'.replace('{projectId}',projectId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createWebhook:(projectId,name,events,url,security,httpUser,httpPass)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof events==='undefined'){throw new AppwriteException('Missing required parameter: "events"');}
|
||||
if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
if(typeof security==='undefined'){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
let path='/projects/{projectId}/webhooks'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
if(typeof security!=='undefined'){payload['security']=security;}
|
||||
if(typeof httpUser!=='undefined'){payload['httpUser']=httpUser;}
|
||||
if(typeof httpPass!=='undefined'){payload['httpPass']=httpPass;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getWebhook:(projectId,webhookId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(webhookId===undefined){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
let path='/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}',projectId).replace('{webhookId}',webhookId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateWebhook:(projectId,webhookId,name,events,url,security,httpUser='',httpPass='')=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(webhookId===undefined){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(events===undefined){throw new AppwriteException('Missing required parameter: "events"');}
|
||||
if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
if(security===undefined){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getWebhook:(projectId,webhookId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof webhookId==='undefined'){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
let path='/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}',projectId).replace('{webhookId}',webhookId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateWebhook:(projectId,webhookId,name,events,url,security,httpUser,httpPass)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof webhookId==='undefined'){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof events==='undefined'){throw new AppwriteException('Missing required parameter: "events"');}
|
||||
if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
if(typeof security==='undefined'){throw new AppwriteException('Missing required parameter: "security"');}
|
||||
let path='/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}',projectId).replace('{webhookId}',webhookId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
if(typeof security!=='undefined'){payload['security']=security;}
|
||||
if(typeof httpUser!=='undefined'){payload['httpUser']=httpUser;}
|
||||
if(typeof httpPass!=='undefined'){payload['httpPass']=httpPass;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteWebhook:(projectId,webhookId)=>__awaiter(this,void 0,void 0,function*(){if(projectId===undefined){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(webhookId===undefined){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
let path='/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}',projectId).replace('{webhookId}',webhookId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);})};this.storage={listFiles:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/storage/files';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createFile:(file,read=[],write=[])=>__awaiter(this,void 0,void 0,function*(){if(file===undefined){throw new AppwriteException('Missing required parameter: "file"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteWebhook:(projectId,webhookId)=>__awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
if(typeof webhookId==='undefined'){throw new AppwriteException('Missing required parameter: "webhookId"');}
|
||||
let path='/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}',projectId).replace('{webhookId}',webhookId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);})};this.storage={listFiles:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/storage/files';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createFile:(file,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof file==='undefined'){throw new AppwriteException('Missing required parameter: "file"');}
|
||||
let path='/storage/files';let payload={};if(typeof file!=='undefined'){payload['file']=file;}
|
||||
if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getFile:(fileId)=>__awaiter(this,void 0,void 0,function*(){if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
if(read===undefined){throw new AppwriteException('Missing required parameter: "read"');}
|
||||
if(write===undefined){throw new AppwriteException('Missing required parameter: "write"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getFile:(fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateFile:(fileId,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
if(typeof read==='undefined'){throw new AppwriteException('Missing required parameter: "read"');}
|
||||
if(typeof write==='undefined'){throw new AppwriteException('Missing required parameter: "write"');}
|
||||
let path='/storage/files/{fileId}'.replace('{fileId}',fileId);let payload={};if(typeof read!=='undefined'){payload['read']=read;}
|
||||
if(typeof write!=='undefined'){payload['write']=write;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteFile:(fileId)=>__awaiter(this,void 0,void 0,function*(){if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getFileDownload:(fileId)=>{if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),deleteFile:(fileId)=>__awaiter(this,void 0,void 0,function*(){if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getFileDownload:(fileId)=>{if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}/download'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getFilePreview:(fileId,width=0,height=0,quality=100,borderWidth=0,borderColor='',borderRadius=0,opacity=1,rotation=0,background='',output='')=>{if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}/preview'.replace('{fileId}',fileId);let payload={};if(width){payload['width']=width;}
|
||||
if(height){payload['height']=height;}
|
||||
if(quality){payload['quality']=quality;}
|
||||
if(borderWidth){payload['borderWidth']=borderWidth;}
|
||||
if(borderColor){payload['borderColor']=borderColor;}
|
||||
if(borderRadius){payload['borderRadius']=borderRadius;}
|
||||
if(opacity){payload['opacity']=opacity;}
|
||||
if(rotation){payload['rotation']=rotation;}
|
||||
if(background){payload['background']=background;}
|
||||
if(output){payload['output']=output;}
|
||||
return uri;},getFilePreview:(fileId,width,height,gravity,quality,borderWidth,borderColor,borderRadius,opacity,rotation,background,output)=>{if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}/preview'.replace('{fileId}',fileId);let payload={};if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof gravity!=='undefined'){payload['gravity']=gravity;}
|
||||
if(typeof quality!=='undefined'){payload['quality']=quality;}
|
||||
if(typeof borderWidth!=='undefined'){payload['borderWidth']=borderWidth;}
|
||||
if(typeof borderColor!=='undefined'){payload['borderColor']=borderColor;}
|
||||
if(typeof borderRadius!=='undefined'){payload['borderRadius']=borderRadius;}
|
||||
if(typeof opacity!=='undefined'){payload['opacity']=opacity;}
|
||||
if(typeof rotation!=='undefined'){payload['rotation']=rotation;}
|
||||
if(typeof background!=='undefined'){payload['background']=background;}
|
||||
if(typeof output!=='undefined'){payload['output']=output;}
|
||||
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;},getFileView:(fileId)=>{if(fileId===undefined){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
return uri;},getFileView:(fileId)=>{if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
|
||||
let path='/storage/files/{fileId}/view'.replace('{fileId}',fileId);let payload={};const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}};this.teams={list:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/teams';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,roles=["owner"])=>__awaiter(this,void 0,void 0,function*(){if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
return uri;}};this.teams={list:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/teams';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(name,roles)=>__awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/teams';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof roles!=='undefined'){payload['roles']=roles;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(teamId,name)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(name===undefined){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),update:(teamId,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}/memberships'.replace('{teamId}',teamId);let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createMembership:(teamId,email,roles,url,name='')=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(roles===undefined){throw new AppwriteException('Missing required parameter: "roles"');}
|
||||
if(url===undefined){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(teamId)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getMemberships:(teamId,search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}/memberships'.replace('{teamId}',teamId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createMembership:(teamId,email,roles,url,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof roles==='undefined'){throw new AppwriteException('Missing required parameter: "roles"');}
|
||||
if(typeof url==='undefined'){throw new AppwriteException('Missing required parameter: "url"');}
|
||||
let path='/teams/{teamId}/memberships'.replace('{teamId}',teamId);let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof roles!=='undefined'){payload['roles']=roles;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateMembershipRoles:(teamId,membershipId,roles)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(membershipId===undefined){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
if(roles===undefined){throw new AppwriteException('Missing required parameter: "roles"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),updateMembershipRoles:(teamId,membershipId,roles)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof membershipId==='undefined'){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
if(typeof roles==='undefined'){throw new AppwriteException('Missing required parameter: "roles"');}
|
||||
let path='/teams/{teamId}/memberships/{membershipId}'.replace('{teamId}',teamId).replace('{membershipId}',membershipId);let payload={};if(typeof roles!=='undefined'){payload['roles']=roles;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteMembership:(teamId,membershipId)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(membershipId===undefined){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
let path='/teams/{teamId}/memberships/{membershipId}'.replace('{teamId}',teamId).replace('{membershipId}',membershipId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateMembershipStatus:(teamId,membershipId,userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(teamId===undefined){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(membershipId===undefined){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(secret===undefined){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),deleteMembership:(teamId,membershipId)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof membershipId==='undefined'){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
let path='/teams/{teamId}/memberships/{membershipId}'.replace('{teamId}',teamId).replace('{membershipId}',membershipId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateMembershipStatus:(teamId,membershipId,userId,secret)=>__awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof membershipId==='undefined'){throw new AppwriteException('Missing required parameter: "membershipId"');}
|
||||
if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof secret==='undefined'){throw new AppwriteException('Missing required parameter: "secret"');}
|
||||
let path='/teams/{teamId}/memberships/{membershipId}/status'.replace('{teamId}',teamId).replace('{membershipId}',membershipId);let payload={};if(typeof userId!=='undefined'){payload['userId']=userId;}
|
||||
if(typeof secret!=='undefined'){payload['secret']=secret;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);})};this.users={list:(search='',limit=25,offset=0,orderType='ASC')=>__awaiter(this,void 0,void 0,function*(){let path='/users';let payload={};if(search){payload['search']=search;}
|
||||
if(limit){payload['limit']=limit;}
|
||||
if(offset){payload['offset']=offset;}
|
||||
if(orderType){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(email,password,name='')=>__awaiter(this,void 0,void 0,function*(){if(email===undefined){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(password===undefined){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);})};this.users={list:(search,limit,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/users';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
|
||||
if(typeof limit!=='undefined'){payload['limit']=limit;}
|
||||
if(typeof offset!=='undefined'){payload['offset']=offset;}
|
||||
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),create:(email,password,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
if(typeof password==='undefined'){throw new AppwriteException('Missing required parameter: "password"');}
|
||||
let path='/users';let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),delete:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getLogs:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/logs'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getPrefs:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/prefs'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePrefs:(userId,prefs)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(prefs===undefined){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),get:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),delete:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getLogs:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/logs'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getPrefs:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/prefs'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updatePrefs:(userId,prefs)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof prefs==='undefined'){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
let path='/users/{userId}/prefs'.replace('{userId}',userId);let payload={};if(typeof prefs!=='undefined'){payload['prefs']=prefs;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getSessions:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteSessions:(userId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),deleteSession:(userId,sessionId)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(sessionId===undefined){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/users/{userId}/sessions/{sessionId}'.replace('{userId}',userId).replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateStatus:(userId,status)=>__awaiter(this,void 0,void 0,function*(){if(userId===undefined){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(status===undefined){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getSessions:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteSessions:(userId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),deleteSession:(userId,sessionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof sessionId==='undefined'){throw new AppwriteException('Missing required parameter: "sessionId"');}
|
||||
let path='/users/{userId}/sessions/{sessionId}'.replace('{userId}',userId).replace('{sessionId}',sessionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),updateStatus:(userId,status)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof status==='undefined'){throw new AppwriteException('Missing required parameter: "status"');}
|
||||
let path='/users/{userId}/status'.replace('{userId}',userId);let payload={};if(typeof status!=='undefined'){payload['status']=status;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),updateVerification:(userId,emailVerification)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof emailVerification==='undefined'){throw new AppwriteException('Missing required parameter: "emailVerification"');}
|
||||
let path='/users/{userId}/verification'.replace('{userId}',userId);let payload={};if(typeof emailVerification!=='undefined'){payload['emailVerification']=emailVerification;}
|
||||
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);})};}
|
||||
setEndpoint(endpoint){this.config.endpoint=endpoint;return this;}
|
||||
setProject(value){this.headers['X-Appwrite-Project']=value;this.config.project=value;return this;}
|
||||
|
@ -455,7 +459,7 @@ catch(e){throw new AppwriteException(e.message);}});}
|
|||
flatten(data,prefix=''){let output={};for(const key in data){let value=data[key];let finalKey=prefix?`${prefix}[${key}]`:key;if(Array.isArray(value)){output=Object.assign(output,this.flatten(value,finalKey));}
|
||||
else{output[finalKey]=value;}}
|
||||
return output;}}
|
||||
exports.Appwrite=Appwrite;return exports;}({},null,window));(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(function(){try{return require('moment');}catch(e){}}()):typeof define==='function'&&define.amd?define(['require'],function(require){return factory(function(){try{return require('moment');}catch(e){}}());}):(global=global||self,global.Chart=factory(global.moment));}(this,(function(moment){'use strict';moment=moment&&moment.hasOwnProperty('default')?moment['default']:moment;function createCommonjsModule(fn,module){return module={exports:{}},fn(module,module.exports),module.exports;}
|
||||
exports.Appwrite=Appwrite;Object.defineProperty(exports,'__esModule',{value:true});}(this.window=this.window||{},null,window));(function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory(function(){try{return require('moment');}catch(e){}}()):typeof define==='function'&&define.amd?define(['require'],function(require){return factory(function(){try{return require('moment');}catch(e){}}());}):(global=global||self,global.Chart=factory(global.moment));}(this,(function(moment){'use strict';moment=moment&&moment.hasOwnProperty('default')?moment['default']:moment;function createCommonjsModule(fn,module){return module={exports:{}},fn(module,module.exports),module.exports;}
|
||||
function getCjsExportFromNamespace(n){return n&&n['default']||n;}
|
||||
var colorName={"aliceblue":[240,248,255],"antiquewhite":[250,235,215],"aqua":[0,255,255],"aquamarine":[127,255,212],"azure":[240,255,255],"beige":[245,245,220],"bisque":[255,228,196],"black":[0,0,0],"blanchedalmond":[255,235,205],"blue":[0,0,255],"blueviolet":[138,43,226],"brown":[165,42,42],"burlywood":[222,184,135],"cadetblue":[95,158,160],"chartreuse":[127,255,0],"chocolate":[210,105,30],"coral":[255,127,80],"cornflowerblue":[100,149,237],"cornsilk":[255,248,220],"crimson":[220,20,60],"cyan":[0,255,255],"darkblue":[0,0,139],"darkcyan":[0,139,139],"darkgoldenrod":[184,134,11],"darkgray":[169,169,169],"darkgreen":[0,100,0],"darkgrey":[169,169,169],"darkkhaki":[189,183,107],"darkmagenta":[139,0,139],"darkolivegreen":[85,107,47],"darkorange":[255,140,0],"darkorchid":[153,50,204],"darkred":[139,0,0],"darksalmon":[233,150,122],"darkseagreen":[143,188,143],"darkslateblue":[72,61,139],"darkslategray":[47,79,79],"darkslategrey":[47,79,79],"darkturquoise":[0,206,209],"darkviolet":[148,0,211],"deeppink":[255,20,147],"deepskyblue":[0,191,255],"dimgray":[105,105,105],"dimgrey":[105,105,105],"dodgerblue":[30,144,255],"firebrick":[178,34,34],"floralwhite":[255,250,240],"forestgreen":[34,139,34],"fuchsia":[255,0,255],"gainsboro":[220,220,220],"ghostwhite":[248,248,255],"gold":[255,215,0],"goldenrod":[218,165,32],"gray":[128,128,128],"green":[0,128,0],"greenyellow":[173,255,47],"grey":[128,128,128],"honeydew":[240,255,240],"hotpink":[255,105,180],"indianred":[205,92,92],"indigo":[75,0,130],"ivory":[255,255,240],"khaki":[240,230,140],"lavender":[230,230,250],"lavenderblush":[255,240,245],"lawngreen":[124,252,0],"lemonchiffon":[255,250,205],"lightblue":[173,216,230],"lightcoral":[240,128,128],"lightcyan":[224,255,255],"lightgoldenrodyellow":[250,250,210],"lightgray":[211,211,211],"lightgreen":[144,238,144],"lightgrey":[211,211,211],"lightpink":[255,182,193],"lightsalmon":[255,160,122],"lightseagreen":[32,178,170],"lightskyblue":[135,206,250],"lightslategray":[119,136,153],"lightslategrey":[119,136,153],"lightsteelblue":[176,196,222],"lightyellow":[255,255,224],"lime":[0,255,0],"limegreen":[50,205,50],"linen":[250,240,230],"magenta":[255,0,255],"maroon":[128,0,0],"mediumaquamarine":[102,205,170],"mediumblue":[0,0,205],"mediumorchid":[186,85,211],"mediumpurple":[147,112,219],"mediumseagreen":[60,179,113],"mediumslateblue":[123,104,238],"mediumspringgreen":[0,250,154],"mediumturquoise":[72,209,204],"mediumvioletred":[199,21,133],"midnightblue":[25,25,112],"mintcream":[245,255,250],"mistyrose":[255,228,225],"moccasin":[255,228,181],"navajowhite":[255,222,173],"navy":[0,0,128],"oldlace":[253,245,230],"olive":[128,128,0],"olivedrab":[107,142,35],"orange":[255,165,0],"orangered":[255,69,0],"orchid":[218,112,214],"palegoldenrod":[238,232,170],"palegreen":[152,251,152],"paleturquoise":[175,238,238],"palevioletred":[219,112,147],"papayawhip":[255,239,213],"peachpuff":[255,218,185],"peru":[205,133,63],"pink":[255,192,203],"plum":[221,160,221],"powderblue":[176,224,230],"purple":[128,0,128],"rebeccapurple":[102,51,153],"red":[255,0,0],"rosybrown":[188,143,143],"royalblue":[65,105,225],"saddlebrown":[139,69,19],"salmon":[250,128,114],"sandybrown":[244,164,96],"seagreen":[46,139,87],"seashell":[255,245,238],"sienna":[160,82,45],"silver":[192,192,192],"skyblue":[135,206,235],"slateblue":[106,90,205],"slategray":[112,128,144],"slategrey":[112,128,144],"snow":[255,250,250],"springgreen":[0,255,127],"steelblue":[70,130,180],"tan":[210,180,140],"teal":[0,128,128],"thistle":[216,191,216],"tomato":[255,99,71],"turquoise":[64,224,208],"violet":[238,130,238],"wheat":[245,222,179],"white":[255,255,255],"whitesmoke":[245,245,245],"yellow":[255,255,0],"yellowgreen":[154,205,50]};var conversions=createCommonjsModule(function(module){var reverseKeywords={};for(var key in colorName){if(colorName.hasOwnProperty(key)){reverseKeywords[colorName[key]]=key;}}
|
||||
var convert=module.exports={rgb:{channels:3,labels:'rgb'},hsl:{channels:3,labels:'hsl'},hsv:{channels:3,labels:'hsv'},hwb:{channels:3,labels:'hwb'},cmyk:{channels:4,labels:'cmyk'},xyz:{channels:3,labels:'xyz'},lab:{channels:3,labels:'lab'},lch:{channels:3,labels:'lch'},hex:{channels:1,labels:['hex']},keyword:{channels:1,labels:['keyword']},ansi16:{channels:1,labels:['ansi16']},ansi256:{channels:1,labels:['ansi256']},hcg:{channels:3,labels:['h','c','g']},apple:{channels:3,labels:['r16','g16','b16']},gray:{channels:1,labels:['gray']}};for(var model in convert){if(convert.hasOwnProperty(model)){if(!('channels'in convert[model])){throw new Error('missing channels property: '+model);}
|
||||
|
|
12
public/dist/scripts/app.js
vendored
12
public/dist/scripts/app.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-rtl.css
vendored
2
public/dist/styles/default-rtl.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
public/images/runtimes/java.png
Normal file
BIN
public/images/runtimes/java.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
File diff suppressed because it is too large
Load diff
|
@ -234,21 +234,21 @@ window.ls.filter
|
|||
|
||||
return $value.join(", ").replace(/,\s([^,]+)$/, ' and $1');
|
||||
})
|
||||
.add("envName", function($value, env) {
|
||||
.add("runtimeName", function($value, env) {
|
||||
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
|
||||
return env.RUNTIMES[$value].name;
|
||||
}
|
||||
|
||||
return '';
|
||||
})
|
||||
.add("envLogo", function($value, env) {
|
||||
.add("runtimeLogo", function($value, env) {
|
||||
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
|
||||
return env.RUNTIMES[$value].logo;
|
||||
}
|
||||
|
||||
return '';
|
||||
})
|
||||
.add("envVersion", function($value, env) {
|
||||
.add("runtimeVersion", function($value, env) {
|
||||
if(env && env.RUNTIMES && env.RUNTIMES[$value]) {
|
||||
return env.RUNTIMES[$value].version;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"use strict";
|
||||
|
||||
window.ls.container.set('console', function (window) {
|
||||
var sdk = new window.Appwrite.Appwrite();
|
||||
var sdk = new window.Appwrite();
|
||||
|
||||
sdk
|
||||
.setEndpoint(APP_ENV.ENDPOINT + APP_ENV.API)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"use strict";
|
||||
|
||||
window.ls.container.set('sdk', function (window, router) {
|
||||
var sdk = new window.Appwrite.Appwrite();
|
||||
var sdk = new window.Appwrite();
|
||||
|
||||
sdk
|
||||
.setEndpoint(APP_ENV.ENDPOINT + APP_ENV.API)
|
||||
|
|
|
@ -257,7 +257,7 @@
|
|||
args.map(function(value) {
|
||||
let result = getValue(value, prefix, data);
|
||||
|
||||
return result;
|
||||
return result ?? undefined;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -66,6 +66,12 @@
|
|||
--config-language-dart-contrast: #ffffff;
|
||||
--config-language-flutter: #035698;
|
||||
--config-language-flutter-contrast: #ffffff;
|
||||
--config-language-android: #a4c439;
|
||||
--config-language-android-contrast: #ffffff;
|
||||
--config-language-kotlin: #766DB2;
|
||||
--config-language-kotlin-contrast: #ffffff;
|
||||
--config-language-java: #0074bd;
|
||||
--config-language-java-contrast: #ffffff;
|
||||
--config-modal-note-background: #f5fbff;
|
||||
--config-modal-note-border: #eaf2f7;
|
||||
--config-modal-note-color: #3b5d73;
|
||||
|
|
|
@ -271,4 +271,32 @@ class Auth
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all roles for a user.
|
||||
*
|
||||
* @param Document $user
|
||||
* @return array
|
||||
*/
|
||||
public static function getRoles(Document $user): array
|
||||
{
|
||||
if ($user->getId()) {
|
||||
$roles[] = 'user:'.$user->getId();
|
||||
$roles[] = 'role:'.Auth::USER_ROLE_MEMBER;
|
||||
} else {
|
||||
return ['role:'.Auth::USER_ROLE_GUEST];
|
||||
}
|
||||
|
||||
foreach ($user->getAttribute('memberships', []) as $node) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
$roles[] = 'team:' . $node['teamId'];
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
$roles[] = 'team:' . $node['teamId'] . '/' . $nodeRole;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $roles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
namespace Appwrite\Database\Adapter;
|
||||
|
||||
use Utopia\Registry\Registry;
|
||||
use Appwrite\Database\Adapter;
|
||||
use Appwrite\Database\Exception\Duplicate;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Exception;
|
||||
use PDO;
|
||||
use Redis as Client;
|
||||
use Redis;
|
||||
|
||||
class MySQL extends Adapter
|
||||
{
|
||||
|
@ -23,11 +22,6 @@ class MySQL extends Adapter
|
|||
|
||||
const OPTIONS_LIMIT_ATTRIBUTES = 1000;
|
||||
|
||||
/**
|
||||
* @var Registry
|
||||
*/
|
||||
protected $register;
|
||||
|
||||
/**
|
||||
* Last modified.
|
||||
*
|
||||
|
@ -42,16 +36,28 @@ class MySQL extends Adapter
|
|||
*/
|
||||
protected $debug = [];
|
||||
|
||||
/**
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Set connection and settings
|
||||
*
|
||||
* @param Registry $register
|
||||
* @param PDO $pdo
|
||||
* @param Redis $redis
|
||||
*/
|
||||
public function __construct(Registry $register)
|
||||
public function __construct($pdo, Redis $redis)
|
||||
{
|
||||
$this->register = $register;
|
||||
$this->pdo = $pdo;
|
||||
$this->redis = $redis;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,8 +93,8 @@ class MySQL extends Adapter
|
|||
ORDER BY `order`
|
||||
');
|
||||
|
||||
$st->bindParam(':documentUid', $document['uid'], PDO::PARAM_STR);
|
||||
$st->bindParam(':documentRevision', $document['revision'], PDO::PARAM_STR);
|
||||
$st->bindParam(':documentUid', $document['uid'], PDO::PARAM_STR, 32);
|
||||
$st->bindParam(':documentRevision', $document['revision'], PDO::PARAM_STR, 32);
|
||||
|
||||
$st->execute();
|
||||
|
||||
|
@ -116,8 +122,8 @@ class MySQL extends Adapter
|
|||
ORDER BY `order`
|
||||
');
|
||||
|
||||
$st->bindParam(':start', $document['uid'], PDO::PARAM_STR);
|
||||
$st->bindParam(':revision', $document['revision'], PDO::PARAM_STR);
|
||||
$st->bindParam(':start', $document['uid'], PDO::PARAM_STR, 32);
|
||||
$st->bindParam(':revision', $document['revision'], PDO::PARAM_STR, 32);
|
||||
|
||||
$st->execute();
|
||||
|
||||
|
@ -933,18 +939,18 @@ class MySQL extends Adapter
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getPDO(): PDO
|
||||
protected function getPDO()
|
||||
{
|
||||
return $this->register->get('db');
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*
|
||||
* @return Client
|
||||
* @return Redis
|
||||
*/
|
||||
protected function getRedis(): Client
|
||||
protected function getRedis(): Redis
|
||||
{
|
||||
return $this->register->get('cache');
|
||||
return $this->redis;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Appwrite\Database\Adapter;
|
||||
|
||||
use Utopia\Registry\Registry;
|
||||
use Appwrite\Database\Adapter;
|
||||
use Exception;
|
||||
use Redis as Client;
|
||||
|
@ -10,9 +9,9 @@ use Redis as Client;
|
|||
class Redis extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var Registry
|
||||
* @var Client
|
||||
*/
|
||||
protected $register;
|
||||
protected $redis;
|
||||
|
||||
/**
|
||||
* @var Adapter
|
||||
|
@ -23,11 +22,11 @@ class Redis extends Adapter
|
|||
* Redis constructor.
|
||||
*
|
||||
* @param Adapter $adapter
|
||||
* @param Registry $register
|
||||
* @param Client $redis
|
||||
*/
|
||||
public function __construct(Adapter $adapter, Registry $register)
|
||||
public function __construct(Adapter $adapter, Client $redis)
|
||||
{
|
||||
$this->register = $register;
|
||||
$this->redis = $redis;
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
|
@ -261,7 +260,7 @@ class Redis extends Adapter
|
|||
*/
|
||||
protected function getRedis(): Client
|
||||
{
|
||||
return $this->register->get('cache');
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -281,4 +280,4 @@ class Redis extends Adapter
|
|||
|
||||
return parent::setNamespace($namespace);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
namespace Appwrite\Database;
|
||||
|
||||
abstract class Pool
|
||||
{
|
||||
protected $available = true;
|
||||
protected $pool;
|
||||
protected $size = 5;
|
||||
|
||||
abstract public function get();
|
||||
|
||||
public function destruct()
|
||||
{
|
||||
$this->available = false;
|
||||
while (!$this->pool->isEmpty()) {
|
||||
$this->pool->pop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Database\Pool;
|
||||
|
||||
use Appwrite\Database\Pool;
|
||||
use Appwrite\Extend\PDO;
|
||||
use SplQueue;
|
||||
|
||||
class PDOPool extends Pool
|
||||
{
|
||||
public function __construct(int $size, string $host = 'localhost', string $schema = 'appwrite', string $user = '', string $pass = '', string $charset = 'utf8mb4')
|
||||
{
|
||||
$this->pool = new SplQueue;
|
||||
$this->size = $size;
|
||||
for ($i = 0; $i < $this->size; $i++) {
|
||||
$pdo = new PDO(
|
||||
"mysql:" .
|
||||
"host={$host};" .
|
||||
"dbname={$schema};" .
|
||||
"charset={$charset}",
|
||||
$user,
|
||||
$pass,
|
||||
[
|
||||
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,
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
|
||||
]
|
||||
);
|
||||
$this->pool->enqueue($pdo);
|
||||
}
|
||||
}
|
||||
|
||||
public function put(PDO $pdo)
|
||||
{
|
||||
$this->pool->enqueue($pdo);
|
||||
}
|
||||
|
||||
public function get(): PDO
|
||||
{
|
||||
if ($this->available && count($this->pool) > 0) {
|
||||
return $this->pool->dequeue();
|
||||
}
|
||||
sleep(0.01);
|
||||
return $this->get();
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Database\Pool;
|
||||
|
||||
use Appwrite\Database\Pool;
|
||||
use SplQueue;
|
||||
|
||||
use Redis;
|
||||
|
||||
class RedisPool extends Pool
|
||||
{
|
||||
public function __construct(int $size, string $host, int $port, array $auth = [])
|
||||
{
|
||||
$this->pool = new SplQueue;
|
||||
$this->size = $size;
|
||||
for ($i = 0; $i < $this->size; $i++) {
|
||||
$redis = new Redis();
|
||||
$redis->pconnect($host, $port);
|
||||
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
if ($auth) {
|
||||
$redis->auth($auth);
|
||||
}
|
||||
|
||||
$this->pool->enqueue($redis);
|
||||
}
|
||||
}
|
||||
|
||||
public function put(Redis $redis)
|
||||
{
|
||||
$this->pool->enqueue($redis);
|
||||
}
|
||||
|
||||
public function get(): Redis
|
||||
{
|
||||
if ($this->available && !$this->pool->isEmpty()) {
|
||||
return $this->pool->dequeue();
|
||||
}
|
||||
sleep(0.1);
|
||||
return $this->get();
|
||||
}
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Utopia\App;
|
||||
|
||||
class Realtime
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $project = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $event = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $userId = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $channels = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $permissions = [];
|
||||
|
||||
/**
|
||||
* @var false
|
||||
*/
|
||||
protected $permissionsChanged = false;
|
||||
|
||||
/**
|
||||
* @var Document
|
||||
*/
|
||||
protected $payload;
|
||||
|
||||
|
||||
/**
|
||||
* Event constructor.
|
||||
*
|
||||
* @param string $project
|
||||
* @param string $event
|
||||
* @param array $payload
|
||||
*/
|
||||
public function __construct(string $project, string $event, array $payload)
|
||||
{
|
||||
$this->project = $project;
|
||||
$this->event = $event;
|
||||
$this->payload = new Document($payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $project
|
||||
* return $this
|
||||
*/
|
||||
public function setProject(string $project): self
|
||||
{
|
||||
$this->project = $project;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userId
|
||||
* return $this
|
||||
*/
|
||||
public function setUserId(string $userId): self
|
||||
{
|
||||
$this->userId = $userId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProject(): string
|
||||
{
|
||||
return $this->project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $event
|
||||
* return $this
|
||||
*/
|
||||
public function setEvent(string $event): self
|
||||
{
|
||||
$this->event = $event;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEvent(): string
|
||||
{
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $payload
|
||||
* @return $this
|
||||
*/
|
||||
public function setPayload(array $payload): self
|
||||
{
|
||||
$this->payload = new Document($payload);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Document
|
||||
*/
|
||||
public function getPayload(): Document
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate channels array based on the event name and payload.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function prepareChannels(): void
|
||||
{
|
||||
switch (true) {
|
||||
case strpos($this->event, 'account.recovery.') === 0:
|
||||
case strpos($this->event, 'account.sessions.') === 0:
|
||||
case strpos($this->event, 'account.verification.') === 0:
|
||||
$this->channels[] = 'account.' . $this->payload->getAttribute('userId');
|
||||
$this->permissions = ['user:' . $this->payload->getAttribute('userId')];
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'account.') === 0:
|
||||
$this->channels[] = 'account.' . $this->payload->getId();
|
||||
$this->permissions = ['user:' . $this->payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'teams.memberships') === 0:
|
||||
$this->permissionsChanged = in_array($this->event, ['teams.memberships.update', 'teams.memberships.delete', 'teams.memberships.update.status']);
|
||||
$this->channels[] = 'memberships';
|
||||
$this->channels[] = 'memberships.' . $this->payload->getId();
|
||||
$this->permissions = ['team:' . $this->payload->getAttribute('teamId')];
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'teams.') === 0:
|
||||
$this->permissionsChanged = $this->event === 'teams.create';
|
||||
$this->channels[] = 'teams';
|
||||
$this->channels[] = 'teams.' . $this->payload->getId();
|
||||
$this->permissions = ['team:' . $this->payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'database.collections.') === 0:
|
||||
$this->channels[] = 'collections';
|
||||
$this->channels[] = 'collections.' . $this->payload->getId();
|
||||
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'database.documents.') === 0:
|
||||
$this->channels[] = 'documents';
|
||||
$this->channels[] = 'collections.' . $this->payload->getAttribute('$collection') . '.documents';
|
||||
$this->channels[] = 'documents.' . $this->payload->getId();
|
||||
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'storage.') === 0:
|
||||
$this->channels[] = 'files';
|
||||
$this->channels[] = 'files.' . $this->payload->getId();
|
||||
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($this->event, 'functions.executions.') === 0:
|
||||
if (!empty($this->payload->getAttribute('$permissions.read'))) {
|
||||
$this->channels[] = 'executions';
|
||||
$this->channels[] = 'executions.' . $this->payload->getId();
|
||||
$this->channels[] = 'functions.' . $this->payload->getAttribute('functionId');
|
||||
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function trigger(): void
|
||||
{
|
||||
$this->prepareChannels();
|
||||
if (empty($this->channels)) return;
|
||||
|
||||
$redis = new \Redis();
|
||||
$redis->connect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
||||
$redis->publish('realtime', json_encode([
|
||||
'project' => $this->project,
|
||||
'permissions' => $this->permissions,
|
||||
'permissionsChanged' => $this->permissionsChanged,
|
||||
'userId' => $this->userId,
|
||||
'data' => [
|
||||
'event' => $this->event,
|
||||
'channels' => $this->channels,
|
||||
'timestamp' => time(),
|
||||
'payload' => $this->payload->getArrayCopy()
|
||||
]
|
||||
]));
|
||||
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this event and unpopulates all data.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reset(): self
|
||||
{
|
||||
$this->event = '';
|
||||
$this->payload = $this->channels = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
10
src/Appwrite/Messaging/Adapter.php
Normal file
10
src/Appwrite/Messaging/Adapter.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Messaging;
|
||||
|
||||
abstract class Adapter
|
||||
{
|
||||
public abstract function subscribe(string $project, mixed $identifier, array $roles, array $channels): void;
|
||||
public abstract function unsubscribe(mixed $identifier): void;
|
||||
public static abstract function send(string $projectId, array $payload, string $event, array $channels, array $permissions, array $options): void;
|
||||
}
|
295
src/Appwrite/Messaging/Adapter/Realtime.php
Normal file
295
src/Appwrite/Messaging/Adapter/Realtime.php
Normal file
|
@ -0,0 +1,295 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Messaging\Adapter;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Messaging\Adapter;
|
||||
use Utopia\App;
|
||||
|
||||
class Realtime extends Adapter
|
||||
{
|
||||
/**
|
||||
* Connection Tree
|
||||
*
|
||||
* [CONNECTION_ID] ->
|
||||
* 'projectId' -> [PROJECT_ID]
|
||||
* 'roles' -> [ROLE_x, ROLE_Y]
|
||||
* 'channels' -> [CHANNEL_NAME_X, CHANNEL_NAME_Y, CHANNEL_NAME_Z]
|
||||
*/
|
||||
public array $connections = [];
|
||||
|
||||
/**
|
||||
* Subscription Tree
|
||||
*
|
||||
* [PROJECT_ID] ->
|
||||
* [ROLE_X] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
* [ROLE_Y] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
*/
|
||||
public array $subscriptions = [];
|
||||
|
||||
/**
|
||||
* Adds a subscribtion.
|
||||
* @param string $projectId Project ID.
|
||||
* @param mixed $connection Unique Identifier - Connection ID.
|
||||
* @param array $roles Roles of the Subscription.
|
||||
* @param array $channels Subscribed Channels.
|
||||
* @return void
|
||||
*/
|
||||
public function subscribe(string $projectId, mixed $connection, array $roles, array $channels): void
|
||||
{
|
||||
if (!isset($this->subscriptions[$projectId])) { // Init Project
|
||||
$this->subscriptions[$projectId] = [];
|
||||
}
|
||||
|
||||
foreach ($roles as $role) {
|
||||
if (!isset($this->subscriptions[$projectId][$role])) { // Add user first connection
|
||||
$this->subscriptions[$projectId][$role] = [];
|
||||
}
|
||||
|
||||
foreach ($channels as $channel => $list) {
|
||||
$this->subscriptions[$projectId][$role][$channel][$connection] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->connections[$connection] = [
|
||||
'projectId' => $projectId,
|
||||
'roles' => $roles,
|
||||
'channels' => $channels
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes Subscription.
|
||||
*
|
||||
* @param mixed $connection
|
||||
* @return void
|
||||
*/
|
||||
public function unsubscribe(mixed $connection): void
|
||||
{
|
||||
$projectId = $this->connections[$connection]['projectId'] ?? '';
|
||||
$roles = $this->connections[$connection]['roles'] ?? [];
|
||||
|
||||
foreach ($roles as $role) {
|
||||
foreach ($this->subscriptions[$projectId][$role] as $channel => $list) {
|
||||
unset($this->subscriptions[$projectId][$role][$channel][$connection]); // Remove connection
|
||||
|
||||
if (empty($this->subscriptions[$projectId][$role][$channel])) {
|
||||
unset($this->subscriptions[$projectId][$role][$channel]); // Remove channel when no connections
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->subscriptions[$projectId][$role])) {
|
||||
unset($this->subscriptions[$projectId][$role]); // Remove role when no channels
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->subscriptions[$projectId])) { // Remove project when no roles
|
||||
unset($this->subscriptions[$projectId]);
|
||||
}
|
||||
|
||||
unset($this->connections[$connection]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Channel has a subscriber.
|
||||
* @param string $projectId
|
||||
* @param string $role
|
||||
* @param string $channel
|
||||
* @return bool
|
||||
*/
|
||||
public function hasSubscriber(string $projectId, string $role, string $channel = ''): bool
|
||||
{
|
||||
if (empty($channel)) {
|
||||
return array_key_exists($projectId, $this->subscriptions)
|
||||
&& array_key_exists($role, $this->subscriptions[$projectId]);
|
||||
}
|
||||
|
||||
return array_key_exists($projectId, $this->subscriptions)
|
||||
&& array_key_exists($role, $this->subscriptions[$projectId])
|
||||
&& array_key_exists($channel, $this->subscriptions[$projectId][$role]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an event to the Realtime Server.
|
||||
* @param string $project
|
||||
* @param array $payload
|
||||
* @param string $event
|
||||
* @param array $channels
|
||||
* @param array $permissions
|
||||
* @param array $options
|
||||
* @return void
|
||||
*/
|
||||
public static function send(string $project, array $payload, string $event, array $channels, array $permissions, array $options = []): void
|
||||
{
|
||||
if (empty($channels) || empty($permissions) || empty($project)) return;
|
||||
|
||||
$permissionsChanged = array_key_exists('permissionsChanged', $options) && $options['permissionsChanged'];
|
||||
$userId = array_key_exists('userId', $options) ? $options['userId'] : null;
|
||||
|
||||
$redis = new \Redis();
|
||||
$redis->connect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
||||
$redis->publish('realtime', json_encode([
|
||||
'project' => $project,
|
||||
'permissions' => $permissions,
|
||||
'permissionsChanged' => $permissionsChanged,
|
||||
'userId' => $userId,
|
||||
'data' => [
|
||||
'event' => $event,
|
||||
'channels' => $channels,
|
||||
'timestamp' => time(),
|
||||
'payload' => $payload
|
||||
]
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the receivers of all subscriptions, based on the permissions and event.
|
||||
*
|
||||
* Example of performance with an event with user:XXX permissions and with X users spread across 10 different channels:
|
||||
* - 0.014 ms (±6.88%) | 10 Connections / 100 Subscriptions
|
||||
* - 0.070 ms (±3.71%) | 100 Connections / 1,000 Subscriptions
|
||||
* - 0.846 ms (±2.74%) | 1,000 Connections / 10,000 Subscriptions
|
||||
* - 10.866 ms (±1.01%) | 10,000 Connections / 100,000 Subscriptions
|
||||
* - 110.201 ms (±2.32%) | 100,000 Connections / 1,000,000 Subscriptions
|
||||
* - 1,121.328 ms (±0.84%) | 1,000,000 Connections / 10,000,000 Subscriptions
|
||||
*
|
||||
* @param array $event
|
||||
*/
|
||||
public function getReceivers(array $event)
|
||||
{
|
||||
$receivers = [];
|
||||
if (isset($this->subscriptions[$event['project']])) {
|
||||
foreach ($this->subscriptions[$event['project']] as $role => $subscription) {
|
||||
foreach ($event['data']['channels'] as $channel) {
|
||||
if (
|
||||
\array_key_exists($channel, $this->subscriptions[$event['project']][$role])
|
||||
&& (\in_array($role, $event['permissions']) || \in_array('*', $event['permissions']))
|
||||
) {
|
||||
foreach (array_keys($this->subscriptions[$event['project']][$role][$channel]) as $ids) {
|
||||
$receivers[$ids] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($receivers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the channels from the Query Params into an array.
|
||||
* Also renames the account channel to account.USER_ID and removes all illegal account channel variations.
|
||||
* @param array $channels
|
||||
* @param Document $user
|
||||
* @return array
|
||||
*/
|
||||
public static function convertChannels(array $channels, Document $user): array
|
||||
{
|
||||
$channels = array_flip($channels);
|
||||
|
||||
foreach ($channels as $key => $value) {
|
||||
switch (true) {
|
||||
case strpos($key, 'account.') === 0:
|
||||
unset($channels[$key]);
|
||||
break;
|
||||
|
||||
case $key === 'account':
|
||||
if (!empty($user->getId())) {
|
||||
$channels['account.' . $user->getId()] = $value;
|
||||
}
|
||||
unset($channels['account']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (\array_key_exists('account', $channels)) {
|
||||
if ($user->getId()) {
|
||||
$channels['account.' . $user->getId()] = $channels['account'];
|
||||
}
|
||||
unset($channels['account']);
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create channels array based on the event name and payload.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function fromPayload(string $event, Document $payload): array
|
||||
{
|
||||
$channels = [];
|
||||
$permissions = [];
|
||||
$permissionsChanged = false;
|
||||
|
||||
switch (true) {
|
||||
case strpos($event, 'account.recovery.') === 0:
|
||||
case strpos($event, 'account.sessions.') === 0:
|
||||
case strpos($event, 'account.verification.') === 0:
|
||||
$channels[] = 'account.' . $payload->getAttribute('userId');
|
||||
$permissions = ['user:' . $payload->getAttribute('userId')];
|
||||
|
||||
break;
|
||||
case strpos($event, 'account.') === 0:
|
||||
$channels[] = 'account.' . $payload->getId();
|
||||
$permissions = ['user:' . $payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($event, 'teams.memberships') === 0:
|
||||
$permissionsChanged = in_array($event, ['teams.memberships.update', 'teams.memberships.delete', 'teams.memberships.update.status']);
|
||||
$channels[] = 'memberships';
|
||||
$channels[] = 'memberships.' . $payload->getId();
|
||||
$permissions = ['team:' . $payload->getAttribute('teamId')];
|
||||
|
||||
break;
|
||||
case strpos($event, 'teams.') === 0:
|
||||
$permissionsChanged = $event === 'teams.create';
|
||||
$channels[] = 'teams';
|
||||
$channels[] = 'teams.' . $payload->getId();
|
||||
$permissions = ['team:' . $payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($event, 'database.collections.') === 0:
|
||||
$channels[] = 'collections';
|
||||
$channels[] = 'collections.' . $payload->getId();
|
||||
$permissions = $payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($event, 'database.documents.') === 0:
|
||||
$channels[] = 'documents';
|
||||
$channels[] = 'collections.' . $payload->getAttribute('$collection') . '.documents';
|
||||
$channels[] = 'documents.' . $payload->getId();
|
||||
$permissions = $payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($event, 'storage.') === 0:
|
||||
$channels[] = 'files';
|
||||
$channels[] = 'files.' . $payload->getId();
|
||||
$permissions = $payload->getAttribute('$permissions.read');
|
||||
|
||||
break;
|
||||
case strpos($event, 'functions.executions.') === 0:
|
||||
if (!empty($payload->getAttribute('$permissions.read'))) {
|
||||
$channels[] = 'executions';
|
||||
$channels[] = 'executions.' . $payload->getId();
|
||||
$channels[] = 'functions.' . $payload->getAttribute('functionId');
|
||||
$permissions = $payload->getAttribute('$permissions.read');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return [
|
||||
'channels' => $channels,
|
||||
'permissions' => $permissions,
|
||||
'permissionsChanged' => $permissionsChanged
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Realtime;
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Document;
|
||||
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* @var Document $user
|
||||
*/
|
||||
static $user;
|
||||
|
||||
/**
|
||||
* Sets the current user for the role and channel parsing.
|
||||
*
|
||||
* @param Document $user
|
||||
*/
|
||||
static function setUser(Document $user)
|
||||
{
|
||||
self::$user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of roles that the set User has permissions to.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static function getRoles()
|
||||
{
|
||||
if (!isset(self::$user)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$roles = ['role:' . ((self::$user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER)];
|
||||
if (!(self::$user->isEmpty())) {
|
||||
$roles[] = 'user:' . self::$user->getId();
|
||||
}
|
||||
foreach (self::$user->getAttribute('memberships', []) as $node) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
$roles[] = 'team:' . $node['teamId'];
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
$roles[] = 'team:' . $node['teamId'] . '/' . $nodeRole;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the channels from the Query Params into an array.
|
||||
* Also renames the account channel to account.USER_ID and removes all illegal account channel variations.
|
||||
*
|
||||
* @param array $channels
|
||||
*/
|
||||
static function parseChannels(array $channels)
|
||||
{
|
||||
$channels = array_flip($channels);
|
||||
|
||||
foreach ($channels as $key => $value) {
|
||||
switch (true) {
|
||||
case strpos($key, 'account.') === 0:
|
||||
unset($channels[$key]);
|
||||
break;
|
||||
|
||||
case $key === 'account':
|
||||
if (!empty(self::$user->getId())) {
|
||||
$channels['account.' . self::$user->getId()] = $value;
|
||||
}
|
||||
unset($channels['account']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (\array_key_exists('account', $channels)) {
|
||||
if (self::$user->getId()) {
|
||||
$channels['account.' . self::$user->getId()] = $channels['account'];
|
||||
}
|
||||
unset($channels['account']);
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the receivers of all subscriptions, based on the permissions and event.
|
||||
*
|
||||
* Example of performance with an event with user:XXX permissions and with X users spread across 10 different channels:
|
||||
* - 0.014 ms (±6.88%) | 10 Connections / 100 Subscriptions
|
||||
* - 0.070 ms (±3.71%) | 100 Connections / 1,000 Subscriptions
|
||||
* - 0.846 ms (±2.74%) | 1,000 Connections / 10,000 Subscriptions
|
||||
* - 10.866 ms (±1.01%) | 10,000 Connections / 100,000 Subscriptions
|
||||
* - 110.201 ms (±2.32%) | 100,000 Connections / 1,000,000 Subscriptions
|
||||
* - 1,121.328 ms (±0.84%) | 1,000,000 Connections / 10,000,000 Subscriptions
|
||||
*
|
||||
* @param array $event
|
||||
* @param array $connections
|
||||
* @param array $subscriptions
|
||||
*/
|
||||
static function identifyReceivers(array &$event, array &$subscriptions)
|
||||
{
|
||||
$receivers = [];
|
||||
if (isset($subscriptions[$event['project']])) {
|
||||
foreach ($subscriptions[$event['project']] as $role => $subscription) {
|
||||
foreach ($event['data']['channels'] as $channel) {
|
||||
if (
|
||||
\array_key_exists($channel, $subscriptions[$event['project']][$role])
|
||||
&& (\in_array($role, $event['permissions']) || \in_array('*', $event['permissions']))
|
||||
) {
|
||||
foreach (array_keys($subscriptions[$event['project']][$role][$channel]) as $ids) {
|
||||
$receivers[$ids] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($receivers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Subscription.
|
||||
*
|
||||
* @param string $projectId
|
||||
* @param mixed $connection
|
||||
* @param array $subscriptions
|
||||
* @param array $roles
|
||||
* @param array $channels
|
||||
*/
|
||||
static function subscribe($projectId, $connection, $roles, &$subscriptions, &$connections, &$channels)
|
||||
{
|
||||
/**
|
||||
* Build Subscriptions Tree
|
||||
*
|
||||
* [PROJECT_ID] ->
|
||||
* [ROLE_X] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
* [ROLE_Y] ->
|
||||
* [CHANNEL_NAME_X] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Y] -> [CONNECTION_ID]
|
||||
* [CHANNEL_NAME_Z] -> [CONNECTION_ID]
|
||||
*/
|
||||
|
||||
if (!isset($subscriptions[$projectId])) { // Init Project
|
||||
$subscriptions[$projectId] = [];
|
||||
}
|
||||
|
||||
foreach ($roles as $role) {
|
||||
if (!isset($subscriptions[$projectId][$role])) { // Add user first connection
|
||||
$subscriptions[$projectId][$role] = [];
|
||||
}
|
||||
|
||||
foreach ($channels as $channel => $list) {
|
||||
$subscriptions[$projectId][$role][$channel][$connection] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$connections[$connection] = [
|
||||
'projectId' => $projectId,
|
||||
'roles' => $roles,
|
||||
'channels' => $channels
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Subscription.
|
||||
*
|
||||
* @param mixed $connection
|
||||
* @param array $subscriptions
|
||||
* @param array $connections
|
||||
*/
|
||||
static function unsubscribe($connection, &$subscriptions, &$connections)
|
||||
{
|
||||
$projectId = $connections[$connection]['projectId'] ?? '';
|
||||
$roles = $connections[$connection]['roles'] ?? [];
|
||||
|
||||
foreach ($roles as $role) {
|
||||
foreach ($subscriptions[$projectId][$role] as $channel => $list) {
|
||||
unset($subscriptions[$projectId][$role][$channel][$connection]); // Remove connection
|
||||
|
||||
if (empty($subscriptions[$projectId][$role][$channel])) {
|
||||
unset($subscriptions[$projectId][$role][$channel]); // Remove channel when no connections
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($subscriptions[$projectId][$role])) {
|
||||
unset($subscriptions[$projectId][$role]); // Remove role when no channels
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($subscriptions[$projectId])) { // Remove project when no roles
|
||||
unset($subscriptions[$projectId]);
|
||||
}
|
||||
|
||||
unset($connections[$connection]);
|
||||
}
|
||||
}
|
|
@ -1,553 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Realtime;
|
||||
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
||||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Exception;
|
||||
use Swoole\Coroutine\Redis;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Swoole\Process;
|
||||
use Swoole\Table;
|
||||
use Swoole\Timer;
|
||||
use Swoole\WebSocket\Frame;
|
||||
use Swoole\WebSocket\Server as SwooleServer;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Exception as UtopiaException;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Swoole\Request as SwooleRequest;
|
||||
|
||||
|
||||
class Server
|
||||
{
|
||||
/**
|
||||
* Container scoped Registry.
|
||||
* @var Registry
|
||||
*/
|
||||
public Registry $register;
|
||||
|
||||
/**
|
||||
* Container scoped Swoole Server.
|
||||
* @var SwooleServer
|
||||
*/
|
||||
public SwooleServer $server;
|
||||
|
||||
/**
|
||||
* Container scoped Usage Table.
|
||||
* @var Table
|
||||
*/
|
||||
public Table $usage;
|
||||
|
||||
/**
|
||||
* Container scoped Database connection.
|
||||
* @var Database
|
||||
*/
|
||||
public Database $consoleDb;
|
||||
|
||||
/**
|
||||
* Container scoped Database connection.
|
||||
* @var Database
|
||||
*/
|
||||
public Database $projectDb;
|
||||
|
||||
/**
|
||||
* Container scoped Redis connection.
|
||||
* @var Redis
|
||||
*/
|
||||
public Redis $cache;
|
||||
|
||||
/**
|
||||
* Worker scoped subscription.
|
||||
* @var array
|
||||
*/
|
||||
public array $subscriptions;
|
||||
|
||||
/**
|
||||
* Worker scoped connections.
|
||||
* @var array
|
||||
*/
|
||||
public array $connections;
|
||||
|
||||
public function __construct(Registry &$register, $host = '0.0.0.0', $port = 80, $config = [])
|
||||
{
|
||||
$this->subscriptions = [];
|
||||
$this->connections = [];
|
||||
$this->register = $register;
|
||||
|
||||
$this->usage = new Table(4096, 1);
|
||||
$this->usage->column('projectId', Table::TYPE_STRING, 64);
|
||||
$this->usage->column('connections', Table::TYPE_INT);
|
||||
$this->usage->column('connectionsTotal', Table::TYPE_INT);
|
||||
$this->usage->column('messages', Table::TYPE_INT);
|
||||
$this->usage->create();
|
||||
|
||||
$this->consoleDb = new Database();
|
||||
$this->consoleDb->setAdapter(new RedisAdapter(new MySQLAdapter($this->register), $this->register));
|
||||
$this->consoleDb->setNamespace('app_console');
|
||||
$this->consoleDb->setMocks(Config::getParam('collections', []));
|
||||
|
||||
$this->projectDb = new Database();
|
||||
$this->projectDb->setAdapter(new RedisAdapter(new MySQLAdapter($this->register), $this->register));
|
||||
$this->projectDb->setMocks(Config::getParam('collections', []));
|
||||
|
||||
$this->server = new SwooleServer($host, $port, SWOOLE_PROCESS);
|
||||
$this->server->set($config);
|
||||
$this->server->on('start', [$this, 'onStart']);
|
||||
$this->server->on('workerStart', [$this, 'onWorkerStart']);
|
||||
$this->server->on('open', [$this, 'onOpen']);
|
||||
$this->server->on('message', [$this, 'onMessage']);
|
||||
$this->server->on('close', [$this, 'onClose']);
|
||||
$this->server->container_id = uniqid();
|
||||
$this->server->start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when the Realtime server starts.
|
||||
*
|
||||
* @param SwooleServer $server
|
||||
* @return void
|
||||
*/
|
||||
public function onStart(SwooleServer $server): void
|
||||
{
|
||||
Console::success('Server started succefully');
|
||||
Console::info("Master pid {$server->master_pid}, manager pid {$server->manager_pid}");
|
||||
|
||||
try {
|
||||
go(function() {
|
||||
$document = [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'$permissions' => [
|
||||
'read' => ['*'],
|
||||
'write' => ['*'],
|
||||
],
|
||||
'container' => $this->server->container_id,
|
||||
'timestamp' => time(),
|
||||
'value' => '{}'
|
||||
];
|
||||
Authorization::disable();
|
||||
$document = $this->consoleDb->createDocument($document);
|
||||
Authorization::enable();
|
||||
$this->server->document_id = $document->getId();
|
||||
});
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('[Error] Type: '.get_class($th));
|
||||
Console::error('[Error] Message: '.$th->getMessage());
|
||||
Console::error('[Error] File: '.$th->getFile());
|
||||
Console::error('[Error] Line: '.$th->getLine());
|
||||
}
|
||||
|
||||
|
||||
// Run ever 10 seconds
|
||||
Timer::tick(10000, function () {
|
||||
/** @var Table $stats */
|
||||
foreach ($this->usage as $projectId => $value) {
|
||||
if (empty($value['connections']) && empty($value['messages'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$connections = $value['connections'];
|
||||
$messages = $value['messages'];
|
||||
|
||||
$usage = new Event('v1-usage', 'UsageV1');
|
||||
$usage
|
||||
->setParam('projectId', $projectId)
|
||||
->setParam('realtimeConnections', $connections)
|
||||
->setParam('realtimeMessages', $messages)
|
||||
->setParam('networkRequestSize', 0)
|
||||
->setParam('networkResponseSize', 0);
|
||||
|
||||
$this->usage->set($projectId, [
|
||||
'projectId' => $projectId,
|
||||
'messages' => 0,
|
||||
'connections' => 0
|
||||
]);
|
||||
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$usage->trigger();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Run ever 10 seconds
|
||||
Timer::tick(10000, function () {
|
||||
$payload = [];
|
||||
foreach ($this->usage as $projectId => $value) {
|
||||
if (!empty($value['connectionsTotal'])) {
|
||||
$payload[$projectId] = $value['connectionsTotal'];
|
||||
}
|
||||
}
|
||||
if (empty($payload)){
|
||||
return;
|
||||
}
|
||||
$document = [
|
||||
'$id' => $this->server->document_id,
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'$permissions' => [
|
||||
'read' => ['*'],
|
||||
'write' => ['*'],
|
||||
],
|
||||
'container' => $this->server->container_id,
|
||||
'timestamp' => time(),
|
||||
'value' => json_encode($payload)
|
||||
];
|
||||
try {
|
||||
$document = $this->consoleDb->updateDocument($document);
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('[Error] Type: '.get_class($th));
|
||||
Console::error('[Error] Message: '.$th->getMessage());
|
||||
Console::error('[Error] File: '.$th->getFile());
|
||||
Console::error('[Error] Line: '.$th->getLine());
|
||||
}
|
||||
});
|
||||
|
||||
Process::signal(2, function () use ($server) {
|
||||
Console::log('Stop by Ctrl+C');
|
||||
$server->shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when a WebSocket worker process starts.
|
||||
*
|
||||
* @param SwooleServer $server
|
||||
* @param int $workerId
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onWorkerStart(SwooleServer $server, int $workerId): void
|
||||
{
|
||||
Console::success('Worker ' . $workerId . ' started succefully');
|
||||
|
||||
$attempts = 0;
|
||||
$start = time();
|
||||
$redisPool = $this->register->get('redisPool');
|
||||
|
||||
/**
|
||||
* Sending current connections to project channels on the console project every 5 seconds.
|
||||
*/
|
||||
$server->tick(5000, function () use (&$server) {
|
||||
$this->tickSendProjectUsage($server);
|
||||
});
|
||||
|
||||
while ($attempts < 300) {
|
||||
try {
|
||||
if ($attempts > 0) {
|
||||
Console::error('Pub/sub connection lost (lasted ' . (time() - $start) . ' seconds, worker: ' . $workerId . ').
|
||||
Attempting restart in 5 seconds (attempt #' . $attempts . ')');
|
||||
sleep(5); // 5 sec delay between connection attempts
|
||||
}
|
||||
|
||||
/** @var Swoole\Coroutine\Redis $redis */
|
||||
$redis = $redisPool->get();
|
||||
|
||||
if ($redis->ping(true)) {
|
||||
$attempts = 0;
|
||||
Console::success('Pub/sub connection established (worker: ' . $workerId . ')');
|
||||
} else {
|
||||
Console::error('Pub/sub failed (worker: ' . $workerId . ')');
|
||||
}
|
||||
|
||||
$redis->subscribe(['realtime'], function ($redis, $channel, $payload) use ($server, $workerId) {
|
||||
$this->onRedisPublish($payload, $server, $workerId);
|
||||
});
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Pub/sub error: ' . $th->getMessage());
|
||||
$redisPool->put($redis);
|
||||
$attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$attempts++;
|
||||
}
|
||||
|
||||
Console::error('Failed to restart pub/sub...');
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when a new Realtime connection is established.
|
||||
* @param SwooleServer $server
|
||||
* @param Request $request
|
||||
* @return void
|
||||
* @throws Exception
|
||||
* @throws UtopiaException
|
||||
*/
|
||||
public function onOpen(SwooleServer $server, Request $request): void
|
||||
{
|
||||
$app = new App('UTC');
|
||||
$connection = $request->fd;
|
||||
$request = new SwooleRequest($request);
|
||||
|
||||
$db = $this->register->get('dbPool')->get();
|
||||
$redis = $this->register->get('redisPool')->get();
|
||||
|
||||
$this->register->set('db', function () use (&$db) {
|
||||
return $db;
|
||||
});
|
||||
|
||||
$this->register->set('cache', function () use (&$redis) {
|
||||
return $redis;
|
||||
});
|
||||
|
||||
Console::info("Connection open (user: {$connection}, worker: {$server->getWorkerId()})");
|
||||
|
||||
App::setResource('request', function () use ($request) {
|
||||
return $request;
|
||||
});
|
||||
|
||||
App::setResource('response', function () {
|
||||
return new Response(new SwooleResponse());
|
||||
});
|
||||
|
||||
try {
|
||||
/** @var \Appwrite\Database\Document $user */
|
||||
$user = $app->getResource('user');
|
||||
|
||||
/** @var \Appwrite\Database\Document $project */
|
||||
$project = $app->getResource('project');
|
||||
|
||||
/** @var \Appwrite\Database\Document $console */
|
||||
$console = $app->getResource('console');
|
||||
|
||||
/*
|
||||
* Project Check
|
||||
*/
|
||||
if (empty($project->getId())) {
|
||||
throw new Exception('Missing or unknown project ID', 1008);
|
||||
}
|
||||
|
||||
/*
|
||||
* Abuse Check
|
||||
*
|
||||
* Abuse limits are connecting 128 times per minute and ip address.
|
||||
*/
|
||||
$timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, function () use ($db) {
|
||||
return $db;
|
||||
});
|
||||
$timeLimit
|
||||
->setNamespace('app_' . $project->getId())
|
||||
->setParam('{ip}', $request->getIP())
|
||||
->setParam('{url}', $request->getURI());
|
||||
|
||||
$abuse = new Abuse($timeLimit);
|
||||
|
||||
if ($abuse->check() && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
|
||||
throw new Exception('Too many requests', 1013);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate Client Domain - Check to avoid CSRF attack.
|
||||
* Adding Appwrite API domains to allow XDOMAIN communication.
|
||||
* Skip this check for non-web platforms which are not required to send an origin header.
|
||||
*/
|
||||
$origin = $request->getOrigin();
|
||||
$originValidator = new Origin(\array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', [])));
|
||||
|
||||
if (!$originValidator->isValid($origin) && $project->getId() !== 'console') {
|
||||
throw new Exception($originValidator->getDescription(), 1008);
|
||||
}
|
||||
|
||||
Parser::setUser($user);
|
||||
|
||||
$roles = Parser::getRoles();
|
||||
$channels = Parser::parseChannels($request->getQuery('channels', []));
|
||||
|
||||
/**
|
||||
* Channels Check
|
||||
*/
|
||||
if (empty($channels)) {
|
||||
throw new Exception('Missing channels', 1008);
|
||||
}
|
||||
|
||||
Parser::subscribe($project->getId(), $connection, $roles, $this->subscriptions, $this->connections, $channels);
|
||||
|
||||
$server->push($connection, json_encode($channels));
|
||||
|
||||
$this->usage->incr($project->getId(), 'connections');
|
||||
$this->usage->incr($project->getId(), 'connectionsTotal');
|
||||
} catch (\Throwable $th) {
|
||||
$response = [
|
||||
'code' => $th->getCode(),
|
||||
'message' => $th->getMessage()
|
||||
];
|
||||
// Temporarily print debug logs by default for Alpha testing.
|
||||
//if (App::isDevelopment()) {
|
||||
Console::error("[Error] Connection Error");
|
||||
Console::error("[Error] Code: " . $response['code']);
|
||||
Console::error("[Error] Message: " . $response['message']);
|
||||
//}
|
||||
$server->push($connection, json_encode($response));
|
||||
$server->close($connection);
|
||||
}
|
||||
/**
|
||||
* Put used PDO and Redis Connections back into their pools.
|
||||
*/
|
||||
/** @var PDOPool $dbPool */
|
||||
$dbPool = $this->register->get('dbPool');
|
||||
$dbPool->put($db);
|
||||
|
||||
/** @var RedisPool $redisPool */
|
||||
$redisPool = $this->register->get('redisPool');
|
||||
$redisPool->put($redis);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when a message is received by the Realtime server.
|
||||
*
|
||||
* @param SwooleServer $server
|
||||
* @param Frame $frame
|
||||
* @return void
|
||||
*/
|
||||
public function onMessage(SwooleServer $server, Frame $frame)
|
||||
{
|
||||
$server->push($frame->fd, 'Sending messages is not allowed.');
|
||||
$server->close($frame->fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when a Realtime connection is closed.
|
||||
*
|
||||
* @param SwooleServer $server
|
||||
* @param int $connection
|
||||
* @return void
|
||||
*/
|
||||
public function onClose(SwooleServer $server, int $connection)
|
||||
{
|
||||
if (array_key_exists($connection, $this->connections)) {
|
||||
$this->usage->decr($this->connections[$connection]['projectId'], 'connectionsTotal');
|
||||
}
|
||||
Parser::unsubscribe($connection, $this->subscriptions, $this->connections);
|
||||
Console::info('Connection close: ' . $connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is executed when an event is published on realtime channel in Redis.
|
||||
*
|
||||
* Supported Resources:
|
||||
* - Collection
|
||||
* - Document
|
||||
* - File
|
||||
* - Account
|
||||
* - Session
|
||||
* - Team? (not implemented yet)
|
||||
* - Membership? (not implemented yet)
|
||||
* - Function
|
||||
* - Execution
|
||||
*
|
||||
* @param string $payload
|
||||
* @param SwooleServer $server
|
||||
* @param int $workerId
|
||||
* @return void
|
||||
*/
|
||||
public function onRedisPublish(string $payload, SwooleServer &$server, int $workerId)
|
||||
{
|
||||
$event = json_decode($payload, true);
|
||||
|
||||
if ($event['permissionsChanged'] && isset($event['userId'])) {
|
||||
$this->addPermission($event);
|
||||
}
|
||||
|
||||
$receivers = Parser::identifyReceivers($event, $this->subscriptions);
|
||||
|
||||
// Temporarily print debug logs by default for Alpha testing.
|
||||
// if (App::isDevelopment() && !empty($receivers)) {
|
||||
if (!empty($receivers)) {
|
||||
Console::log("[Debug][Worker {$workerId}] Receivers: " . count($receivers));
|
||||
Console::log("[Debug][Worker {$workerId}] Receivers Connection IDs: " . json_encode($receivers));
|
||||
Console::log("[Debug][Worker {$workerId}] Event: " . $payload);
|
||||
}
|
||||
|
||||
foreach ($receivers as $receiver) {
|
||||
if ($server->exist($receiver) && $server->isEstablished($receiver)) {
|
||||
$server->push(
|
||||
$receiver,
|
||||
json_encode($event['data']),
|
||||
SWOOLE_WEBSOCKET_OPCODE_TEXT,
|
||||
SWOOLE_WEBSOCKET_FLAG_FIN | SWOOLE_WEBSOCKET_FLAG_COMPRESS
|
||||
);
|
||||
} else {
|
||||
$server->close($receiver);
|
||||
}
|
||||
}
|
||||
if (($num = count($receivers)) > 0) {
|
||||
$this->usage->incr($event['project'], 'messages', $num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This sends the usage to the `console` channel.
|
||||
*
|
||||
* @param SwooleServer $server
|
||||
* @return void
|
||||
*/
|
||||
public function tickSendProjectUsage(SwooleServer &$server)
|
||||
{
|
||||
if (
|
||||
array_key_exists('console', $this->subscriptions)
|
||||
&& array_key_exists('role:member', $this->subscriptions['console'])
|
||||
&& array_key_exists('project', $this->subscriptions['console']['role:member'])
|
||||
) {
|
||||
$payload = [];
|
||||
$list = $this->consoleDb->getCollection([
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'timestamp>'.(time() - 15)
|
||||
],
|
||||
]);
|
||||
|
||||
foreach ($list as $document) {
|
||||
foreach (json_decode($document->getAttribute('value')) as $projectId => $value) {
|
||||
if (array_key_exists($projectId, $payload)) {
|
||||
$payload[$projectId] += $value;
|
||||
} else {
|
||||
$payload[$projectId] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->subscriptions['console']['role:member']['project'] as $connection => $value) {
|
||||
$server->push(
|
||||
$connection,
|
||||
json_encode([
|
||||
'event' => 'stats.connections',
|
||||
'channels' => ['project'],
|
||||
'timestamp' => time(),
|
||||
'payload' => $payload
|
||||
]),
|
||||
SWOOLE_WEBSOCKET_OPCODE_TEXT,
|
||||
SWOOLE_WEBSOCKET_FLAG_FIN | SWOOLE_WEBSOCKET_FLAG_COMPRESS
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addPermission(array $event)
|
||||
{
|
||||
$project = $event['project'];
|
||||
$userId = $event['userId'];
|
||||
|
||||
if (array_key_exists($project, $this->subscriptions) && array_key_exists('user:'.$userId, $this->subscriptions[$project])) {
|
||||
$connection = array_key_first(reset($this->subscriptions[$project]['user:'.$userId]));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->projectDb->setNamespace('app_'.$project);
|
||||
|
||||
$user = $this->projectDb->getDocument($userId);
|
||||
|
||||
Parser::setUser($user);
|
||||
|
||||
$roles = Parser::getRoles();
|
||||
|
||||
Parser::subscribe($project, $connection, $roles, $this->subscriptions, $this->connections, $this->connections[$connection]['channels']);
|
||||
}
|
||||
}
|
|
@ -47,9 +47,9 @@ class Func extends Model
|
|||
'default' => '',
|
||||
'example' => 'enabled',
|
||||
])
|
||||
->addRule('env', [
|
||||
->addRule('runtime', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Function execution environment.',
|
||||
'description' => 'Function execution runtime.',
|
||||
'default' => '',
|
||||
'example' => 'python-3.8',
|
||||
])
|
||||
|
|
|
@ -26,7 +26,7 @@ export default function () {
|
|||
'X-Appwrite-Project': '60479fe35d95d'
|
||||
}}
|
||||
|
||||
const resDb = http.get('http://localhost:9501/v1/health/db', config);
|
||||
const resDb = http.get('http://localhost:9501/', config);
|
||||
|
||||
check(resDb, {
|
||||
'status is 200': (r) => r.status === 200,
|
||||
|
|
|
@ -8,11 +8,11 @@ export let options = {
|
|||
stages: [
|
||||
{
|
||||
duration: '10s',
|
||||
target: 10
|
||||
target: 500
|
||||
},
|
||||
{
|
||||
duration: '30m',
|
||||
target: 10
|
||||
duration: '1m',
|
||||
target: 500
|
||||
},
|
||||
],
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ 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', '60476312f335c');
|
||||
url.searchParams.append('project', 'console');
|
||||
url.searchParams.append('channels[]', 'files');
|
||||
|
||||
const res = ws.connect(url.toString(), function (socket) {
|
||||
|
|
|
@ -424,4 +424,39 @@ class AccountCustomClientTest extends Scope
|
|||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function testGetSessionByID() {
|
||||
$session = $this->testCreateAnonymousAccount();
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/current', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]));
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertEquals($response['body']['provider'], 'anonymous');
|
||||
|
||||
$sessionID = $response['body']['$id'];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/'.$sessionID, array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]));
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertEquals($response['body']['provider'], 'anonymous');
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/account/sessions/97823askjdkasd80921371980', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]));
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 404);
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'name' => 'Test',
|
||||
'execute' => ['user:'.$this->getUser()['$id']],
|
||||
'env' => 'php-8.0',
|
||||
'runtime' => 'php-8.0',
|
||||
'vars' => [
|
||||
'funcKey1' => 'funcValue1',
|
||||
'funcKey2' => 'funcValue2',
|
||||
|
@ -140,7 +140,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
], [
|
||||
'name' => 'Test',
|
||||
'execute' => ['*'],
|
||||
'env' => 'php-8.0',
|
||||
'runtime' => 'php-8.0',
|
||||
'vars' => [
|
||||
'funcKey1' => 'funcValue1',
|
||||
'funcKey2' => 'funcValue2',
|
||||
|
|
|
@ -24,7 +24,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test',
|
||||
'env' => 'php-8.0',
|
||||
'runtime' => 'php-8.0',
|
||||
'vars' => [
|
||||
'funcKey1' => 'funcValue1',
|
||||
'funcKey2' => 'funcValue2',
|
||||
|
@ -43,7 +43,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(201, $response1['headers']['status-code']);
|
||||
$this->assertNotEmpty($response1['body']['$id']);
|
||||
$this->assertEquals('Test', $response1['body']['name']);
|
||||
$this->assertEquals('php-8.0', $response1['body']['env']);
|
||||
$this->assertEquals('php-8.0', $response1['body']['runtime']);
|
||||
$this->assertIsInt($response1['body']['dateCreated']);
|
||||
$this->assertIsInt($response1['body']['dateUpdated']);
|
||||
$this->assertEquals('', $response1['body']['tag']);
|
||||
|
@ -327,7 +327,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('PHP', $execution['body']['stdout']);
|
||||
$this->assertStringContainsString('8.0', $execution['body']['stdout']);
|
||||
$this->assertEquals('', $execution['body']['stderr']);
|
||||
$this->assertGreaterThan(0.100, $execution['body']['time']);
|
||||
$this->assertGreaterThan(0.05, $execution['body']['time']);
|
||||
$this->assertLessThan(0.500, $execution['body']['time']);
|
||||
|
||||
/**
|
||||
|
@ -462,7 +462,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test '.$name,
|
||||
'env' => $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [],
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
|
@ -540,7 +540,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test '.$name,
|
||||
'env' => $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [],
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
|
|
|
@ -22,7 +22,7 @@ trait RealtimeBase
|
|||
];
|
||||
return new WebSocketClient('ws://appwrite-traefik/v1/realtime?' . http_build_query($query), [
|
||||
'headers' => $headers,
|
||||
'timeout' => 60,
|
||||
'timeout' => 30,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -622,7 +622,7 @@ trait RealtimeBase
|
|||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'name' => 'Test',
|
||||
'env' => 'php-7.4',
|
||||
'runtime' => 'php-7.4',
|
||||
'execute' => ['*'],
|
||||
'timeout' => 10,
|
||||
]);
|
||||
|
|
|
@ -306,7 +306,7 @@ class WebhooksCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test',
|
||||
'env' => 'php-8.0',
|
||||
'runtime' => 'php-8.0',
|
||||
'execute' => ['*'],
|
||||
'timeout' => 10,
|
||||
]);
|
||||
|
@ -348,7 +348,7 @@ class WebhooksCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Test',
|
||||
'env' => 'php-8.0',
|
||||
'runtime' => 'php-8.0',
|
||||
'execute' => ['*'],
|
||||
'vars' => [
|
||||
'key1' => 'value1',
|
||||
|
|
|
@ -196,4 +196,48 @@ class AuthTest extends TestCase
|
|||
$this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_OWNER => true, 'role:'.Auth::USER_ROLE_GUEST => true]));
|
||||
$this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_OWNER => true, 'role:'.Auth::USER_ROLE_ADMIN => true, 'role:'.Auth::USER_ROLE_DEVELOPER => true]));
|
||||
}
|
||||
|
||||
public function testGuestRoles()
|
||||
{
|
||||
$user = new Document([
|
||||
'$id' => ''
|
||||
]);
|
||||
|
||||
$roles = Auth::getRoles($user);
|
||||
$this->assertCount(1, $roles);
|
||||
$this->assertContains('role:guest', $roles);
|
||||
}
|
||||
|
||||
public function testUserRoles()
|
||||
{
|
||||
$user = new Document([
|
||||
'$id' => '123',
|
||||
'memberships' => [
|
||||
[
|
||||
'teamId' => 'abc',
|
||||
'roles' => [
|
||||
'administrator',
|
||||
'moderator'
|
||||
]
|
||||
],
|
||||
[
|
||||
'teamId' => 'def',
|
||||
'roles' => [
|
||||
'guest'
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
$this->assertCount(7, $roles);
|
||||
$this->assertContains('role:member', $roles);
|
||||
$this->assertContains('user:123', $roles);
|
||||
$this->assertContains('team:abc', $roles);
|
||||
$this->assertContains('team:abc/administrator', $roles);
|
||||
$this->assertContains('team:abc/moderator', $roles);
|
||||
$this->assertContains('team:def', $roles);
|
||||
$this->assertContains('team:def/guest', $roles);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Realtime;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RealtimeChannelsTest extends TestCase
|
||||
class MessagingChannelsTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Configures how many Connections the Test should Mock.
|
||||
*/
|
||||
public $connectionsPerChannel = 10;
|
||||
|
||||
public $connections = [];
|
||||
public $subscriptions = [];
|
||||
public Realtime $realtime;
|
||||
public $connectionsCount = 0;
|
||||
public $connectionsAuthenticated = 0;
|
||||
public $connectionsGuest = 0;
|
||||
|
@ -41,12 +41,14 @@ class RealtimeChannelsTest extends TestCase
|
|||
$this->connectionsGuest = count($this->allChannels) * $this->connectionsPerChannel;
|
||||
$this->connectionsTotal = $this->connectionsAuthenticated + $this->connectionsGuest;
|
||||
|
||||
$this->realtime = new Realtime();
|
||||
|
||||
/**
|
||||
* Add Authenticated Clients
|
||||
*/
|
||||
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
||||
foreach ($this->allChannels as $index => $channel) {
|
||||
Realtime\Parser::setUser(new Document([
|
||||
$user = new Document([
|
||||
'$id' => 'user' . $this->connectionsCount,
|
||||
'memberships' => [
|
||||
[
|
||||
|
@ -56,16 +58,16 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
]
|
||||
]
|
||||
]));
|
||||
$roles = Realtime\Parser::getRoles();
|
||||
$parsedChannels = Realtime\Parser::parseChannels([0 => $channel]);
|
||||
]);
|
||||
|
||||
Realtime\Parser::subscribe(
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
$parsedChannels = Realtime::convertChannels([0 => $channel], $user);
|
||||
|
||||
$this->realtime->subscribe(
|
||||
'1',
|
||||
$this->connectionsCount,
|
||||
$roles,
|
||||
$this->subscriptions,
|
||||
$this->connections,
|
||||
$parsedChannels
|
||||
);
|
||||
|
||||
|
@ -78,19 +80,18 @@ class RealtimeChannelsTest extends TestCase
|
|||
*/
|
||||
for ($i = 0; $i < $this->connectionsPerChannel; $i++) {
|
||||
foreach ($this->allChannels as $index => $channel) {
|
||||
Realtime\Parser::setUser(new Document([
|
||||
$user = new Document([
|
||||
'$id' => ''
|
||||
]));
|
||||
]);
|
||||
|
||||
$roles = Realtime\Parser::getRoles();
|
||||
$parsedChannels = Realtime\Parser::parseChannels([0 => $channel]);
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
Realtime\Parser::subscribe(
|
||||
$parsedChannels = Realtime::convertChannels([0 => $channel], $user);
|
||||
|
||||
$this->realtime->subscribe(
|
||||
'1',
|
||||
$this->connectionsCount,
|
||||
$roles,
|
||||
$this->subscriptions,
|
||||
$this->connections,
|
||||
$parsedChannels
|
||||
);
|
||||
|
||||
|
@ -101,8 +102,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
|
||||
public function tearDown(): void
|
||||
{
|
||||
$this->connections = [];
|
||||
$this->subscriptions = [];
|
||||
unset($this->realtime);
|
||||
$this->connectionsCount = 0;
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
/**
|
||||
* Check for 1 project.
|
||||
*/
|
||||
$this->assertCount(1, $this->subscriptions);
|
||||
$this->assertCount(1, $this->realtime->subscriptions);
|
||||
|
||||
/**
|
||||
* Check for correct amount of subscriptions:
|
||||
|
@ -121,28 +121,28 @@ class RealtimeChannelsTest extends TestCase
|
|||
* - 1 role:guest
|
||||
* - 1 role:member
|
||||
*/
|
||||
$this->assertCount(($this->connectionsAuthenticated + (3 * $this->connectionsPerChannel) + 2), $this->subscriptions['1']);
|
||||
$this->assertCount(($this->connectionsAuthenticated + (3 * $this->connectionsPerChannel) + 2), $this->realtime->subscriptions['1']);
|
||||
|
||||
/**
|
||||
* Check for connections
|
||||
* - Authenticated
|
||||
* - Guests
|
||||
*/
|
||||
$this->assertCount($this->connectionsTotal, $this->connections);
|
||||
$this->assertCount($this->connectionsTotal, $this->realtime->connections);
|
||||
|
||||
$this->realtime->unsubscribe(-1);
|
||||
|
||||
Realtime\Parser::unsubscribe(-1, $this->subscriptions, $this->connections);
|
||||
|
||||
$this->assertCount($this->connectionsTotal, $this->connections);
|
||||
$this->assertCount(($this->connectionsAuthenticated + (3 * $this->connectionsPerChannel) + 2), $this->subscriptions['1']);
|
||||
$this->assertCount($this->connectionsTotal, $this->realtime->connections);
|
||||
$this->assertCount(($this->connectionsAuthenticated + (3 * $this->connectionsPerChannel) + 2), $this->realtime->subscriptions['1']);
|
||||
|
||||
for ($i = 0; $i < $this->connectionsCount; $i++) {
|
||||
Realtime\Parser::unsubscribe($i, $this->subscriptions, $this->connections);
|
||||
$this->realtime->unsubscribe($i);
|
||||
|
||||
$this->assertCount(($this->connectionsCount - $i - 1), $this->connections);
|
||||
$this->assertCount(($this->connectionsCount - $i - 1), $this->realtime->connections);
|
||||
}
|
||||
|
||||
$this->assertEmpty($this->connections);
|
||||
$this->assertEmpty($this->subscriptions);
|
||||
$this->assertEmpty($this->realtime->connections);
|
||||
$this->assertEmpty($this->realtime->subscriptions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,10 +161,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $this->realtime->getReceivers($event);
|
||||
|
||||
/**
|
||||
* Every Client subscribed to the Wildcard should receive this event.
|
||||
|
@ -197,10 +194,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $this->realtime->getReceivers($event);
|
||||
|
||||
/**
|
||||
* Every Role subscribed to a Channel should receive this event.
|
||||
|
@ -234,10 +228,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $this->realtime->getReceivers($event);
|
||||
|
||||
/**
|
||||
* Every Client subscribed to a Channel should receive this event.
|
||||
|
@ -271,10 +262,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $this->realtime->getReceivers($event);
|
||||
|
||||
/**
|
||||
* Every Team Member should receive this event.
|
||||
|
@ -300,10 +288,7 @@ class RealtimeChannelsTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $this->realtime->getReceivers($event);
|
||||
|
||||
/**
|
||||
* Only 1 Team Member of a role should have access to a specific channel.
|
128
tests/unit/Messaging/MessagingGuestTest.php
Normal file
128
tests/unit/Messaging/MessagingGuestTest.php
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MessagingGuestTest extends TestCase
|
||||
{
|
||||
public function testGuest()
|
||||
{
|
||||
$realtime = new Realtime();
|
||||
|
||||
$realtime->subscribe(
|
||||
'1',
|
||||
1,
|
||||
['role:guest'],
|
||||
['files' => 0, 'documents' => 0, 'documents.789' => 0, 'account.123' => 0]
|
||||
);
|
||||
|
||||
$event = [
|
||||
'project' => '1',
|
||||
'permissions' => ['*'],
|
||||
'data' => [
|
||||
'channels' => [
|
||||
0 => 'documents',
|
||||
1 => 'documents',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['role:guest'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['role:member'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['user:123'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc/administrator'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc/god'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def/guest'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['user:456'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def/member'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['*'];
|
||||
$event['data']['channels'] = ['documents.123'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['data']['channels'] = ['documents.789'];
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['project'] = '2';
|
||||
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$realtime->unsubscribe(2);
|
||||
|
||||
$this->assertCount(1, $realtime->connections);
|
||||
$this->assertCount(1, $realtime->subscriptions['1']);
|
||||
|
||||
$realtime->unsubscribe(1);
|
||||
|
||||
$this->assertEmpty($realtime->connections);
|
||||
$this->assertEmpty($realtime->subscriptions);
|
||||
}
|
||||
}
|
|
@ -3,14 +3,11 @@
|
|||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Realtime;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RealtimeTest extends TestCase
|
||||
class MessagingTest extends TestCase
|
||||
{
|
||||
public $connections = [];
|
||||
public $subscriptions = [];
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
}
|
||||
|
@ -21,55 +18,14 @@ class RealtimeTest extends TestCase
|
|||
|
||||
public function testUser()
|
||||
{
|
||||
Realtime\Parser::setUser(new Document([
|
||||
'$id' => '123',
|
||||
'memberships' => [
|
||||
[
|
||||
'teamId' => 'abc',
|
||||
'roles' => [
|
||||
'administrator',
|
||||
'god'
|
||||
]
|
||||
],
|
||||
[
|
||||
'teamId' => 'def',
|
||||
'roles' => [
|
||||
'guest'
|
||||
]
|
||||
]
|
||||
]
|
||||
]));
|
||||
$realtime = new Realtime();
|
||||
|
||||
$roles = Realtime\Parser::getRoles();
|
||||
|
||||
$this->assertCount(7, $roles);
|
||||
$this->assertContains('user:123', $roles);
|
||||
$this->assertContains('role:member', $roles);
|
||||
$this->assertContains('team:abc', $roles);
|
||||
$this->assertContains('team:abc/administrator', $roles);
|
||||
$this->assertContains('team:abc/god', $roles);
|
||||
$this->assertContains('team:def', $roles);
|
||||
$this->assertContains('team:def/guest', $roles);
|
||||
|
||||
$channels = [
|
||||
0 => 'files',
|
||||
1 => 'documents',
|
||||
2 => 'documents.789',
|
||||
3 => 'account',
|
||||
4 => 'account.456'
|
||||
];
|
||||
|
||||
$channels = Realtime\Parser::parseChannels($channels);
|
||||
|
||||
$this->assertCount(4, $channels);
|
||||
$this->assertArrayHasKey('files', $channels);
|
||||
$this->assertArrayHasKey('documents', $channels);
|
||||
$this->assertArrayHasKey('documents.789', $channels);
|
||||
$this->assertArrayHasKey('account.123', $channels);
|
||||
$this->assertArrayNotHasKey('account', $channels);
|
||||
$this->assertArrayNotHasKey('account.456', $channels);
|
||||
|
||||
Realtime\Parser::subscribe('1', 1, $roles, $this->subscriptions, $this->connections, $channels);
|
||||
$realtime->subscribe(
|
||||
'1',
|
||||
1,
|
||||
['user:123', 'role:member', 'team:abc', 'team:abc/administrator', 'team:abc/moderator', 'team:def', 'team:def/guest'],
|
||||
['files' => 0, 'documents' => 0, 'documents.789' => 0, 'account.123' => 0]
|
||||
);
|
||||
|
||||
$event = [
|
||||
'project' => '1',
|
||||
|
@ -81,140 +37,162 @@ class RealtimeTest extends TestCase
|
|||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['role:member'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['user:123'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['team:abc'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['team:abc/administrator'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['team:abc/god'];
|
||||
$event['permissions'] = ['team:abc/moderator'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['team:def'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['team:def/guest'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['user:456'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def/member'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['*'];
|
||||
$event['data']['channels'] = ['documents.123'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['data']['channels'] = ['documents.789'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['project'] = '2';
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
$receivers = $realtime->getReceivers($event);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
Realtime\Parser::unsubscribe(2, $this->subscriptions, $this->connections);
|
||||
$realtime->unsubscribe(2);
|
||||
|
||||
$this->assertCount(1, $this->connections);
|
||||
$this->assertCount(7, $this->subscriptions['1']);
|
||||
$this->assertCount(1, $realtime->connections);
|
||||
$this->assertCount(7, $realtime->subscriptions['1']);
|
||||
|
||||
$realtime->unsubscribe(1);
|
||||
|
||||
Realtime\Parser::unsubscribe(1, $this->subscriptions, $this->connections);
|
||||
$this->assertEmpty($realtime->connections);
|
||||
$this->assertEmpty($realtime->subscriptions);
|
||||
}
|
||||
|
||||
$this->assertEmpty($this->connections);
|
||||
$this->assertEmpty($this->subscriptions);
|
||||
public function testConvertChannelsGuest()
|
||||
{
|
||||
$user = new Document([
|
||||
'$id' => ''
|
||||
]);
|
||||
|
||||
$channels = [
|
||||
0 => 'files',
|
||||
1 => 'documents',
|
||||
2 => 'documents.789',
|
||||
3 => 'account',
|
||||
4 => 'account.456'
|
||||
];
|
||||
|
||||
$channels = Realtime::convertChannels($channels, $user);
|
||||
$this->assertCount(3, $channels);
|
||||
$this->assertArrayHasKey('files', $channels);
|
||||
$this->assertArrayHasKey('documents', $channels);
|
||||
$this->assertArrayHasKey('documents.789', $channels);
|
||||
$this->assertArrayNotHasKey('account', $channels);
|
||||
$this->assertArrayNotHasKey('account.456', $channels);
|
||||
}
|
||||
|
||||
public function testConvertChannelsUser()
|
||||
{
|
||||
$user = new Document([
|
||||
'$id' => '123',
|
||||
'memberships' => [
|
||||
[
|
||||
'teamId' => 'abc',
|
||||
'roles' => [
|
||||
'administrator',
|
||||
'moderator'
|
||||
]
|
||||
],
|
||||
[
|
||||
'teamId' => 'def',
|
||||
'roles' => [
|
||||
'guest'
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
||||
$channels = [
|
||||
0 => 'files',
|
||||
1 => 'documents',
|
||||
2 => 'documents.789',
|
||||
3 => 'account',
|
||||
4 => 'account.456'
|
||||
];
|
||||
|
||||
$channels = Realtime::convertChannels($channels, $user);
|
||||
|
||||
$this->assertCount(4, $channels);
|
||||
$this->assertArrayHasKey('files', $channels);
|
||||
$this->assertArrayHasKey('documents', $channels);
|
||||
$this->assertArrayHasKey('documents.789', $channels);
|
||||
$this->assertArrayHasKey('account.123', $channels);
|
||||
$this->assertArrayNotHasKey('account', $channels);
|
||||
$this->assertArrayNotHasKey('account.456', $channels);
|
||||
}
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Realtime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RealtimeGuestTest extends TestCase
|
||||
{
|
||||
public $connections = [];
|
||||
public $subscriptions = [];
|
||||
|
||||
public function testGuest()
|
||||
{
|
||||
Realtime\Parser::setUser(new Document([
|
||||
'$id' => ''
|
||||
]));
|
||||
|
||||
$roles = Realtime\Parser::getRoles();
|
||||
$this->assertCount(1, $roles);
|
||||
$this->assertContains('role:guest', $roles);
|
||||
|
||||
$channels = [
|
||||
0 => 'files',
|
||||
1 => 'documents',
|
||||
2 => 'documents.789',
|
||||
3 => 'account',
|
||||
4 => 'account.456'
|
||||
];
|
||||
|
||||
$channels = Realtime\Parser::parseChannels($channels);
|
||||
$this->assertCount(3, $channels);
|
||||
$this->assertArrayHasKey('files', $channels);
|
||||
$this->assertArrayHasKey('documents', $channels);
|
||||
$this->assertArrayHasKey('documents.789', $channels);
|
||||
$this->assertArrayNotHasKey('account', $channels);
|
||||
$this->assertArrayNotHasKey('account.456', $channels);
|
||||
|
||||
Realtime\Parser::subscribe('1', 1, $roles, $this->subscriptions, $this->connections, $channels);
|
||||
|
||||
$event = [
|
||||
'project' => '1',
|
||||
'permissions' => ['*'],
|
||||
'data' => [
|
||||
'channels' => [
|
||||
0 => 'documents',
|
||||
1 => 'documents',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['role:guest'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['permissions'] = ['role:member'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['user:123'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc/administrator'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:abc/god'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def/guest'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['user:456'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['team:def/member'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['permissions'] = ['*'];
|
||||
$event['data']['channels'] = ['documents.123'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
$event['data']['channels'] = ['documents.789'];
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertCount(1, $receivers);
|
||||
$this->assertEquals(1, $receivers[0]);
|
||||
|
||||
$event['project'] = '2';
|
||||
|
||||
$receivers = Realtime\Parser::identifyReceivers(
|
||||
$event,
|
||||
$this->subscriptions
|
||||
);
|
||||
|
||||
$this->assertEmpty($receivers);
|
||||
|
||||
Realtime\Parser::unsubscribe(2, $this->subscriptions, $this->connections);
|
||||
|
||||
$this->assertCount(1, $this->connections);
|
||||
$this->assertCount(1, $this->subscriptions['1']);
|
||||
|
||||
Realtime\Parser::unsubscribe(1, $this->subscriptions, $this->connections);
|
||||
|
||||
$this->assertEmpty($this->connections);
|
||||
$this->assertEmpty($this->subscriptions);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue