Merge remote-tracking branch 'origin/1.1.x' into feat-graphql-support
# Conflicts: # app/config/specs/open-api3-latest-client.json # app/config/specs/open-api3-latest-console.json # app/config/specs/open-api3-latest-server.json # app/config/specs/swagger2-latest-client.json # app/config/specs/swagger2-latest-console.json # app/config/specs/swagger2-latest-server.json # app/init.php # composer.json # composer.lock
This commit is contained in:
commit
cecc6dada2
42 changed files with 498 additions and 544 deletions
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -21,6 +21,11 @@ Happy contributing!
|
|||
|
||||
(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)
|
||||
|
||||
### Have you added your change to the [Changelog](https://github.com/appwrite/appwrite/blob/master/CHANGES.md)?
|
||||
|
||||
(The CHANGES.md file tracks all the changes that make it to the `main` branch. Add your change to this file in the following format)
|
||||
- One line description of your PR [#pr_number](Link to your PR)
|
||||
|
||||
### Have you read the [Contributing Guidelines on issues](https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md)?
|
||||
|
||||
(Write your answer here.)
|
||||
|
|
|
@ -523,6 +523,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('region'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 128,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('description'),
|
||||
'type' => Database::VAR_STRING,
|
||||
|
@ -737,6 +748,13 @@ $collections = [
|
|||
'lengths' => [128],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_team'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['teamId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
@ -3010,6 +3028,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('region'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 255,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('value'),
|
||||
'type' => Database::VAR_INTEGER,
|
||||
|
|
9
app/config/regions.php
Normal file
9
app/config/regions.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'name' => 'Default',
|
||||
'default' => true,
|
||||
'disabled' => false,
|
||||
]
|
||||
];
|
|
@ -58,6 +58,7 @@ App::post('/v1/projects')
|
|||
->param('projectId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('region', '', new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn($config) => !$config['disabled']))), 'Project Region.')
|
||||
->param('description', '', new Text(256), 'Project description. Max length: 256 chars.', true)
|
||||
->param('logo', '', new Text(1024), 'Project logo.', true)
|
||||
->param('url', '', new URL(), 'Project URL.', true)
|
||||
|
@ -70,7 +71,7 @@ App::post('/v1/projects')
|
|||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $projectId, string $name, string $teamId, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Database $dbForProject) {
|
||||
->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Database $dbForProject) {
|
||||
|
||||
$team = $dbForConsole->getDocument('teams', $teamId);
|
||||
|
||||
|
@ -102,6 +103,7 @@ App::post('/v1/projects')
|
|||
'name' => $name,
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'region' => $region,
|
||||
'description' => $description,
|
||||
'logo' => $logo,
|
||||
'url' => $url,
|
||||
|
@ -561,10 +563,6 @@ App::delete('/v1/projects/:projectId')
|
|||
->setDocument($project)
|
||||
;
|
||||
|
||||
if (!$dbForConsole->deleteDocument('teams', $project->getAttribute('teamId', null))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project team from DB');
|
||||
}
|
||||
|
||||
if (!$dbForConsole->deleteDocument('projects', $projectId)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove project from DB');
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ App::shutdown()
|
|||
$header = new View(__DIR__ . '/../../views/console/comps/header.phtml');
|
||||
$footer = new View(__DIR__ . '/../../views/console/comps/footer.phtml');
|
||||
|
||||
$header
|
||||
->setParam('regions', Config::getParam('regions', []))
|
||||
;
|
||||
|
||||
$footer
|
||||
->setParam('home', App::getEnv('_APP_HOME', ''))
|
||||
->setParam('version', App::getEnv('_APP_VERSION', 'UNKNOWN'))
|
||||
|
|
|
@ -27,7 +27,6 @@ $http = new Server("0.0.0.0", App::getEnv('PORT', 80));
|
|||
|
||||
$payloadSize = 6 * (1024 * 1024); // 6MB
|
||||
$workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6));
|
||||
|
||||
$http
|
||||
->set([
|
||||
'worker_num' => $workerNumber,
|
||||
|
|
19
app/init.php
19
app/init.php
|
@ -36,14 +36,20 @@ use Appwrite\Network\Validator\Email;
|
|||
use Appwrite\Network\Validator\IP;
|
||||
use Appwrite\Network\Validator\URL;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\SMS\Adapter\Mock;
|
||||
use Appwrite\SMS\Adapter\Msg91;
|
||||
use Appwrite\SMS\Adapter\Telesign;
|
||||
use Appwrite\SMS\Adapter\TextMagic;
|
||||
use Appwrite\SMS\Adapter\Twilio;
|
||||
use Appwrite\SMS\Adapter\Vonage;
|
||||
use Appwrite\Usage\Stats;
|
||||
use Appwrite\Utopia\View;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\ID;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Messaging\Adapters\SMS\Mock;
|
||||
use Utopia\Messaging\Adapters\SMS\Msg91;
|
||||
use Utopia\Messaging\Adapters\SMS\Telesign;
|
||||
use Utopia\Messaging\Adapters\SMS\TextMagic;
|
||||
use Utopia\Messaging\Adapters\SMS\Twilio;
|
||||
use Utopia\Messaging\Adapters\SMS\Vonage;
|
||||
use Utopia\Registry\Registry;
|
||||
use MaxMind\Db\Reader;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Swoole\Database\PDOConfig;
|
||||
|
@ -191,6 +197,7 @@ Config::load('roles', __DIR__ . '/config/roles.php'); // User roles and scopes
|
|||
Config::load('scopes', __DIR__ . '/config/scopes.php'); // User roles and scopes
|
||||
Config::load('services', __DIR__ . '/config/services.php'); // List of services
|
||||
Config::load('variables', __DIR__ . '/config/variables.php'); // List of env variables
|
||||
Config::load('regions', __DIR__ . '/config/regions.php'); // List of available regions
|
||||
Config::load('avatar-browsers', __DIR__ . '/config/avatars/browsers.php');
|
||||
Config::load('avatar-credit-cards', __DIR__ . '/config/avatars/credit-cards.php');
|
||||
Config::load('avatar-flags', __DIR__ . '/config/avatars/flags.php');
|
||||
|
|
|
@ -118,7 +118,8 @@ $logError = function (Throwable $error, string $action = 'syncUsageStats') use (
|
|||
function aggregateTimeseries(UtopiaDatabase $database, InfluxDatabase $influxDB, callable $logError): void
|
||||
{
|
||||
$interval = (int) App::getEnv('_APP_USAGE_TIMESERIES_INTERVAL', '30'); // 30 seconds (by default)
|
||||
$usage = new TimeSeries($database, $influxDB, $logError);
|
||||
$region = App::getEnv('region', 'default');
|
||||
$usage = new TimeSeries($region, $database, $influxDB, $logError);
|
||||
|
||||
Console::loop(function () use ($interval, $usage) {
|
||||
$now = date('d-m-Y H:i:s', time());
|
||||
|
@ -136,8 +137,9 @@ function aggregateTimeseries(UtopiaDatabase $database, InfluxDatabase $influxDB,
|
|||
function aggregateDatabase(UtopiaDatabase $database, callable $logError): void
|
||||
{
|
||||
$interval = (int) App::getEnv('_APP_USAGE_DATABASE_INTERVAL', '900'); // 15 minutes (by default)
|
||||
$usage = new Database($database, $logError);
|
||||
$aggregrator = new Aggregator($database, $logError);
|
||||
$region = App::getEnv('region', 'default');
|
||||
$usage = new Database($region, $database, $logError);
|
||||
$aggregrator = new Aggregator($region, $database, $logError);
|
||||
|
||||
Console::loop(function () use ($interval, $usage, $aggregrator) {
|
||||
$now = date('d-m-Y H:i:s', time());
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
<?php
|
||||
$regions = $this->getParam('regions', []);
|
||||
?>
|
||||
<header class="clear" data-version>
|
||||
<a href="/console" class="logo pull-start">
|
||||
<img src="/images/appwrite.svg" alt="Appwrite Light Logo" class="force-light" loading="lazy" />
|
||||
|
@ -215,7 +218,18 @@
|
|||
name="projectId" />
|
||||
|
||||
<label>Name</label>
|
||||
<input type="text" class="full-width margin-bottom-xl" name="name" required autocomplete="off" maxlength="128" />
|
||||
<input type="text" class="full-width" name="name" required autocomplete="off" maxlength="128" />
|
||||
|
||||
<?php if(count($regions) > 1): ?>
|
||||
<label>Region</label>
|
||||
<select name="region" class="margin-bottom-xl">
|
||||
<?php foreach($regions as $key => $region): ?>
|
||||
<option <?php echo ($region['default'] ?? false) ? 'selected' : '' ?> <?php echo ($region['disabled'] ?? false ) ? 'disabled' : '' ?> value="<?php echo $key ?>"><?php echo $region['name'] ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php else: ?>
|
||||
<input type="hidden" name="region" value="<?php echo array_key_first($regions) ?>" class="margin-bottom-xl" />
|
||||
<?php endif; ?>
|
||||
|
||||
<footer>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\SMS\Adapter\Mock;
|
||||
use Appwrite\SMS\Adapter\Telesign;
|
||||
use Appwrite\SMS\Adapter\TextMagic;
|
||||
use Appwrite\SMS\Adapter\Twilio;
|
||||
use Appwrite\SMS\Adapter\Msg91;
|
||||
use Appwrite\SMS\Adapter\Vonage;
|
||||
use Appwrite\DSN\DSN;
|
||||
use Appwrite\Resque\Worker;
|
||||
use Appwrite\SMS\Adapter;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Messaging\Adapter;
|
||||
use Utopia\Messaging\Adapters\SMS\Mock;
|
||||
use Utopia\Messaging\Adapters\SMS\Msg91;
|
||||
use Utopia\Messaging\Adapters\SMS\Telesign;
|
||||
use Utopia\Messaging\Adapters\SMS\TextMagic;
|
||||
use Utopia\Messaging\Adapters\SMS\Twilio;
|
||||
use Utopia\Messaging\Adapters\SMS\Vonage;
|
||||
use Utopia\Messaging\Messages\SMS;
|
||||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
|
@ -58,11 +59,14 @@ class MessagingV1 extends Worker
|
|||
return;
|
||||
}
|
||||
|
||||
$recipient = $this->args['recipient'];
|
||||
$message = $this->args['message'];
|
||||
$message = new SMS(
|
||||
to: [$this->args['recipient']],
|
||||
content: $this->args['message'],
|
||||
from: $this->from,
|
||||
);
|
||||
|
||||
try {
|
||||
$this->sms->send($this->from, $recipient, $message);
|
||||
$this->sms->send($message);
|
||||
} catch (\Exception $error) {
|
||||
throw new Exception('Error sending message: ' . $error->getMessage(), 500);
|
||||
}
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
"ext-sockets": "*",
|
||||
"appwrite/php-clamav": "1.1.*",
|
||||
"appwrite/php-runtimes": "0.11.*",
|
||||
"utopia-php/framework": "dev-feat-allow-mutations as 0.22.1",
|
||||
"utopia-php/logger": "0.3.*",
|
||||
"utopia-php/abuse": "0.13.*",
|
||||
"utopia-php/analytics": "0.2.*",
|
||||
"utopia-php/audit": "0.14.*",
|
||||
|
@ -52,15 +50,18 @@
|
|||
"utopia-php/cli": "0.13.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.25.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/registry": "0.6.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/domains": "1.1.*",
|
||||
"utopia-php/swoole": "dev-feat-allow-mutations as 0.3.0",
|
||||
"utopia-php/storage": "0.11.*",
|
||||
"utopia-php/websocket": "0.1.0",
|
||||
"utopia-php/framework": "dev-feat-allow-mutations as 0.22.1",
|
||||
"utopia-php/image": "0.5.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.3.*",
|
||||
"utopia-php/messaging": "0.1.*",
|
||||
"utopia-php/orchestration": "0.6.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/storage": "0.11.*",
|
||||
"utopia-php/swoole": "dev-feat-allow-mutations as 0.4.0",
|
||||
"utopia-php/websocket": "0.1.0",
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "6.0.0",
|
||||
"dragonmantank/cron-expression": "3.3.1",
|
||||
|
|
101
composer.lock
generated
101
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": "7313a5d7b3f2e7e2ed8659128c84d5c8",
|
||||
"content-hash": "bdda7382f6174d4fc9f068b0d2bf92a3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -2394,6 +2394,60 @@
|
|||
},
|
||||
"time": "2022-03-18T10:56:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "501272fad666f06bec8f130076862e7981a73f8c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/501272fad666f06bec8f130076862e7981a73f8c",
|
||||
"reference": "501272fad666f06bec8f130076862e7981a73f8c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"php": ">=8.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpmailer/phpmailer": "6.6.*",
|
||||
"phpunit/phpunit": "9.5.*",
|
||||
"squizlabs/php_codesniffer": "^3.6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Messaging\\": "src/Utopia/Messaging"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jake Barnby",
|
||||
"email": "jake@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple, light and advanced PHP messaging library",
|
||||
"keywords": [
|
||||
"library",
|
||||
"messaging",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia",
|
||||
"utopia-php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.1.0"
|
||||
},
|
||||
"time": "2022-09-29T11:22:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/orchestration",
|
||||
"version": "0.6.0",
|
||||
|
@ -2504,16 +2558,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
"version": "0.6.0",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/registry.git",
|
||||
"reference": "9c183312e48c926135085f34ac2e73dadb83e0c8"
|
||||
"reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/registry/zipball/9c183312e48c926135085f34ac2e73dadb83e0c8",
|
||||
"reference": "9c183312e48c926135085f34ac2e73dadb83e0c8",
|
||||
"url": "https://api.github.com/repos/utopia-php/registry/zipball/bedc4ed54527b2803e6dfdccc39449f98522b70d",
|
||||
"reference": "bedc4ed54527b2803e6dfdccc39449f98522b70d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2550,9 +2604,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/registry/issues",
|
||||
"source": "https://github.com/utopia-php/registry/tree/0.6.0"
|
||||
"source": "https://github.com/utopia-php/registry/tree/0.5.0"
|
||||
},
|
||||
"time": "2022-07-17T15:26:57+00:00"
|
||||
"time": "2021-03-10T10:45:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
|
@ -2910,12 +2964,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "42a6ec3c565f44eb5353009f754fcb76ff8ecd96"
|
||||
"reference": "44baaa67b1a907dd0140b2a8bd6b950ae2d1c965"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/42a6ec3c565f44eb5353009f754fcb76ff8ecd96",
|
||||
"reference": "42a6ec3c565f44eb5353009f754fcb76ff8ecd96",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/44baaa67b1a907dd0140b2a8bd6b950ae2d1c965",
|
||||
"reference": "44baaa67b1a907dd0140b2a8bd6b950ae2d1c965",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2952,7 +3006,7 @@
|
|||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/feat-graphql-method-type"
|
||||
},
|
||||
"time": "2022-10-13T00:32:14+00:00"
|
||||
"time": "2022-10-14T02:36:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
|
@ -3485,25 +3539,30 @@
|
|||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "1.6.1",
|
||||
"version": "1.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "77a32518733312af16a44300404e945338981de3"
|
||||
"reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3",
|
||||
"reference": "77a32518733312af16a44300404e945338981de3",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
|
||||
"reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpdocumentor/reflection-common": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-tokenizer": "*",
|
||||
"psalm/phar": "^4.8"
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/rector": "^0.13.9",
|
||||
"vimeo/psalm": "^4.25"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -3529,9 +3588,9 @@
|
|||
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1"
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2"
|
||||
},
|
||||
"time": "2022-03-15T21:29:03+00:00"
|
||||
"time": "2022-10-14T12:47:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
|
@ -5440,8 +5499,8 @@
|
|||
{
|
||||
"package": "utopia-php/swoole",
|
||||
"version": "dev-feat-allow-mutations",
|
||||
"alias": "0.3.0",
|
||||
"alias_normalized": "0.3.0.0"
|
||||
"alias": "0.4.0",
|
||||
"alias_normalized": "0.4.0.0"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
|
|
10
public/dist/scripts/app-all.js
vendored
10
public/dist/scripts/app-all.js
vendored
|
@ -519,12 +519,14 @@ class Projects extends Service{constructor(client){super(client);}
|
|||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
create(projectId,name,teamId,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
create(projectId,name,teamId,region,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __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 teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof region==='undefined'){throw new AppwriteException('Missing required parameter: "region"');}
|
||||
let path='/projects';let payload={};if(typeof projectId!=='undefined'){payload['projectId']=projectId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof teamId!=='undefined'){payload['teamId']=teamId;}
|
||||
if(typeof region!=='undefined'){payload['region']=region;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
if(typeof logo!=='undefined'){payload['logo']=logo;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
|
@ -537,9 +539,11 @@ if(typeof legalTaxId!=='undefined'){payload['legalTaxId']=legalTaxId;}
|
|||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
get(projectId){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
update(projectId,name,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
update(projectId,name,region,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __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 region==='undefined'){throw new AppwriteException('Missing required parameter: "region"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof region!=='undefined'){payload['region']=region;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
if(typeof logo!=='undefined'){payload['logo']=logo;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
|
@ -4145,7 +4149,7 @@ element.classList.add('scroll-to-bottom')}
|
|||
else{element.classList.remove('scroll-to-bottom')
|
||||
element.classList.add('scroll-to-top')}
|
||||
position=direction;let current=Math.ceil(direction/window.innerHeight);element.setAttribute('data-views-total',Math.ceil(element.scrollHeight/window.innerHeight));element.setAttribute('data-views-current',current);if(element.scrollHeight<=(direction+element.offsetHeight+300)&&direction>0){element.classList.add('scroll-end')}
|
||||
else{element.classList.remove('scroll-end')}};window.addEventListener('scroll',check,false);window.addEventListener('resize',check,false);check();}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-setup",controller:function(element,console,form,alerts,router){element.addEventListener("submit",function(event){event.preventDefault();let loaderId=alerts.add({text:'Creating new project...',class:""},0);let formData=form.toJson(element);formData["name"]=formData["name"]||(element.dataset["defaultName"]||"");console.teams.create('unique()',formData["name"]||"").then(function(data){let team=data["$id"];formData=JSON.parse(JSON.stringify(formData).replace(new RegExp("{{teamId}}","g"),team));console.projects.create(formData["projectId"],formData["name"],team).then(function(project){alerts.remove(loaderId);window.location.href="/console/home?project="+project["$id"];},function(){throw new Error("Failed to setup project");});},function(){throw new Error("Setup failed creating project team");});});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-switch",controller:function(element,router,document){let check=function(c){if(!element.value){return;}
|
||||
else{element.classList.remove('scroll-end')}};window.addEventListener('scroll',check,false);window.addEventListener('resize',check,false);check();}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-setup",controller:function(element,console,form,alerts,router){element.addEventListener("submit",function(event){event.preventDefault();let loaderId=alerts.add({text:'Creating new project...',class:""},0);let formData=form.toJson(element);formData["name"]=formData["name"]||(element.dataset["defaultName"]||"");console.teams.create('unique()',formData["name"]||"").then(function(data){let team=data["$id"];formData=JSON.parse(JSON.stringify(formData).replace(new RegExp("{{teamId}}","g"),team));console.projects.create(formData["projectId"],formData["name"],team,formData['region']).then(function(project){alerts.remove(loaderId);window.location.href="/console/home?project="+project["$id"];},function(){throw new Error("Failed to setup project");});},function(){throw new Error("Setup failed creating project team");});});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-switch",controller:function(element,router,document){let check=function(c){if(!element.value){return;}
|
||||
if(element.value===router.params.project){return;}
|
||||
return router.change("/console/home?project="+element.value);};element.addEventListener("change",function(){check();});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-general-theme",controller:function(element,router,document){let toggle=function(c){if(document.body.classList.contains('theme-light')){document.body.classList.remove('theme-light');document.body.classList.add('theme-dark');window.localStorage.setItem('user-theme','theme-dark')}
|
||||
else{document.body.classList.remove('theme-dark');document.body.classList.add('theme-light');window.localStorage.setItem('user-theme','theme-light')}};element.addEventListener("click",function(){toggle();});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-version",controller:function(alerts,env,cookie){let cookieName="version-update-"+env.VERSION.replace(/\./g,"_");if(!cookie.get(cookieName)){var xhr=new XMLHttpRequest();xhr.open('GET','https://appwrite.io/version',true);xhr.onload=function(){if(this.readyState==4&&this.status==200){let data=JSON.parse(this.responseText);let text='Appwrite version '+data.version+' is available, check the';if(isNewerVersion(env.VERSION,data.version)){alerts.add({text:text,class:"success",link:"https://github.com/appwrite/appwrite/releases",label:'release notes',callback:function(){cookie.set(cookieName,"true",365*10);}},0);}}};xhr.send(null);function isNewerVersion(oldVer,newVer){const oldParts=oldVer.split('.')
|
||||
|
|
8
public/dist/scripts/app-dep.js
vendored
8
public/dist/scripts/app-dep.js
vendored
|
@ -519,12 +519,14 @@ class Projects extends Service{constructor(client){super(client);}
|
|||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
create(projectId,name,teamId,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
create(projectId,name,teamId,region,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __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 teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
if(typeof region==='undefined'){throw new AppwriteException('Missing required parameter: "region"');}
|
||||
let path='/projects';let payload={};if(typeof projectId!=='undefined'){payload['projectId']=projectId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof teamId!=='undefined'){payload['teamId']=teamId;}
|
||||
if(typeof region!=='undefined'){payload['region']=region;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
if(typeof logo!=='undefined'){payload['logo']=logo;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
|
@ -537,9 +539,11 @@ if(typeof legalTaxId!=='undefined'){payload['legalTaxId']=legalTaxId;}
|
|||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
get(projectId){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
update(projectId,name,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __awaiter(this,void 0,void 0,function*(){if(typeof projectId==='undefined'){throw new AppwriteException('Missing required parameter: "projectId"');}
|
||||
update(projectId,name,region,description,logo,url,legalName,legalCountry,legalState,legalCity,legalAddress,legalTaxId){return __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 region==='undefined'){throw new AppwriteException('Missing required parameter: "region"');}
|
||||
let path='/projects/{projectId}'.replace('{projectId}',projectId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof region!=='undefined'){payload['region']=region;}
|
||||
if(typeof description!=='undefined'){payload['description']=description;}
|
||||
if(typeof logo!=='undefined'){payload['logo']=logo;}
|
||||
if(typeof url!=='undefined'){payload['url']=url;}
|
||||
|
|
2
public/dist/scripts/app.js
vendored
2
public/dist/scripts/app.js
vendored
|
@ -739,7 +739,7 @@ element.classList.add('scroll-to-bottom')}
|
|||
else{element.classList.remove('scroll-to-bottom')
|
||||
element.classList.add('scroll-to-top')}
|
||||
position=direction;let current=Math.ceil(direction/window.innerHeight);element.setAttribute('data-views-total',Math.ceil(element.scrollHeight/window.innerHeight));element.setAttribute('data-views-current',current);if(element.scrollHeight<=(direction+element.offsetHeight+300)&&direction>0){element.classList.add('scroll-end')}
|
||||
else{element.classList.remove('scroll-end')}};window.addEventListener('scroll',check,false);window.addEventListener('resize',check,false);check();}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-setup",controller:function(element,console,form,alerts,router){element.addEventListener("submit",function(event){event.preventDefault();let loaderId=alerts.add({text:'Creating new project...',class:""},0);let formData=form.toJson(element);formData["name"]=formData["name"]||(element.dataset["defaultName"]||"");console.teams.create('unique()',formData["name"]||"").then(function(data){let team=data["$id"];formData=JSON.parse(JSON.stringify(formData).replace(new RegExp("{{teamId}}","g"),team));console.projects.create(formData["projectId"],formData["name"],team).then(function(project){alerts.remove(loaderId);window.location.href="/console/home?project="+project["$id"];},function(){throw new Error("Failed to setup project");});},function(){throw new Error("Setup failed creating project team");});});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-switch",controller:function(element,router,document){let check=function(c){if(!element.value){return;}
|
||||
else{element.classList.remove('scroll-end')}};window.addEventListener('scroll',check,false);window.addEventListener('resize',check,false);check();}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-setup",controller:function(element,console,form,alerts,router){element.addEventListener("submit",function(event){event.preventDefault();let loaderId=alerts.add({text:'Creating new project...',class:""},0);let formData=form.toJson(element);formData["name"]=formData["name"]||(element.dataset["defaultName"]||"");console.teams.create('unique()',formData["name"]||"").then(function(data){let team=data["$id"];formData=JSON.parse(JSON.stringify(formData).replace(new RegExp("{{teamId}}","g"),team));console.projects.create(formData["projectId"],formData["name"],team,formData['region']).then(function(project){alerts.remove(loaderId);window.location.href="/console/home?project="+project["$id"];},function(){throw new Error("Failed to setup project");});},function(){throw new Error("Setup failed creating project team");});});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-switch",controller:function(element,router,document){let check=function(c){if(!element.value){return;}
|
||||
if(element.value===router.params.project){return;}
|
||||
return router.change("/console/home?project="+element.value);};element.addEventListener("change",function(){check();});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-general-theme",controller:function(element,router,document){let toggle=function(c){if(document.body.classList.contains('theme-light')){document.body.classList.remove('theme-light');document.body.classList.add('theme-dark');window.localStorage.setItem('user-theme','theme-dark')}
|
||||
else{document.body.classList.remove('theme-dark');document.body.classList.add('theme-light');window.localStorage.setItem('user-theme','theme-light')}};element.addEventListener("click",function(){toggle();});}});})(window);(function(window){window.ls.container.get("view").add({selector:"data-version",controller:function(alerts,env,cookie){let cookieName="version-update-"+env.VERSION.replace(/\./g,"_");if(!cookie.get(cookieName)){var xhr=new XMLHttpRequest();xhr.open('GET','https://appwrite.io/version',true);xhr.onload=function(){if(this.readyState==4&&this.status==200){let data=JSON.parse(this.responseText);let text='Appwrite version '+data.version+' is available, check the';if(isNewerVersion(env.VERSION,data.version)){alerts.add({text:text,class:"success",link:"https://github.com/appwrite/appwrite/releases",label:'release notes',callback:function(){cookie.set(cookieName,"true",365*10);}},0);}}};xhr.send(null);function isNewerVersion(oldVer,newVer){const oldParts=oldVer.split('.')
|
||||
|
|
|
@ -4084,6 +4084,7 @@
|
|||
* @param {string} projectId
|
||||
* @param {string} name
|
||||
* @param {string} teamId
|
||||
* @param {string} region
|
||||
* @param {string} description
|
||||
* @param {string} logo
|
||||
* @param {string} url
|
||||
|
@ -4096,7 +4097,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
create(projectId, name, teamId, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId) {
|
||||
create(projectId, name, teamId, region, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof projectId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "projectId"');
|
||||
|
@ -4107,6 +4108,9 @@
|
|||
if (typeof teamId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "teamId"');
|
||||
}
|
||||
if (typeof region === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "region"');
|
||||
}
|
||||
let path = '/projects';
|
||||
let payload = {};
|
||||
if (typeof projectId !== 'undefined') {
|
||||
|
@ -4118,6 +4122,9 @@
|
|||
if (typeof teamId !== 'undefined') {
|
||||
payload['teamId'] = teamId;
|
||||
}
|
||||
if (typeof region !== 'undefined') {
|
||||
payload['region'] = region;
|
||||
}
|
||||
if (typeof description !== 'undefined') {
|
||||
payload['description'] = description;
|
||||
}
|
||||
|
@ -4178,6 +4185,7 @@
|
|||
*
|
||||
* @param {string} projectId
|
||||
* @param {string} name
|
||||
* @param {string} region
|
||||
* @param {string} description
|
||||
* @param {string} logo
|
||||
* @param {string} url
|
||||
|
@ -4190,7 +4198,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
update(projectId, name, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId) {
|
||||
update(projectId, name, region, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof projectId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "projectId"');
|
||||
|
@ -4198,11 +4206,17 @@
|
|||
if (typeof name === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "name"');
|
||||
}
|
||||
if (typeof region === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "region"');
|
||||
}
|
||||
let path = '/projects/{projectId}'.replace('{projectId}', projectId);
|
||||
let payload = {};
|
||||
if (typeof name !== 'undefined') {
|
||||
payload['name'] = name;
|
||||
}
|
||||
if (typeof region !== 'undefined') {
|
||||
payload['region'] = region;
|
||||
}
|
||||
if (typeof description !== 'undefined') {
|
||||
payload['description'] = description;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
)
|
||||
); //convert to JSON string
|
||||
|
||||
console.projects.create(formData["projectId"], formData["name"], team).then(
|
||||
console.projects.create(formData["projectId"], formData["name"], team, formData['region']).then(
|
||||
function(project) {
|
||||
alerts.remove(loaderId);
|
||||
//router.change("/console/home?project=" + project["$id"]);
|
||||
|
|
|
@ -49,11 +49,17 @@ class URL extends Validator
|
|||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (\filter_var($value, FILTER_VALIDATE_URL) === false) {
|
||||
$sanitizedURL = '';
|
||||
|
||||
foreach (str_split($value) as $character) {
|
||||
$sanitizedURL .= (ord($character) > 127) ? rawurlencode($character) : $character;
|
||||
}
|
||||
|
||||
if (\filter_var($sanitizedURL, FILTER_VALIDATE_URL) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($this->allowedSchemes) && !\in_array(\parse_url($value, PHP_URL_SCHEME), $this->allowedSchemes)) {
|
||||
if (!empty($this->allowedSchemes) && !\in_array(\parse_url($sanitizedURL, PHP_URL_SCHEME), $this->allowedSchemes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS;
|
||||
|
||||
abstract class Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $user;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $secret;
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*/
|
||||
public function __construct(string $user, string $secret)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Message to phone.
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
abstract public function send(string $from, string $to, string $message): void;
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array $headers
|
||||
* @param string $payload
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function request(string $method, string $url, array $headers = [], ?string $payload = null, ?string $userpwd = null): string
|
||||
{
|
||||
$ch = \curl_init($url);
|
||||
|
||||
\curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
\curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
\curl_setopt($ch, CURLOPT_USERAGENT, 'Appwrite Phone Authentication');
|
||||
|
||||
if (!is_null($payload)) {
|
||||
\curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
}
|
||||
|
||||
if (!is_null($userpwd)) {
|
||||
\curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
|
||||
}
|
||||
|
||||
$headers[] = 'Content-length: ' . \strlen($payload);
|
||||
|
||||
\curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
$response = (string) \curl_exec($ch);
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
\curl_close($ch);
|
||||
|
||||
if ($code >= 400) {
|
||||
throw new \Exception($response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Mock adapter used to E2E test worker
|
||||
class Mock extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'http://request-catcher:5000/mock-sms';
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: $this->endpoint,
|
||||
payload: \json_encode([
|
||||
'message' => $message,
|
||||
'from' => $from,
|
||||
'to' => $to
|
||||
]),
|
||||
headers: [
|
||||
"content-type: application/json",
|
||||
"x-username: {$this->user}",
|
||||
"x-key: {$this->secret}",
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Reference Material
|
||||
// https://docs.msg91.com/p/tf9GTextN/e/Irz7-x1PK/MSG91
|
||||
|
||||
class Msg91 extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'https://api.msg91.com/api/v5/flow/';
|
||||
|
||||
/**
|
||||
* For Flow based sending SMS sender ID should not be set in flow
|
||||
* In environment _APP_SMS_PROVIDER format is 'sms://[senderID]:[authKey]@msg91'.
|
||||
* _APP_SMS_FROM value is flow ID created in Msg91
|
||||
* Eg. _APP_SMS_PROVIDER = sms://DINESH:5e1e93cad6fc054d8e759a5b@msg91
|
||||
* _APP_SMS_FROM = 3968636f704b303135323339
|
||||
* @param string $from-> utilized from for flow id
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$to = ltrim($to, '+');
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: $this->endpoint,
|
||||
payload: json_encode([
|
||||
'sender' => $this->user,
|
||||
'otp' => $message,
|
||||
'flow_id' => $from,
|
||||
'mobiles' => $to
|
||||
]),
|
||||
headers: [
|
||||
"content-type: application/JSON",
|
||||
"authkey: {$this->secret}",
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Reference Material
|
||||
// https://developer.telesign.com/enterprise/docs/sms-api-send-an-sms
|
||||
|
||||
class Telesign extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'https://rest-api.telesign.com/v1/messaging';
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
* @throws \Appwrite\Extend\Exception
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$to = ltrim($to, '+');
|
||||
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: $this->endpoint,
|
||||
payload: \http_build_query([
|
||||
'message' => $message,
|
||||
'message_type' => 'otp',
|
||||
'phone_number' => $to
|
||||
]),
|
||||
userpwd: "{$this->user}:{$this->secret}"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Reference Material
|
||||
// https://www.textmagic.com/docs/api/start/
|
||||
|
||||
class TextMagic extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'https://rest.textmagic.com/api/v2';
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$to = ltrim($to, '+');
|
||||
$from = ltrim($from, '+');
|
||||
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: $this->endpoint . '/messages',
|
||||
payload: \http_build_query([
|
||||
'text' => $message,
|
||||
'from' => $from,
|
||||
'phones' => $to
|
||||
]),
|
||||
headers: [
|
||||
"X-TM-Username: {$this->user}",
|
||||
"X-TM-Key: {$this->secret}",
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Reference Material
|
||||
// https://www.twilio.com/docs/sms/api
|
||||
|
||||
class Twilio extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'https://api.twilio.com/2010-04-01';
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: "{$this->endpoint}/Accounts/{$this->user}/Messages.json",
|
||||
payload: \http_build_query([
|
||||
'Body' => $message,
|
||||
'From' => $from,
|
||||
'To' => $to
|
||||
]),
|
||||
userpwd: "{$this->user}:{$this->secret}"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\SMS\Adapter;
|
||||
|
||||
use Appwrite\SMS\Adapter;
|
||||
|
||||
// Reference Material
|
||||
// https://developer.vonage.com/api/sms
|
||||
|
||||
class Vonage extends Adapter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $endpoint = 'https://rest.nexmo.com/sms/json';
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
public function send(string $from, string $to, string $message): void
|
||||
{
|
||||
$to = ltrim($to, '+');
|
||||
$headers = ['Content-Type: application/x-www-form-urlencoded'];
|
||||
|
||||
$this->request(
|
||||
method: 'POST',
|
||||
url: $this->endpoint,
|
||||
headers: $headers,
|
||||
payload: \http_build_query([
|
||||
'text' => $message,
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
'api_key' => $this->user,
|
||||
'api_secret' => $this->secret
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,5 +4,12 @@ namespace Appwrite\Usage;
|
|||
|
||||
abstract class Calculator
|
||||
{
|
||||
protected string $region;
|
||||
|
||||
public function __construct(string $region)
|
||||
{
|
||||
$this->region = $region;
|
||||
}
|
||||
|
||||
abstract public function collect(): void;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Appwrite\Usage\Calculators;
|
||||
|
||||
use Exception;
|
||||
use Utopia\App;
|
||||
use Appwrite\Usage\Calculator;
|
||||
use DateTime;
|
||||
use Utopia\Database\Database as UtopiaDatabase;
|
||||
|
@ -24,8 +25,9 @@ class Database extends Calculator
|
|||
],
|
||||
];
|
||||
|
||||
public function __construct(UtopiaDatabase $database, callable $errorHandler = null)
|
||||
public function __construct(string $region, UtopiaDatabase $database, callable $errorHandler = null)
|
||||
{
|
||||
parent::__construct($region);
|
||||
$this->database = $database;
|
||||
$this->errorHandler = $errorHandler;
|
||||
}
|
||||
|
@ -95,6 +97,7 @@ class Database extends Calculator
|
|||
'time' => $time,
|
||||
'metric' => $metric,
|
||||
'value' => $value,
|
||||
'region' => $this->region,
|
||||
'type' => 2, // these are cumulative metrics
|
||||
]));
|
||||
} else {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Appwrite\Usage\Calculators;
|
||||
|
||||
use Utopia\App;
|
||||
use Appwrite\Usage\Calculator;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
|
@ -278,8 +279,9 @@ class TimeSeries extends Calculator
|
|||
'startTime' => '-24 hours',
|
||||
];
|
||||
|
||||
public function __construct(Database $database, InfluxDatabase $influxDB, callable $errorHandler = null)
|
||||
public function __construct(string $region, Database $database, InfluxDatabase $influxDB, callable $errorHandler = null)
|
||||
{
|
||||
parent::__construct($region);
|
||||
$this->database = $database;
|
||||
$this->influxDB = $influxDB;
|
||||
$this->errorHandler = $errorHandler;
|
||||
|
@ -315,6 +317,7 @@ class TimeSeries extends Calculator
|
|||
'metric' => $metric,
|
||||
'value' => $value,
|
||||
'type' => $type,
|
||||
'region' => $this->region,
|
||||
]));
|
||||
} else {
|
||||
$this->database->updateDocument(
|
||||
|
|
|
@ -7,7 +7,8 @@ use Appwrite\Utopia\Database\Validator\Queries\Base;
|
|||
class Projects extends Base
|
||||
{
|
||||
public const ALLOWED_ATTRIBUTES = [
|
||||
'name'
|
||||
'name',
|
||||
'teamId'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,45 +17,45 @@ class UsageBuckets extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('filesCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of files in this bucket.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesStorage', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total storage of files in this bucket.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,38 +17,38 @@ class UsageCollection extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('documentsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of documents.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,73 +17,73 @@ class UsageDatabase extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('documentsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of documents.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of collections.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections delete.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,108 +17,108 @@ class UsageDatabases extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('databasesCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of documents.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of documents.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of collections.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('databasesCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('databasesRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('databasesUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('databasesDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of collections.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documentsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for documents deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collectionsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for collections delete.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,59 +17,59 @@ class UsageFunction extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('executionsTotal', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of function executions.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsFailure', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution failures.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsSuccess', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution successes.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsTime', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution duration.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsTotal', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of function builds.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsFailure', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build failures.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsSuccess', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build successes.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsTime', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build duration.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,59 +17,59 @@ class UsageFunctions extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('executionsTotal', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of function executions.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsFailure', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution failures.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsSuccess', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution successes.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executionsTime', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function execution duration.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsTotal', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of function builds.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsFailure', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build failures.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsSuccess', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build successes.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('buildsTime', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function build duration.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,52 +17,52 @@ class UsageProject extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('requests', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of requests.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('network', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for consumed bandwidth.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('executions', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for function executions.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('documents', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of documents.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('collections', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of collections.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('users', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for number of users.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('storage', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for the occupied storage size (in bytes).',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,80 +17,80 @@ class UsageStorage extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('storage', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for the occupied storage size (in bytes).',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of files.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('bucketsCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of buckets.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('bucketsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for buckets created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('bucketsRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for buckets read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('bucketsUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for buckets updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('bucketsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for buckets deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('filesDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for files deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -17,59 +17,59 @@ class UsageUsers extends Model
|
|||
'example' => '30d',
|
||||
])
|
||||
->addRule('usersCount', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for total number of users.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('usersCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for users created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('usersRead', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for users read.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('usersUpdate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for users updated.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('usersDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for users deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('sessionsCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for sessions created.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('sessionsProviderCreate', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for sessions created for a provider ( email, anonymous or oauth2 ).',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('sessionsDelete', [
|
||||
'type' => Response::MODEL_METRIC_LIST,
|
||||
'type' => Response::MODEL_METRIC,
|
||||
'description' => 'Aggregated stats for sessions deleted.',
|
||||
'default' => [],
|
||||
'example' => new \stdClass(),
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
|
|
|
@ -42,6 +42,7 @@ trait ProjectCustom
|
|||
'x-appwrite-project' => 'console',
|
||||
], [
|
||||
'projectId' => ID::unique(),
|
||||
'region' => 'default',
|
||||
'name' => 'Demo Project',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'description' => 'Demo Project Description',
|
||||
|
|
|
@ -716,12 +716,12 @@ class AccountCustomClientTest extends Scope
|
|||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
\sleep(2);
|
||||
\sleep(5);
|
||||
|
||||
$smsRequest = $this->getLastRequest();
|
||||
|
||||
$this->assertEquals('http://request-catcher:5000/mock-sms', $smsRequest['url']);
|
||||
$this->assertEquals('Appwrite Phone Authentication', $smsRequest['headers']['User-Agent']);
|
||||
$this->assertEquals('Appwrite Mock Message Sender', $smsRequest['headers']['User-Agent']);
|
||||
$this->assertEquals('username', $smsRequest['headers']['X-Username']);
|
||||
$this->assertEquals('password', $smsRequest['headers']['X-Key']);
|
||||
$this->assertEquals('POST', $smsRequest['method']);
|
||||
|
|
|
@ -42,6 +42,7 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => 'default',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -64,6 +65,7 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'projectId' => ID::unique(),
|
||||
'name' => '',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
@ -74,6 +76,7 @@ class ProjectsConsoleClientTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
@ -153,6 +156,7 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test 2',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
@ -163,6 +167,18 @@ class ProjectsConsoleClientTest extends Scope
|
|||
$this->assertArrayHasKey('webhooks', $response['body']);
|
||||
$this->assertArrayHasKey('keys', $response['body']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("teamId", "' . $team['body']['$id'] . '")' ],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertCount(1, $response['body']['projects']);
|
||||
$this->assertEquals($team['body']['$id'], $response['body']['projects'][0]['teamId']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -688,6 +704,7 @@ class ProjectsConsoleClientTest extends Scope
|
|||
'projectId' => ID::unique(),
|
||||
'name' => 'Project Test',
|
||||
'teamId' => $team['body']['$id'],
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $project['headers']['status-code']);
|
||||
|
@ -2316,4 +2333,83 @@ class ProjectsConsoleClientTest extends Scope
|
|||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function testDeleteProject(): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
// Create a team and a project
|
||||
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'teamId' => ID::unique(),
|
||||
'name' => 'Amating Team',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $team['headers']['status-code']);
|
||||
$this->assertEquals('Amating Team', $team['body']['name']);
|
||||
$this->assertNotEmpty($team['body']['$id']);
|
||||
|
||||
$teamId = $team['body']['$id'];
|
||||
|
||||
$project = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
'teamId' => $teamId,
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $project['headers']['status-code']);
|
||||
$this->assertEquals('Amazing Project', $project['body']['name']);
|
||||
$this->assertEquals($teamId, $project['body']['teamId']);
|
||||
$this->assertNotEmpty($project['body']['$id']);
|
||||
|
||||
$projectId = $project['body']['$id'];
|
||||
|
||||
// Ensure I can get both team and project
|
||||
$team = $this->client->call(Client::METHOD_GET, '/teams/' . $teamId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $team['headers']['status-code']);
|
||||
|
||||
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $project['headers']['status-code']);
|
||||
|
||||
// Delete team
|
||||
$team = $this->client->call(Client::METHOD_DELETE, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'password' => 'password'
|
||||
]);
|
||||
|
||||
$this->assertEquals(204, $team['headers']['status-code']);
|
||||
|
||||
// Ensure I can get team but not a project
|
||||
$team = $this->client->call(Client::METHOD_GET, '/teams/' . $teamId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $team['headers']['status-code']);
|
||||
|
||||
$project = $this->client->call(Client::METHOD_GET, '/projects/' . $projectId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(404, $project['headers']['status-code']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ class URLTest extends TestCase
|
|||
$this->assertEquals(false, $this->url->isValid('htt@s://example.com'));
|
||||
$this->assertEquals(true, $this->url->isValid('http://www.example.com/foo%2\u00c2\u00a9zbar'));
|
||||
$this->assertEquals(true, $this->url->isValid('http://www.example.com/?q=%3Casdf%3E'));
|
||||
$this->assertEquals(true, $this->url->isValid('https://example.com/foo%2\u00c2\u00ä9zbär'));
|
||||
}
|
||||
|
||||
public function testIsValidAllowedSchemes(): void
|
||||
|
|
Loading…
Reference in a new issue