1
0
Fork 0
mirror of synced 2024-05-20 12:42:39 +12:00

Merge branch 'feat-database-indexing' into feat-usage-daemon

This commit is contained in:
Damodar Lohani 2021-08-24 15:04:07 +05:45
commit c81ee72c7e
59 changed files with 1220 additions and 659 deletions

View file

@ -1,8 +1,8 @@
dist: xenial
dist: focal
arch:
- amd64
- arm64
- arm64-graviton2
os: linux
@ -30,7 +30,7 @@ before_install:
- echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
install:
- docker-compose up -d
- docker-compose up -d --build
- sleep 10
script:
@ -43,6 +43,9 @@ script:
- docker-compose exec appwrite test --debug
- docker-compose logs appwrite
after_failure:
- docker-compose logs appwrite
deploy:
- provider: script
edge: true

View file

@ -6,6 +6,12 @@
- Grouped oAuth related attributes in project collection. Introduced new attribute `providers` and removed all attributes related to OAuth2 providers. All OAuth2 attributes are grouped under `providers`
- Project model changed, `userAuth<AuthMethod>` => `auth<AuthMethod>` example `userAuthEmailPassword` => `authEmailPassword`, also `userOauth2<Provider>...` => `provider<Provider>...` example `userOauth2GithubAppid` => `providerGithubAppid`
# Version 0.9.4
## Security
- Fixed security vulnerability that exposes project ID's from other admin users (#1453)
# Version 0.9.3
## Bugs

View file

@ -19,8 +19,8 @@ ENV DEBUG=$DEBUG
ENV PHP_REDIS_VERSION=5.3.4 \
PHP_MONGODB_VERSION=1.9.1 \
PHP_SWOOLE_VERSION=v4.6.7 \
PHP_IMAGICK_VERSION=3.5.0 \
PHP_SWOOLE_VERSION=v4.7.0 \
PHP_IMAGICK_VERSION=3.5.1 \
PHP_YAML_VERSION=2.2.1 \
PHP_MAXMINDDB_VERSION=v1.10.1

View file

@ -57,7 +57,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:0.9.3
appwrite/appwrite:0.9.4
```
### Windows
@ -69,7 +69,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:0.9.3
appwrite/appwrite:0.9.4
```
#### PowerShell
@ -79,7 +79,7 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
appwrite/appwrite:0.9.3
appwrite/appwrite:0.9.4
```
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes.

View file

@ -7,6 +7,331 @@ $providers = Config::getParam('providers', []);
$auth = Config::getParam('auth', []);
$collections = [
'collections' => [
'$collection' => Database::METADATA,
'$id' => 'collections',
'name' => 'Collections',
'attributes' => [
[
'$id' => 'name',
'type' => Database::VAR_STRING,
'size' => 256,
'required' => true,
'signed' => true,
'array' => false,
'filters' => [],
],
[
'$id' => 'dateCreated',
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'dateUpdated',
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'permission',
'type' => Database::VAR_STRING,
'size' => 64,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'attributes',
'type' => Database::VAR_STRING,
'size' => 1000000,
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['subQueryAttributes'],
],
[
'$id' => 'indexes',
'type' => Database::VAR_STRING,
'size' => 1000000,
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['subQueryIndexes'],
],
[
'$id' => 'search',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
],
'indexes' => [
[
'$id' => '_fulltext_search',
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [1024],
'orders' => [Database::ORDER_ASC],
],
],
],
'attributes' => [
'$collection' => Database::METADATA,
'$id' => 'attributes',
'name' => 'Attributes',
'attributes' => [
[
'$id' => 'collectionId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'key',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'type',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 256,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'status',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'size',
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'required',
'type' => Database::VAR_BOOLEAN,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'default',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'signed',
'type' => Database::VAR_BOOLEAN,
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'array',
'type' => Database::VAR_BOOLEAN,
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'format',
'type' => Database::VAR_STRING,
'size' => 64,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'formatOptions',
'type' => Database::VAR_STRING,
'size' => 16384,
'signed' => true,
'required' => false,
'default' => new stdClass,
'array' => false,
'filters' => ['json'],
],
[
'$id' => 'filters',
'type' => Database::VAR_STRING,
'size' => 64,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
],
'indexes' => [
[
'$id' => '_key_collection',
'type' => Database::INDEX_KEY,
'attributes' => ['collectionId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
],
],
'indexes' => [
'$collection' => Database::METADATA,
'$id' => 'indexes',
'name' => 'Indexes',
'attributes' => [
[
'$id' => 'collectionId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'key',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'type',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'status',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => 'attributes',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
[
'$id' => 'lengths',
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
[
'$id' => 'orders',
'type' => Database::VAR_STRING,
'format' => '',
'size' => 4,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
],
'indexes' => [
[
'$id' => '_key_collection',
'type' => Database::INDEX_KEY,
'attributes' => ['collectionId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
],
],
'projects' => [
'$collection' => Database::METADATA,
'$id' => 'projects',

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,5 @@
<?php
use Appwrite\Utopia\Response;
use Appwrite\Database\Validator\CustomId;
use Utopia\App;
use Utopia\Exception;
use Utopia\Audit\Audit;
@ -25,29 +23,33 @@ use Utopia\Database\Validator\UID;
use Utopia\Database\Exception\Authorization as AuthorizationException;
use Utopia\Database\Exception\Duplicate as DuplicateException;
use Utopia\Database\Exception\Structure as StructureException;
use Appwrite\Utopia\Response;
use Appwrite\Database\Validator\CustomId;
use DeviceDetector\DeviceDetector;
$attributesCallback = function ($attribute, $response, $dbForExternal, $database, $audits, $usage) {
/** @var Utopia\Database\Document $document*/
$attributesCallback = function ($collectionId, $attribute, $response, $dbForInternal, $database, $audits, $usage) {
/** @var Utopia\Database\Document $attribute*/
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collectionId = $attribute->getCollection();
$attributeId = $attribute->getId();
$type = $attribute->getAttribute('type', '');
$size = $attribute->getAttribute('size', 0);
$required = $attribute->getAttribute('required', true);
$default = $attribute->getAttribute('default', null);
$min = $attribute->getAttribute('min', null);
$max = $attribute->getAttribute('max', null);
$signed = $attribute->getAttribute('signed', true); // integers are signed by default
$array = $attribute->getAttribute('array', false);
$format = $attribute->getAttribute('format', null);
$format = $attribute->getAttribute('format', '');
$formatOptions = $attribute->getAttribute('formatOptions', []);
$filters = $attribute->getAttribute('filters', []); // filters are hidden from the endpoint
$default = $attribute->getAttribute('default', null);
$default = (empty($default)) ? null : (int)$default;
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -62,54 +64,37 @@ $attributesCallback = function ($attribute, $response, $dbForExternal, $database
}
}
if (!\is_null($format)) {
$name = \json_decode($format, true)['name'];
if (!Structure::hasFormat($name, $type)) {
throw new Exception("Format {$name} not available for {$type} attributes.", 400);
if (!empty($format)) {
if (!Structure::hasFormat($format, $type)) {
throw new Exception("Format {$format} not available for {$type} attributes.", 400);
}
}
if (!is_null($min) || !is_null($max)) { // Add range validator if either $min or $max is provided
switch ($type) {
case Database::VAR_INTEGER:
$min = (is_null($min)) ? -INF : \intval($min);
$max = (is_null($max)) ? INF : \intval($max);
$format = 'int-range';
break;
case Database::VAR_FLOAT:
$min = (is_null($min)) ? -INF : \floatval($min);
$max = (is_null($max)) ? INF : \floatval($max);
$format = 'float-range';
break;
default:
throw new Exception("Format range not available for {$type} attributes.", 400);
}
try {
$attribute = $dbForInternal->createDocument('attributes', new Document([
'$id' => $collectionId.'_'.$attributeId,
'key' => $attributeId,
'collectionId' => $collectionId,
'type' => $type,
'status' => 'processing', // processing, available, failed, deleting
'size' => $size,
'required' => $required,
'signed' => $signed,
'default' => $default,
'array' => $array,
'format' => $format,
'formatOptions' => $formatOptions,
'filters' => $filters,
]));
} catch (DuplicateException $th) {
throw new Exception('Attribute already exists', 409);
}
$dbForExternal->addAttributeInQueue($collectionId, $attributeId, $type, $size, $required, $default, $signed, $array, $format, $filters);
// Database->addAttributeInQueue() does not return a document
// So we need to create one for the response
//
// TODO@kodumbeats should $signed and $filters be part of the response model?
$attribute = new Document([
'$collection' => $collectionId,
'$id' => $attributeId,
'type' => $type,
'size' => $size,
'required' => $required,
'default' => $default,
'min' => $min,
'max' => $max,
'signed' => $signed,
'array' => $array,
'format' => $format,
'filters' => $filters,
]);
$dbForInternal->purgeDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_CREATE_ATTRIBUTE)
->setParam('collection', $collection)
->setParam('document', $attribute)
;
@ -139,13 +124,15 @@ App::post('/v1/database/collections')
->label('sdk.response.model', Response::MODEL_COLLECTION)
->param('collectionId', '', 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', '', new Text(128), 'Collection name. Max length: 128 chars.')
->param('permission', null, new WhiteList(['document', 'collection']), 'Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the `read` and `write` params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $name, $read, $write, $response, $dbForExternal, $audits, $usage) {
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Appwrite\Event\Event $audits */
@ -153,17 +140,22 @@ App::post('/v1/database/collections')
$collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId;
$collection = $dbForExternal->createCollection($collectionId);
try {
$dbForExternal->createCollection($collectionId);
// TODO@kodumbeats what should the default permissions be?
$read = (is_null($read)) ? ($collection->getRead() ?? []) : $read; // By default inherit read permissions
$write = (is_null($write)) ? ($collection->getWrite() ?? []) : $write; // By default inherit write permissions
$collection->setAttribute('name', $name);
$collection->setAttribute('$read', $read);
$collection->setAttribute('$write', $write);
$dbForExternal->updateDocument(Database::COLLECTIONS, $collectionId, $collection);
$collection = $dbForInternal->createDocument('collections', new Document([
'$id' => $collectionId,
'$read' => $read ?? [], // Collection permissions for collection documents (based on permission model)
'$write' => $write ?? [], // Collection permissions for collection documents (based on permission model)
'permission' => $permission, // Permissions model type (document vs collection)
'dateCreated' => time(),
'dateUpdated' => time(),
'name' => $name,
'search' => implode(' ', [$collectionId, $name]),
]));
} catch (DuplicateException $th) {
throw new Exception('Collection already exists', 409);
}
$audits
->setParam('event', 'database.collections.create')
@ -195,16 +187,20 @@ App::get('/v1/database/collections')
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForExternal, $usage) {
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
$queries = [];
if (!empty($search)) {
$queries[] = new Query('name', Query::TYPE_SEARCH, [$search]);
}
if (!empty($after)) {
$afterCollection = $dbForExternal->getDocument('collections', $after);
$afterCollection = $dbForInternal->getDocument('collections', $after);
if ($afterCollection->isEmpty()) {
throw new Exception("Collection '{$after}' for the 'after' value not found.", 400);
@ -214,8 +210,8 @@ App::get('/v1/database/collections')
$usage->setParam('database.collections.read', 1);
$response->dynamic(new Document([
'collections' => $dbForExternal->find(Database::COLLECTIONS, $queries, $limit, $offset, [], [$orderType], $afterCollection ?? null),
'sum' => $dbForExternal->count(Database::COLLECTIONS, $queries, APP_LIMIT_COUNT),
'collections' => $dbForInternal->find('collections', $queries, $limit, $offset, [], [$orderType], $afterCollection ?? null),
'sum' => $dbForInternal->count('collections', $queries, APP_LIMIT_COUNT),
]), Response::MODEL_COLLECTION_LIST);
});
@ -233,13 +229,13 @@ App::get('/v1/database/collections/:collectionId')
->param('collectionId', '', new UID(), 'Collection unique ID.')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($collectionId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -360,19 +356,20 @@ App::put('/v1/database/collections/:collectionId')
->label('sdk.response.model', Response::MODEL_COLLECTION)
->param('collectionId', '', new UID(), 'Collection unique ID.')
->param('name', null, new Text(128), 'Collection name. Max length: 128 chars.')
->param('permission', null, new WhiteList(['document', 'collection']), 'Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the `read` and `write` params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $name, $read, $write, $response, $dbForExternal, $audits, $usage) {
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForInternal, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -382,16 +379,21 @@ App::put('/v1/database/collections/:collectionId')
$write = (is_null($write)) ? ($collection->getWrite() ?? []) : $write; // By default inherit write permissions
try {
$collection = $dbForExternal->updateDocument(Database::COLLECTIONS, $collection->getId(), new Document(\array_merge($collection->getArrayCopy(), [
'name' => $name,
'$read' => $read,
'$write' => $write
])));
} catch (AuthorizationException $exception) {
$collection = $dbForInternal->updateDocument('collections', $collection->getId(), $collection
->setAttribute('$write', $write)
->setAttribute('$read', $read)
->setAttribute('name', $name)
->setAttribute('permission', $permission)
->setAttribute('dateUpdated', time())
->setAttribute('search', implode(' ', [$collectionId, $name]))
);
}
catch (AuthorizationException $exception) {
throw new Exception('Unauthorized permissions', 401);
} catch (StructureException $exception) {
}
catch (StructureException $exception) {
throw new Exception('Bad structure. '.$exception->getMessage(), 400);
}
}
$usage->setParam('database.collections.update', 1);
@ -417,25 +419,31 @@ App::delete('/v1/database/collections/:collectionId')
->label('sdk.response.model', Response::MODEL_NONE)
->param('collectionId', '', new UID(), 'Collection unique ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('events')
->inject('audits')
->inject('deletes')
->inject('usage')
->action(function ($collectionId, $response, $dbForExternal, $events, $audits, $deletes, $usage) {
->action(function ($collectionId, $response, $dbForInternal, $dbForExternal, $events, $audits, $deletes, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $audits */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
$dbForExternal->deleteCollection($collectionId);
$dbForExternal->deleteCollection($collectionId); // TDOD move to DB worker
if (!$dbForInternal->deleteDocument('collections', $collectionId)) {
throw new Exception('Failed to remove collection from DB', 500);
}
$usage->setParam('database.collections.delete', 1);
@ -471,26 +479,25 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_STRING,
'size' => $size,
'required' => $required,
'default' => $default,
'array' => $array,
]), $response, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/email')
@ -511,27 +518,26 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_STRING,
'size' => 254,
'required' => $required,
'default' => $default,
'array' => $array,
'format' => \json_encode(['name'=>'email']),
]), $response, $dbForExternal, $database, $audits, $usage);
'format' => 'email',
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/ip')
@ -552,27 +558,26 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_STRING,
'size' => 39,
'required' => $required,
'default' => $default,
'array' => $array,
'format' => \json_encode(['name'=>'ip']),
]), $response, $dbForExternal, $database, $audits, $usage);
'format' => 'ip',
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/url')
@ -589,32 +594,30 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('attributeId', '', new Key(), 'Attribute ID.')
->param('size', null, new Integer(), 'Attribute size for text attributes, in number of characters.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_STRING,
'size' => $size,
'size' => 2000,
'required' => $required,
'default' => $default,
'array' => $array,
'format' => \json_encode(['name'=>'url']),
]), $response, $dbForExternal, $database, $audits, $usage);
'format' => 'url',
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/integer')
@ -637,32 +640,30 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
->param('default', null, new Integer(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_INTEGER,
'size' => 0,
'required' => $required,
'default' => $default,
'array' => $array,
'format' => \json_encode([
'name'=>'int-range',
'min' => $min,
'max' => $max,
]),
]), $response, $dbForExternal, $database, $audits, $usage);
'format' => 'int-range',
'formatOptions' => [
'min' => (is_null($min)) ? PHP_INT_MIN : \intval($min),
'max' => (is_null($max)) ? PHP_INT_MAX : \intval($max),
],
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/float')
@ -685,31 +686,30 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
->param('default', null, new FloatValidator(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_FLOAT,
'required' => $required,
'size' => 0,
'default' => $default,
'array' => $array,
'format' => \json_encode([
'name'=>'float-range',
'min' => $min,
'max' => $max,
]),
]), $response, $dbForExternal, $database, $audits, $usage);
'format' => 'float-range',
'formatOptions' => [
'min' => (is_null($min)) ? PHP_FLOAT_MIN : \floatval($min),
'max' => (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max),
],
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::post('/v1/database/collections/:collectionId/attributes/boolean')
@ -730,26 +730,25 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
->param('default', null, new Boolean(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForExternal, $database, $audits, $usage) use ($attributesCallback) {
->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) use ($attributesCallback) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal*/
/** @var Utopia\Database\Database $dbForInternal*/
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
return $attributesCallback(new Document([
'$collection' => $collectionId,
return $attributesCallback($collectionId, new Document([
'$id' => $attributeId,
'type' => Database::VAR_BOOLEAN,
'size' => 0,
'required' => $required,
'default' => $default,
'array' => $array,
]), $response, $dbForExternal, $database, $audits, $usage);
]), $response, $dbForInternal, $database, $audits, $usage);
});
App::get('/v1/database/collections/:collectionId/attributes')
@ -765,14 +764,13 @@ App::get('/v1/database/collections/:collectionId/attributes')
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_LIST)
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($collectionId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -808,14 +806,13 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId')
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('attributeId', '', new Key(), 'Attribute ID.')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($collectionId, $attributeId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $attributeId, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if (empty($collection)) {
throw new Exception('Collection not found', 404);
@ -853,43 +850,37 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('attributeId', '', new Key(), 'Attribute ID.')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $attributeId, $response, $dbForExternal, $database, $events, $audits, $usage) {
->action(function ($collectionId, $attributeId, $response, $dbForInternal, $database, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
/** @var Document[] $attributes */
$attributes = $collection->getAttribute('attributes');
$attribute = $dbForInternal->getDocument('attributes', $collectionId.'_'.$attributeId);
// find attribute in collection
$attribute = null;
foreach ($attributes as $a) {
if ($a->getId() === $attributeId) {
$attribute = $a->setAttribute('$collection', $collectionId); // set the collectionId
break; // break once attribute is found
}
}
if (\is_null($attribute)) {
if (empty($attribute->getId())) {
throw new Exception('Attribute not found', 404);
}
$attribute = $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
$dbForInternal->purgeDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE)
->setParam('collection', $collection)
->setParam('document', $attribute)
;
@ -926,18 +917,18 @@ App::post('/v1/database/collections/:collectionId/indexes')
->param('attributes', null, new ArrayList(new Key()), 'Array of attributes to index.')
->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING)), 'Array of index orders.', true)
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $indexId, $type, $attributes, $orders, $response, $dbForExternal, $database, $audits, $usage) {
->action(function ($collectionId, $indexId, $type, $attributes, $orders, $response, $dbForInternal, $database, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $audits */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -954,7 +945,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
// set attribute size as length for strings, null otherwise
foreach ($attributes as $key => $attribute) {
// find attribute metadata in collection document
$attributeIndex = \array_search($attribute, array_column($oldAttributes, '$id'));
$attributeIndex = \array_search($attribute, array_column($oldAttributes, 'key'));
if ($attributeIndex === false) {
throw new Exception('Unknown attribute: ' . $attribute, 400);
@ -967,23 +958,27 @@ App::post('/v1/database/collections/:collectionId/indexes')
$lengths[$key] = ($attributeType === Database::VAR_STRING) ? $attributeSize : null;
}
$dbForExternal->addIndexInQueue($collectionId, $indexId, $type, $attributes, $lengths, $orders);
// Database->createIndex() does not return a document
// So we need to create one for the response
//
// TODO@kodumbeats should $lengths be a part of the response model?
$index = new Document([
'$collection' => $collectionId,
'$id' => $indexId,
'type' => $type,
'attributes' => $attributes,
'lengths' => $lengths,
'orders' => $orders,
]);
try {
$index = $dbForInternal->createDocument('indexes', new Document([
'$id' => $collectionId.'_'.$indexId,
'key' => $indexId,
'status' => 'processing', // processing, available, failed, deleting
'collectionId' => $collectionId,
'type' => $type,
'attributes' => $attributes,
'lengths' => $lengths,
'orders' => $orders,
]));
} catch (DuplicateException $th) {
throw new Exception('Attribute already exists', 409);
}
$dbForInternal->purgeDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_CREATE_INDEX)
->setParam('collection', $collection)
->setParam('document', $index)
;
@ -997,7 +992,6 @@ App::post('/v1/database/collections/:collectionId/indexes')
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic($index, Response::MODEL_INDEX);
});
App::get('/v1/database/collections/:collectionId/indexes')
@ -1013,14 +1007,13 @@ App::get('/v1/database/collections/:collectionId/indexes')
->label('sdk.response.model', Response::MODEL_INDEX_LIST)
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($collectionId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1056,14 +1049,13 @@ App::get('/v1/database/collections/:collectionId/indexes/:indexId')
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('indexId', null, new Key(), 'Index ID.')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('usage')
->action(function ($collectionId, $indexId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $indexId, $response, $dbForInternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
/** @var Utopia\Database\Database $dbForInternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1071,7 +1063,7 @@ App::get('/v1/database/collections/:collectionId/indexes/:indexId')
$indexes = $collection->getAttribute('indexes');
// // Search for index
// Search for index
$indexIndex = array_search($indexId, array_column($indexes, '$id'));
if ($indexIndex === false) {
@ -1101,43 +1093,37 @@ App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('indexId', '', new Key(), 'Index ID.')
->inject('response')
->inject('dbForExternal')
->inject('dbForInternal')
->inject('database')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $indexId, $response, $dbForExternal, $database, $events, $audits, $usage) {
->action(function ($collectionId, $indexId, $response, $dbForInternal, $database, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Appwrite\Event\Event $database */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
}
/** @var Document[] $indexes */
$indexes = $collection->getAttribute('indexes');
$index = $dbForInternal->getDocument('indexes', $collectionId.'_'.$indexId);
// find attribute in collection
$index= null;
foreach ($indexes as $i) {
if ($i->getId() === $indexId) {
$index = $i->setAttribute('$collection', $collectionId); // set the collectionId
break; // break once index is found
}
}
if (\is_null($index)) {
if (empty($index->getId())) {
throw new Exception('Index not found', 404);
}
$index = $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
$dbForInternal->purgeDocument('collections', $collectionId);
$database
->setParam('type', DATABASE_TYPE_DELETE_INDEX)
->setParam('collection', $collection)
->setParam('document', $index)
;
@ -1174,12 +1160,14 @@ App::post('/v1/database/collections/:collectionId/documents')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('user')
->inject('audits')
->inject('usage')
->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForExternal, $user, $audits, $usage) {
->action(function ($documentId, $collectionId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $user, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
@ -1195,7 +1183,7 @@ App::post('/v1/database/collections/:collectionId/documents')
throw new Exception('$id is not allowed for creating new documents, try update instead', 400);
}
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1212,6 +1200,9 @@ App::post('/v1/database/collections/:collectionId/documents')
catch (StructureException $exception) {
throw new Exception($exception->getMessage(), 400);
}
catch (DuplicateException $exception) {
throw new Exception('Document already exists', 409);
}
$usage
->setParam('database.documents.create', 1)
@ -1247,14 +1238,16 @@ App::get('/v1/database/collections/:collectionId/documents')
->param('orderAttributes', [], new ArrayList(new Text(128)), 'Array of attributes used to sort results.', true)
->param('orderTypes', [], new ArrayList(new WhiteList(['DESC', 'ASC'], true)), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('usage')
->action(function ($collectionId, $queries, $limit, $offset, $after, $orderAttributes, $orderTypes, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $queries, $limit, $offset, $after, $orderAttributes, $orderTypes, $response, $dbForInternal, $dbForExternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1264,13 +1257,8 @@ App::get('/v1/database/collections/:collectionId/documents')
return Query::parse($query);
}, $queries);
// TODO@kodumbeats find a more efficient alternative to this
$schema = $collection->getArrayCopy()['attributes'];
$indexes = $collection->getArrayCopy()['indexes'];
$indexesInQueue = $collection->getArrayCopy()['indexesInQueue'];
// TODO@kodumbeats use strict query validation
$validator = new QueriesValidator(new QueryValidator($schema), $indexes, $indexesInQueue, false);
$validator = new QueriesValidator(new QueryValidator($collection->getAttribute('attributes', [])), $collection->getAttribute('indexes', []), false);
if (!$validator->isValid($queries)) {
throw new Exception($validator->getDescription(), 400);
@ -1309,13 +1297,15 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document unique ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('usage')
->action(function ($collectionId, $documentId, $response, $dbForExternal, $usage) {
->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $$dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1353,16 +1343,18 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
->param('read', null, new Permissions(), 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(), 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForExternal, $audits, $usage) {
->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForInternal, $dbForExternal, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForInternal */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1429,18 +1421,19 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
->param('documentId', null, new UID(), 'Document unique ID.')
->inject('response')
->inject('dbForInternal')
->inject('dbForExternal')
->inject('events')
->inject('audits')
->inject('usage')
->action(function ($collectionId, $documentId, $response, $dbForExternal, $events, $audits, $usage) {
->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal, $events, $audits, $usage) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForExternal */
/** @var Appwrite\Event\Event $events */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
$collection = $dbForExternal->getCollection($collectionId);
$collection = $dbForInternal->getDocument('collections', $collectionId);
if ($collection->isEmpty()) {
throw new Exception('Collection not found', 404);
@ -1470,4 +1463,4 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
;
$response->noContent();
});
});

View file

@ -319,7 +319,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
if($route) {
Console::error('[Error] Method: '.$route->getMethod());
Console::error('[Error] URL: '.$route->getURL());
Console::error('[Error] URL: '.$route->getPath());
}
Console::error('[Error] Type: '.get_class($error));

View file

@ -518,7 +518,7 @@ App::shutdown(function($utopia, $response, $request) {
throw new Exception('Failed to read results', 500);
}
$result[$route->getMethod() . ':' . $route->getURL()] = true;
$result[$route->getMethod() . ':' . $route->getPath()] = true;
$tests = \array_merge($tests, $result);
@ -526,5 +526,5 @@ App::shutdown(function($utopia, $response, $request) {
throw new Exception('Failed to save results', 500);
}
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getURL() . ':passed']), Response::MODEL_MOCK);
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK);
}, ['utopia', 'response', 'request'], 'mock');

View file

@ -41,7 +41,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
->setParam('{userId}', $user->getId())
->setParam('{userAgent}', $request->getUserAgent(''))
->setParam('{ip}', $request->getIP())
->setParam('{url}', $request->getHostname().$route->getURL())
->setParam('{url}', $request->getHostname().$route->getPath())
;
// TODO make sure we get array here

View file

@ -21,10 +21,9 @@ use Appwrite\Extend\PDO;
use Ahc\Jwt\JWT;
use Ahc\Jwt\JWTException;
use Appwrite\Auth\Auth;
use Appwrite\Database\Database;
use Appwrite\Database\Database as DatabaseOld;
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
use Appwrite\Database\Adapter\Redis as RedisAdapter;
use Appwrite\Database\Document;
use Appwrite\Event\Event;
use Appwrite\Network\Validator\Email;
use Appwrite\Network\Validator\IP;
@ -41,8 +40,8 @@ use PHPMailer\PHPMailer\PHPMailer;
use Utopia\Cache\Adapter\Redis as RedisCache;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Document as Document2;
use Utopia\Database\Database as Database2;
use Utopia\Database\Document;
use Utopia\Database\Database;
use Utopia\Database\Validator\Structure;
use Utopia\Database\Validator\Authorization;
use Utopia\Validator\Range;
@ -50,6 +49,7 @@ use Swoole\Database\PDOConfig;
use Swoole\Database\PDOPool;
use Swoole\Database\RedisConfig;
use Swoole\Database\RedisPool;
use Utopia\Database\Query;
const APP_NAME = 'Appwrite';
const APP_DOMAIN = 'appwrite.io';
@ -62,7 +62,7 @@ const APP_PAGING_LIMIT = 12;
const APP_LIMIT_COUNT = 5000;
const APP_LIMIT_USERS = 10000;
const APP_CACHE_BUSTER = 151;
const APP_VERSION_STABLE = '0.10.0';
const APP_VERSION_STABLE = '0.9.4';
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_CACHE = '/storage/cache';
@ -139,10 +139,11 @@ if(!empty($user) || !empty($pass)) {
} else {
Resque::setBackend(App::getEnv('_APP_REDIS_HOST', '').':'.App::getEnv('_APP_REDIS_PORT', ''));
}
/**
* DB Filters
*/
Database::addFilter('json',
DatabaseOld::addFilter('json',
function($value) {
if(!is_array($value)) {
return $value;
@ -154,7 +155,7 @@ Database::addFilter('json',
}
);
Database::addFilter('encrypt',
DatabaseOld::addFilter('encrypt',
function($value) {
$key = App::getEnv('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
@ -176,7 +177,31 @@ Database::addFilter('encrypt',
}
);
Database2::addFilter('encrypt',
Database::addFilter('subQueryAttributes',
function($value) {
return null;
},
function($value, Document $document, Database $database) {
return $database
->find('attributes', [
new Query('collectionId', Query::TYPE_EQUAL, [$document->getId()])
], 100, 0, []);
}
);
Database::addFilter('subQueryIndexes',
function($value) {
return null;
},
function($value, Document $document, Database $database) {
return $database
->find('indexes', [
new Query('collectionId', Query::TYPE_EQUAL, [$document->getId()])
], 100, 0, []);
}
);
Database::addFilter('encrypt',
function($value) {
$key = App::getEnv('_APP_OPENSSL_KEY_V1');
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
@ -197,37 +222,32 @@ Database2::addFilter('encrypt',
}
);
/**
* DB Formats
*/
Structure::addFormat('email', function() {
return new Email();
}, Database2::VAR_STRING);
}, Database::VAR_STRING);
Structure::addFormat('ip', function() {
return new IP();
}, Database2::VAR_STRING);
}, Database::VAR_STRING);
Structure::addFormat('url', function() {
return new URL();
}, Database2::VAR_STRING);
}, Database::VAR_STRING);
Structure::addFormat('int-range', function($attribute) {
// Format encoded as json string containing name and relevant options
// E.g. Range: $format = json_encode(['name'=>$name, 'min'=>$min, 'max'=>$max]);
$format = json_decode($attribute['format'], true);
$min = $format['min'] ?? -INF;
$max = $format['max'] ?? INF;
$type = $attribute['type'];
return new Range($min, $max, $type);
}, Database2::VAR_INTEGER);
$min = $attribute['formatOptions']['min'] ?? -INF;
$max = $attribute['formatOptions']['max'] ?? INF;
return new Range($min, $max, Range::TYPE_INTEGER);
}, Database::VAR_INTEGER);
Structure::addFormat('float-range', function($attribute) {
// Format encoded as json string containing name and relevant options
// E.g. Range: $format = json_encode(['name'=>$name, 'min'=>$min, 'max'=>$max]);
$format = json_decode($attribute['format'], true);
$min = $format['min'] ?? -INF;
$max = $format['max'] ?? INF;
$type = $attribute['type'] ?? '';
return new Range($min, $max, $type);
}, Database2::VAR_FLOAT);
$min = $attribute['formatOptions']['min'] ?? -INF;
$max = $attribute['formatOptions']['max'] ?? INF;
return new Range($min, $max, Range::TYPE_FLOAT);
}, Database::VAR_FLOAT);
/*
* Registry
@ -463,8 +483,8 @@ App::setResource('database', function($register) {
// Test Mock
App::setResource('clients', function($request, $console, $project) {
$console->setAttribute('platforms', [ // Allways allow current host
'$collection' => Database::SYSTEM_COLLECTION_PLATFORMS,
$console->setAttribute('platforms', [ // Always allow current host
'$collection' => 'platforms',
'name' => 'Current Host',
'type' => 'web',
'hostname' => $request->getHostname(),
@ -532,7 +552,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
if (APP_MODE_ADMIN !== $mode) {
if ($project->isEmpty()) {
$user = new Document2(['$id' => '', '$collection' => 'users']);
$user = new Document(['$id' => '', '$collection' => 'users']);
}
else {
$user = $dbForInternal->getDocument('users', Auth::$unique);
@ -544,14 +564,14 @@ App::setResource('user', function($mode, $project, $console, $request, $response
if ($user->isEmpty() // Check a document has been found in the DB
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret)) { // Validate user has valid login token
$user = new Document2(['$id' => '', '$collection' => 'users']);
$user = new Document(['$id' => '', '$collection' => 'users']);
}
if (APP_MODE_ADMIN === $mode) {
if ($user->find('teamId', $project->getAttribute('teamId'), 'memberships')) {
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
} else {
$user = new Document2(['$id' => '', '$collection' => 'users']);
$user = new Document(['$id' => '', '$collection' => 'users']);
}
}
@ -574,7 +594,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response
}
if (empty($user->find('$id', $jwtSessionId, 'sessions'))) { // Match JWT to active token
$user = new Document2(['$id' => '', '$collection' => 'users']);
$user = new Document(['$id' => '', '$collection' => 'users']);
}
}
@ -603,7 +623,7 @@ App::setResource('project', function($dbForConsole, $request, $console) {
}, ['dbForConsole', 'request', 'console']);
App::setResource('console', function() {
return new Document2([
return new Document([
'$id' => 'console',
'name' => 'Appwrite',
'$collection' => 'projects',
@ -614,19 +634,19 @@ App::setResource('console', function() {
'keys' => [],
'platforms' => [
[
'$collection' => Database::SYSTEM_COLLECTION_PLATFORMS,
'$collection' => 'platforms',
'name' => 'Production',
'type' => 'web',
'hostname' => 'appwrite.io',
],
[
'$collection' => Database::SYSTEM_COLLECTION_PLATFORMS,
'$collection' => 'platforms',
'name' => 'Development',
'type' => 'web',
'hostname' => 'appwrite.test',
],
[
'$collection' => Database::SYSTEM_COLLECTION_PLATFORMS,
'$collection' => 'platforms',
'name' => 'Localhost',
'type' => 'web',
'hostname' => 'localhost',
@ -647,7 +667,7 @@ App::setResource('console', function() {
}, []);
App::setResource('consoleDB', function($db, $cache) {
$consoleDB = new Database();
$consoleDB = new DatabaseOld();
$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', []));
@ -656,7 +676,7 @@ App::setResource('consoleDB', function($db, $cache) {
}, ['db', 'cache']);
App::setResource('projectDB', function($db, $cache, $project) {
$projectDB = new Database();
$projectDB = new DatabaseOld();
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($db, $cache), $cache));
$projectDB->setNamespace('app_'.$project->getId());
$projectDB->setMocks(Config::getParam('collections', []));
@ -667,7 +687,7 @@ App::setResource('projectDB', function($db, $cache, $project) {
App::setResource('dbForInternal', function($db, $cache, $project) {
$cache = new Cache(new RedisCache($cache));
$database = new Database2(new MariaDB($db), $cache);
$database = new Database(new MariaDB($db), $cache);
$database->setNamespace('project_'.$project->getId().'_internal');
return $database;
@ -676,7 +696,7 @@ App::setResource('dbForInternal', function($db, $cache, $project) {
App::setResource('dbForExternal', function($db, $cache, $project) {
$cache = new Cache(new RedisCache($cache));
$database = new Database2(new MariaDB($db), $cache);
$database = new Database(new MariaDB($db), $cache);
$database->setNamespace('project_'.$project->getId().'_external');
return $database;
@ -685,7 +705,7 @@ App::setResource('dbForExternal', function($db, $cache, $project) {
App::setResource('dbForConsole', function($db, $cache) {
$cache = new Cache(new RedisCache($cache));
$database = new Database2(new MariaDB($db), $cache);
$database = new Database(new MariaDB($db), $cache);
$database->setNamespace('project_console_internal');
return $database;

View file

@ -251,7 +251,7 @@
</span>
<div class="pull-start margin-end avatar-container">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=60&height=60&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=60&height=60&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<div data-ls-if="{{session.provider}} !== 'email'" class="corner">
<img data-ls-attrs="src=/images/users/{{session.provider}}.png?buster=<?php echo APP_CACHE_BUSTER; ?>,title={{session.provider}},alt={{session.provider}}" class="avatar xs" loading="lazy" width="30" height="30" />
@ -266,7 +266,7 @@
</span>
<div class="margin-top-small">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<small data-ls-bind="{{session.ip}}"></small> / <small data-ls-bind="{{session.countryName}}"></small>
</div>
</li>
@ -308,7 +308,7 @@
<th width="120">Date</th>
<th width="175">Event</th>
<th>Client</th>
<th width="90">Location</th>
<th width="110">Location</th>
<th width="90">IP</th>
</tr>
</thead>
@ -317,13 +317,13 @@
<td data-title="Date: "><span data-ls-bind="{{log.time|dateTime}}"></span></td>
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
<td data-title="Client: ">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{log.clientCode|lowercase}}?width=80&height=80&project={{env.PROJECT}},title={{log.clientName}},alt={{log.clientName}}" class="avatar xxs inline margin-end-small" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{log.clientCode|lowercase}}?width=80&height=80&project={{env.PROJECT}},title={{log.clientName}},alt={{log.clientName}}" class="avatar xxs inline margin-end-small" />
<span data-ls-if="(!{{log.clientName}})">Unknown</span>
<span data-ls-if="({{log.clientName}})" data-ls-bind="{{log.clientName}} {{log.clientVersion}} on {{log.model}} {{log.osName}} {{log.osVersion}}"></span>
</td>
<td data-title="Location: ">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.geo.countryName}}"></span>
<img onerror="this.onerror=null;this.className='avatar xxs hide'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.countryName}}"></span>
</td>
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>
</tr>

View file

@ -21,7 +21,7 @@ $interval = floor((int)$this->getParam('interval', 0) / 86400);
<th width="120">Date</th>
<th width="180">Initiator</th>
<th>Event</th>
<th width="90">Location</th>
<th width="110">Location</th>
<th width="90">IP</th>
</tr>
</thead>
@ -32,13 +32,15 @@ $interval = floor((int)$this->getParam('interval', 0) / 86400);
<span data-ls-if="{{log.userName|escape}} !== '' && {{log.mode}} === ''"><i class="icon-user"></i>&nbsp; <a data-ls-attrs="href=/console/users/user?id={{log.userId}}&project={{router.params.project}}" data-ls-bind="{{log.userName}}"></a></span>
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} !== '' && {{log.mode}} !== 'key'"><i class="icon-user"></i>&nbsp; Unknown</span>
<span data-ls-if="{{log.userName|escape}} === '' && {{log.userEmail}} === '' && {{log.mode}} !== 'key'"><i class="icon-user"></i>&nbsp; Anonymous User</span>
<span data-ls-if="{{log.mode}} === 'admin'"><i class="icon-user"></i>&nbsp; <span data-ls-bind="{{log.userName}} (Admin)"></span></span>
<span data-ls-if="{{log.mode}} === 'admin'">
<img src="" data-ls-attrs="src={{log.userName|avatar}}" data-size="45" alt="User Avatar" class="avatar xxs inline margin-end-small" loading="lazy" width="30" height="30" /> <span data-ls-bind="{{log.userName}}"></span> <span class="text-fade text-size-xs">(Admin)</span>
</span>
<span data-ls-if="{{log.mode}} === 'key'"> <i class="icon-key"></i>&nbsp; API Key</span>
</td>
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
<td data-title="Location: ">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.geo.countryName}}"></span>
<img onerror="this.onerror=null;this.className='avatar xxs hide'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.countryName}}"></span>
</td>
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>
</tr>

View file

@ -57,7 +57,7 @@ $logs = $this->getParam('logs', null);
</div>
<div data-ls-if="({{project-documents.sum}})" class="margin-top-negative">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-documents.sum}}"></span> documents found</div>
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-documents.sum}}"></span> documents found</div>
<div class="box margin-bottom y-scroll text-size-small">
<table class="vertical borders">
@ -65,14 +65,14 @@ $logs = $this->getParam('logs', null);
<tr data-ls-loop="project-collection.attributes" data-ls-as="attribute" data-ls-prefix="template-attribute-title-first" data-ls-limit="20">
<td style="width: 170px">
<i data-ls-attrs="class=pull-end icon-{{attribute.type}} text-size-xs"></i>
<span class="text-bold" data-ls-bind="{{attribute.$id}}"></span>
<span class="text-bold" data-ls-bind="{{attribute.key}}"></span>
<span class="text-size-small" data-ls-if="{{attribute.array}}">[]</span>
</td>
</tr>
</thead>
<tbody data-ls-loop="project-documents.documents" data-ls-as="node">
<tr data-ls-loop="project-collection.attributes" data-ls-as="attribute" data-ls-prefix="template-attribute-body-first" data-ls-limit="20">
<td data-ls-attrs="data-title={{attribute.$id}}: ">
<td data-ls-attrs="data-title={{attribute.key}}: ">
<!-- <a href="" target="_blank" rel="noopener" class="pull-end margin-start"><i class="icon-link-ext"></i></a> -->
<a data-ls-attrs="href=/console/database/document?id={{node.$id}}&collection={{router.params.id}}&project={{router.params.project}}"><span data-ls-bind="{{node|documentAttribute}}"></span></a>
<span data-ls-if="!{{node|documentAttribute}}" class="text-fade">n/a</span>
@ -130,17 +130,17 @@ $logs = $this->getParam('logs', null);
<h2>Attributes</h2>
<div class="clear box margin-bottom">
<div data-ls-if="0 == {{project-collection.attributes.length}} && 0 == {{project-collection.attributesInQueue.length}}">
<div data-ls-if="0 == {{project-collection.attributes.length}}">
<h3 class="margin-bottom-small text-bold">No Attributes Found</h3>
<p class="margin-bottom-no">Add your first attribute to get started</p>
</div>
<table class="vertical" data-ls-if="0 < {{project-collection.attributes.length}} || 0 < {{project-collection.attributesInQueue.length}}">
<table class="vertical" data-ls-if="0 < {{project-collection.attributes.length}}">
<thead>
<tr>
<th width="30"></th>
<th width="80"></th>
<th width="100"></th>
<th width="130">Attribute ID</th>
<th width="100">Type</th>
<th width="180">Default</th>
@ -154,11 +154,14 @@ $logs = $this->getParam('logs', null);
<i data-ls-attrs="class=icon-{{attribute.type}}"></i>
</td>
<td data-title="Status">
<span class="text-size-small text-success">available&nbsp;</span>
<span data-ls-if="{{attribute.status}} == 'available'" class="text-size-small text-success">available&nbsp;</span>
<span data-ls-if="{{attribute.status}} == 'processing'" class="text-size-small text-info">processing&nbsp;</span>
<span data-ls-if="{{attribute.status}} == 'failed'" class="text-size-small text-danger">failed&nbsp;</span>
<span data-ls-if="{{attribute.status}} == 'deleting'" class="text-size-small text-danger">deleting&nbsp;</span>
</td>
<td data-title="Attribute ID: ">
<span class="text-size-small" data-ls-bind="{{attribute.$id}}"></span><span class="text-size-small" data-ls-if="{{attribute.size}}" data-ls-bind=" ({{attribute.size}})"></span>
<span class="text-size-small" data-ls-bind="{{attribute.key}}"></span><span class="text-size-small" data-ls-if="{{attribute.size}}" data-ls-bind=" ({{attribute.size}})"></span>
</td>
<td data-title="Type:">
@ -176,7 +179,8 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<form class="pull-end"
<form data-ls-if="{{attribute.status}} !== 'deleting'"
class="pull-end"
data-analytics
data-analytics-activity
data-analytics-event="submit"
@ -195,7 +199,7 @@ $logs = $this->getParam('logs', null);
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
<input type="hidden" name="attributeId" data-ls-bind="{{attribute.$id}}" />
<input type="hidden" name="attributeId" data-ls-bind="{{attribute.key}}" />
<button class="danger small">Delete</button>
</form>
@ -203,54 +207,30 @@ $logs = $this->getParam('logs', null);
</tr>
</tbody>
</table>
<hr data-ls-if="0 < {{project-collection.attributesInQueue.length}}" />
<table class="vertical" data-ls-if="0 < {{project-collection.attributesInQueue.length}}">
<tbody data-ls-loop="project-collection.attributesInQueue" data-ls-as="attribute">
<tr>
<td width="30">
<i data-ls-attrs="class=icon-{{attribute.type}}"></i>
</td>
<td width="80" data-title="Status">
<span class="text-size-small text-info">creating&nbsp;</span>
</td>
<td width="130" data-title="Attribute ID: ">
<span class="text-size-small" data-ls-bind="{{attribute.$id}}"></span><span class="text-size-small" data-ls-if="{{attribute.size}}" data-ls-bind=" ({{attribute.size}})"></span>
</td>
<td width="100" data-title="Type:">
<span class="text-size-small" data-ls-bind="{{attribute.type}}"></span>
<span class="text-size-small" data-ls-if="{{attribute.array}}">[]</span>
</td>
<td width="180" data-title="Default:">
<span class="text-size-small" data-ls-bind="{{attribute.default}}" data-ls-attr="title={{attribute.default}}"></span>
<span class="text-fade text-size-small" data-ls-if="!({{attribute.default}})">n/a</span>
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{attribute.required}}">required</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="drop-list pull-start" data-ls-ui-open="" data-button-aria="Choose Platform" data-button-text="Add Attribute" data-button-class="button" data-blur="1">
<ul>
<li>
<div class="link new-attribute-string"><img src="/images/clients/web.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="String Attribute Logo" class="avatar xxs margin-end-small" loading="lazy" /> New String Attribute</div>
<div class="link new-attribute-string"><i class="avatar icon-string"></i> New String Attribute</div>
</li>
<li>
<div class="link new-attribute-integer"><img src="/images/clients/web.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="String Attribute Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Integer Attribute</div>
<div class="link new-attribute-integer"><i class="avatar icon-integer"></i> New Integer Attribute</div>
</li>
<li>
<div class="link new-attribute-float"><img src="/images/clients/web.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="String Attribute Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Float Attribute</div>
<div class="link new-attribute-float"><i class="avatar icon-float"></i> New Float Attribute</div>
</li>
<li>
<div class="link new-attribute-boolean"><img src="/images/clients/web.png?v=<?php echo APP_CACHE_BUSTER; ?>" alt="String Attribute Logo" class="avatar xxs margin-end-small" loading="lazy" /> New Boolean Attribute</div>
<div class="link new-attribute-boolean"><i class="avatar icon-boolean"></i> New Boolean Attribute</div>
</li>
<li>
<div class="link new-attribute-url"><i class="avatar icon-link"></i> New URL Attribute</div>
</li>
<li>
<div class="link new-attribute-email"><i class="avatar icon-mail"></i> New Email Attribute</div>
</li>
<li>
<div class="link new-attribute-ip"><i class="avatar icon-ip"></i> New IP Attribute</div>
</li>
</ul>
</div>
@ -259,13 +239,13 @@ $logs = $this->getParam('logs', null);
<h2>Indexes</h2>
<div class="clear box margin-bottom">
<div data-ls-if="0 == {{project-collection.indexes.length}} && 0 == {{project-collection.indexesInQueue.length}}">
<div data-ls-if="0 == {{project-collection.indexes.length}}">
<h3 class="margin-bottom-small text-bold">No Indexes Found</h3>
<p class="margin-bottom-no">Add your first index to get started</p>
</div>
<table class="vertical multi-line" data-ls-if="0 < {{project-collection.indexes.length}} || 0 < {{project-collection.indexesInQueue.length}}">
<table class="vertical multi-line" data-ls-if="0 < {{project-collection.indexes.length}}">
<thead>
<tr>
<th width="30"></th>
@ -284,11 +264,14 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="Status">
<span class="text-size-small text-success">available</span>
<span data-ls-if="{{index.status}} == 'available'" class="text-size-small text-success">available&nbsp;</span>
<span data-ls-if="{{index.status}} == 'processing'" class="text-size-small text-info">processing&nbsp;</span>
<span data-ls-if="{{index.status}} == 'failed'" class="text-size-small text-danger">failed&nbsp;</span>
<span data-ls-if="{{index.status}} == 'deleting'" class="text-size-small text-danger">deleting&nbsp;</span>
</td>
<td data-title="Index ID: ">
<span class="text-size-small" data-ls-bind="{{index.$id}}"></span><span class="text-size-small" data-ls-if="{{index.size}}" data-ls-bind="({{index.size}})"></span>
<span class="text-size-small" data-ls-bind="{{index.key}}"></span><span class="text-size-small" data-ls-if="{{index.size}}" data-ls-bind="({{index.size}})"></span>
</td>
<td data-title="Type:">
@ -305,7 +288,8 @@ $logs = $this->getParam('logs', null);
</td>
<td data-title="">
<form class="pull-end"
<form data-ls-if="{{index.status}} !== 'deleting'"
class="pull-end"
data-analytics
data-analytics-activity
data-analytics-event="submit"
@ -324,7 +308,7 @@ $logs = $this->getParam('logs', null);
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{project-collection.$id}}" />
<input type="hidden" name="indexId" data-ls-bind="{{index.$id}}" />
<input type="hidden" name="indexId" data-ls-bind="{{index.key}}" />
<button class="danger small">Delete</button>
</form>
@ -332,43 +316,6 @@ $logs = $this->getParam('logs', null);
</tr>
</tbody>
</table>
<hr data-ls-if="0 < {{project-collection.indexesInQueue.length}}" />
<table class="vertical multi-line" data-ls-if="0 < {{project-collection.indexesInQueue.length}}">
<tbody data-ls-loop="project-collection.indexesInQueue" data-ls-as="index">
<tr>
<td width="30">
<i class="icon-key"></i>
</td>
<td width="80" data-title="Status">
<span class="text-size-small text-info">creating</span>
</td>
<td width="130" data-title="Index ID: ">
<span class="text-size-small" data-ls-bind="{{index.$id}}"></span><span class="text-size-small" data-ls-if="{{index.size}}" data-ls-bind="({{index.size}})"></span>
</td>
<td width="100" data-title="Type:">
<span class="text-size-small" data-ls-bind="{{index.type}}"></span>
<span class="text-size-small" data-ls-if="{{index.array}}">[]</span>
</td>
<td width="180" data-title="Attributes:">
<span class="text-size-small" data-ls-bind="{{index|indexAttributes}}"></span>
</td>
<td data-title="">
<span class="text-size-small text-danger" data-ls-if="{{index.required}}">required</span>
</td>
<td width="80" data-title="">
</td>
</tr>
</tbody>
</table>
</div>
<button class="new-index">Add Index</button>
@ -417,7 +364,7 @@ $logs = $this->getParam('logs', null);
<hr class="margin-top-small" />
<div class="row">
<div class="col span-1"><input type="radio" class="margin-top-no" /></div>
<div class="col span-1"><input name="permission" value="document" type="radio" class="margin-top-no" data-ls-bind="{{project-collection.permission}}" /></div>
<div class="col span-11">
<b>Document Level</b>
<p class="text-fade margin-top-tiny">Bla bla bla bla bla Bla blabla bla Bla blabla bla Bla blabla bla Bla blaBla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla</p>
@ -425,7 +372,7 @@ $logs = $this->getParam('logs', null);
</div>
<div class="row">
<div class="col span-1"><input type="radio" class="margin-top-tiny" /></div>
<div class="col span-1"><input name="permission" value="collection" type="radio" class="margin-top-tiny" data-ls-bind="{{project-collection.permission}}" /></div>
<div class="col span-11">
<b>Collection Level</b>
<p class="text-fade margin-top-tiny">Bla bla bla Bla blabla bla Bla blabla bla Bla blabla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla bla bla Bla</p>
@ -526,7 +473,7 @@ $logs = $this->getParam('logs', null);
<input id="string-default" name="default" type="text" class="margin-bottom-large" autocomplete="off">
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
@ -569,19 +516,107 @@ $logs = $this->getParam('logs', null);
<div class="row responsive thin">
<div class="col span-6 margin-bottom-small">
<label for="integer-min">Min</label>
<input type="text" class="full-width" name="number" value="0" required autocomplete="off" />
<input id="integer-min" type="number" class="full-width" name="min" value="0" required autocomplete="off" data-cast-to="integer" />
</div>
<div class="col span-6 margin-bottom-small">
<label for="integer-min">Max</label>
<input type="text" class="full-width" name="number" value="0" required autocomplete="off" />
<label for="integer-max">Max</label>
<input id="integer-max" type="number" class="full-width" name="max" value="0" required autocomplete="off" data-cast-to="integer" />
</div>
</div>
<label for="integer-default">Default Value</label>
<input id="integer-default" name="default" type="number" value="0" class="margin-bottom-large" autocomplete="off">
<input id="integer-default" name="default" type="number" value="0" class="margin-bottom-large" autocomplete="off" data-cast-to="integer">
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
<div data-ui-modal class="modal box close sticky-footer" data-button-alias=".new-attribute-email">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Add Email Attribute</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Collection Attribute (email)"
data-service="database.createEmailAttribute"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created new attribute successfully"
data-success-param-trigger-events="database.createAttribute"
data-failure="alert"
data-failure-param-alert-text="Failed to create attribute"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
<label for="string-attributeId">Attribute ID</label>
<input type="text" class="full-width" name="attributeId" required autocomplete="off" maxlength="128" />
<div class="margin-bottom">
<input name="required" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Required <span class="tooltip" data-tooltip="Mark whether this is a required attribute"><i class="icon-info-circled"></i></span>
</div>
<div class="margin-bottom">
<input name="array" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Array <span class="tooltip" data-tooltip="Mark whether this attribute should act as an array"><i class="icon-info-circled"></i></span>
</div>
<label for="string-default">Default Value</label>
<input id="string-default" name="default" type="email" placeholder="demo@appwrite.io" class="margin-bottom-large" autocomplete="off">
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
<div data-ui-modal class="modal box close sticky-footer" data-button-alias=".new-attribute-url">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Add URL Attribute</h1>
<form
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Collection Attribute (url)"
data-service="database.createUrlAttribute"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created new attribute successfully"
data-success-param-trigger-events="database.createAttribute"
data-failure="alert"
data-failure-param-alert-text="Failed to create attribute"
data-failure-param-alert-classname="error">
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
<label for="string-attributeId">Attribute ID</label>
<input type="text" class="full-width" name="attributeId" required autocomplete="off" maxlength="128" />
<div class="margin-bottom">
<input name="required" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Required <span class="tooltip" data-tooltip="Mark whether this is a required attribute"><i class="icon-info-circled"></i></span>
</div>
<div class="margin-bottom">
<input name="array" type="hidden" data-forms-switch data-cast-to="boolean" /> &nbsp; Array <span class="tooltip" data-tooltip="Mark whether this attribute should act as an array"><i class="icon-info-circled"></i></span>
</div>
<label for="string-default">Default Value</label>
<input id="string-default" name="default" type="url" placeholder="https://appwrite.io/my-link" class="margin-bottom-large" autocomplete="off">
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>
@ -598,7 +633,7 @@ $logs = $this->getParam('logs', null);
<p>Please add your first attribute before adding your first index.</p>
</div>
<button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
<form data-ls-if="0 < {{project-collection.attributes.length}}"
@ -639,7 +674,7 @@ $logs = $this->getParam('logs', null);
<div class="row responsive thin margin-bottom-tiny">
<div class="col span-7 margin-bottom-small">
<select data-duplications data-ls-attrs="name=attributes" data-ls-loop="project-collection.attributes" data-ls-as="option" data-cast-to="array" class="margin-bottom-no">
<option data-ls-attrs="value={{option.$id}}" data-ls-bind="{{option.$id}}"></option>
<option data-ls-attrs="value={{option.key}}" data-ls-bind="{{option.key}}"></option>
</select>
</div>
<div class="col span-4 margin-bottom-small">
@ -656,7 +691,7 @@ $logs = $this->getParam('logs', null);
</div>
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</footer>
</form>
</div>

View file

@ -71,11 +71,11 @@
<ul data-ls-loop="project-collection.attributes" data-ls-as="attribute">
<li>
<label>
<div data-ls-bind="{{attribute.$id}}" class="margin-bottom-tiny"></div>
<div data-ls-bind="{{attribute.key}}" class="margin-bottom-tiny"></div>
<div data-ls-if="{{attribute.required}}" class="text-size-xs text-danger text-fade">required</div>
<div data-ls-if="!{{attribute.required}}" class="text-size-xs text-fade">optional</div>
</label>
<textarea data-ls-attrs="name={{attribute.$id}}" data-ls-bind="{{project-document|documentAttribute}}"></textarea>
<textarea data-ls-attrs="name={{attribute.key}}" data-ls-bind="{{project-document|documentAttribute}}"></textarea>
</li>
</ul>
</fieldset>

View file

@ -107,9 +107,9 @@
<label for="collection-name">Name</label>
<input type="text" class="full-width" id="collection-name" name="name" required autocomplete="off" maxlength="128" />
<input type="hidden" id="collection-permission" name="permission" required value="document" />
<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 />

View file

@ -34,7 +34,7 @@ $runtimes = $this->getParam('runtimes', []);
</div>
<div data-ls-if="0 != {{project-functions.functions.length}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small margin-top-negative"><span data-ls-bind="{{project-functions.sum}}"></span> functions found</div>
<div class="margin-bottom-small text-align-end text-size-small margin-top-negative text-fade"><span data-ls-bind="{{project-functions.sum}}"></span> functions found</div>
<div class="box margin-bottom">
<ul data-ls-loop="project-functions.functions" data-ls-as="function" class="list">

View file

@ -129,7 +129,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
</div>
<div class="col span-3">
<div class="value"><span class="sum" data-ls-bind="{{usage.functions.total|statsTotal}}" data-default="0">0</span></div>
<div class="margin-top-small"><b class="text-size-small unit">Func. Executions</b></div>
<div class="margin-top-small"><b class="text-size-small unit">Executions</b></div>
</div>
</div>
</div>
@ -290,7 +290,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
</div>
</div>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
@ -322,7 +322,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Back</button>
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Cancel</button>
</form>
</script>
@ -358,7 +358,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
@ -398,7 +398,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</li>
@ -432,7 +432,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</li>
<li>
@ -465,7 +465,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</li>
<li>
@ -498,7 +498,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</li>
<li>
@ -531,7 +531,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Back</button>
<button type="submit">Register</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</li>
</ul>
@ -565,7 +565,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Back</button>
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Cancel</button>
</form>
</script>
@ -596,7 +596,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Back</button>
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Cancel</button>
</form>
</script>
@ -628,7 +628,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<hr />
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Back</button>
<button type="submit">Update</button> &nbsp; <button data-ls-ui-trigger="modal-close" type="button" class="reverse">Cancel</button>
</form>
</script>

View file

@ -55,7 +55,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
</div>
<div data-ls-if="0 != {{project-files.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-files.sum}}"></span> files found</div>
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-files.sum}}"></span> files found</div>
<div class="box margin-bottom">
<table class="vertical">

View file

@ -56,7 +56,7 @@ $auth = $this->getParam('auth', []);
</div>
<div data-ls-if="0 != {{project-users.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-users.sum}}"></span> users found</div>
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-users.sum}}"></span> users found</div>
<div class="box margin-bottom">
<table class="vertical">
@ -223,7 +223,7 @@ $auth = $this->getParam('auth', []);
</div>
<div data-ls-if="0 != {{project-teams.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small"><span data-ls-bind="{{project-teams.sum}}"></span> results found</div>
<div class="margin-bottom-small text-align-end text-size-small text-fade"><span data-ls-bind="{{project-teams.sum}}"></span> teams found</div>
<div class="box margin-bottom">
<table class="vertical">

View file

@ -84,7 +84,7 @@
</div>
<div data-ls-if="0 != {{project-members.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small margin-top-negative"><span data-ls-bind="{{project-members.sum}}"></span> memberships found</div>
<div class="margin-bottom-small margin-end-small text-align-end text-size-small margin-top-negative text-fade"><span data-ls-bind="{{project-members.sum}}"></span> memberships found</div>
<div class="box margin-bottom">
<ul data-ls-loop="project-members.memberships" data-ls-as="member" class="list">

View file

@ -218,7 +218,7 @@
<button class="danger">Logout</button>
</form>
<div class="pull-start margin-end avatar-container">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=120&height=120&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-attrs="src={{env.API}}/avatars/browsers/{{session.clientCode|lowercase}}?width=120&height=120&project={{env.PROJECT}},title={{session.clientName}},alt={{session.clientName}}" class="avatar" loading="lazy" width="60" height="60" />
<div data-ls-if="{{session.provider}} !== 'email'" class="corner">
<img data-ls-attrs="src=/images/users/{{session.provider}}.png?buster=<?php echo APP_CACHE_BUSTER; ?>,title={{session.provider}},alt={{session.provider}}" class="avatar xs" loading="lazy" width="30" height="30" />
@ -228,7 +228,7 @@
<span data-ls-bind="{{session.clientName}}"></span> <span data-ls-bind="{{session.clientVersion}}"></span> on <span data-ls-bind="{{session.deviceModel}}"></span> <span data-ls-bind="{{session.osName}}"></span> <span data-ls-bind="{{session.osVersion}}"></span>
<div class="margin-top-small">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=120&height=120&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-if="{{session.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{session.countryCode}}?width=120&height=120&project={{env.PROJECT}}" class="avatar xxs margin-end-small inline" />
<small data-ls-bind="{{session.ip}}"></small> / <small data-ls-bind="{{session.countryName}}"></small>
</div>
</li>
@ -285,12 +285,12 @@
<td data-title="Date: "><span data-ls-bind="{{log.time|dateTime}}"></span></td>
<td data-title="Event: "><span data-ls-bind="{{log.event}}"></span></td>
<td data-title="Client: ">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="({{log.clientCode}})" data-ls-attrs="src={{env.API}}/avatars/browsers/{{log.clientCode|lowercase}}?width=80&height=80&project={{env.PROJECT}},title={{log.clientName}},alt={{log.clientName}}" class="avatar xxs inline margin-end-small" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-if="({{log.clientCode}})" data-ls-attrs="src={{env.API}}/avatars/browsers/{{log.clientCode|lowercase}}?width=80&height=80&project={{env.PROJECT}},title={{log.clientName}},alt={{log.clientName}}" class="avatar xxs inline margin-end-small" />
<span data-ls-if="({{log.clientName}})" data-ls-bind="{{log.clientName}} {{log.clientVersion}} on {{log.model}} {{log.osName}} {{log.osVersion}}"></span>
<div data-ls-if="(!{{log.clientName}})" class="text-align-center text-fade">Unknown</div>
</td>
<td data-title="Location: ">
<img onerror="this.onerror=null;this.src='/images/unknown.svg'" data-ls-if="{{log.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<img onerror="this.onerror=null;this.className='avatar hide'" data-ls-if="{{log.countryCode}} !== '--'" data-ls-attrs="src={{env.API}}/avatars/flags/{{log.countryCode}}?width=80&height=80&project={{env.PROJECT}}" class="avatar xxs inline margin-end-small" />
<span data-ls-bind="{{log.countryName}}"></span>
</td>
<td data-title="IP: "><span data-ls-bind="{{log.ip}}"></span></td>

View file

@ -9,7 +9,7 @@ $image = $this->getParam('image', '');
services:
traefik:
image: traefik:2.3
image: traefik:2.5
container_name: appwrite-traefik
command:
- --providers.file.directory=/storage/config

View file

@ -20,31 +20,34 @@ class DatabaseV1 extends Worker
public function run(): void
{
Authorization::disable();
$projectId = $this->args['projectId'] ?? '';
$type = $this->args['type'] ?? '';
$collection = $this->args['collection'] ?? [];
$collection = new Document($collection);
$document = $this->args['document'] ?? [];
$document = new Document($document);
Authorization::disable();
if($collection->isEmpty()) {
throw new Exception('Missing collection');
}
if($document->isEmpty()) {
throw new Exception('Missing document');
}
switch (strval($type)) {
case DATABASE_TYPE_CREATE_ATTRIBUTE:
$attribute = $this->args['document'] ?? '';
$attribute = new Document($attribute);
$this->createAttribute($attribute, $projectId);
$this->createAttribute($collection, $document, $projectId);
break;
case DATABASE_TYPE_DELETE_ATTRIBUTE:
$attribute = $this->args['document'] ?? '';
$attribute = new Document($attribute);
$this->deleteAttribute($attribute, $projectId);
$this->deleteAttribute($collection, $document, $projectId);
break;
case DATABASE_TYPE_CREATE_INDEX:
$index = $this->args['document'] ?? '';
$index = new Document($index);
$this->createIndex($index, $projectId);
$this->createIndex($collection, $document, $projectId);
break;
case DATABASE_TYPE_DELETE_INDEX:
$index = $this->args['document'] ?? '';
$index = new Document($index);
$this->deleteIndex($index, $projectId);
$this->deleteIndex($collection, $document, $projectId);
break;
default:
@ -60,76 +63,120 @@ class DatabaseV1 extends Worker
}
/**
* @param Document $collection
* @param Document $attribute
* @param string $projectId
*/
protected function createAttribute($attribute, $projectId): void
protected function createAttribute(Document $collection, Document $attribute, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $attribute->getCollection();
$id = $attribute->getAttribute('$id', '');
$collectionId = $collection->getId();
$key = $attribute->getAttribute('key', '');
$type = $attribute->getAttribute('type', '');
$size = $attribute->getAttribute('size', 0);
$required = $attribute->getAttribute('required', false);
$default = $attribute->getAttribute('default', null);
$signed = $attribute->getAttribute('signed', true);
$array = $attribute->getAttribute('array', false);
$format = $attribute->getAttribute('format', null);
$format = $attribute->getAttribute('format', '');
$formatOptions = $attribute->getAttribute('formatOptions', []);
$filters = $attribute->getAttribute('filters', []);
$success = $dbForExternal->createAttribute($collectionId, $id, $type, $size, $required, $default, $signed, $array, $format, $filters);
if ($success) {
$removed = $dbForExternal->removeAttributeInQueue($collectionId, $id);
try {
if(!$dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) {
throw new Exception('Failed to create Attribute');
}
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
* @param Document $collection
* @param Document $attribute
* @param string $projectId
*/
protected function deleteAttribute($attribute, $projectId): void
protected function deleteAttribute(Document $collection, Document $attribute, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $collection->getId();
$key = $attribute->getAttribute('key', '');
$collectionId = $attribute->getCollection();
$id = $attribute->getAttribute('$id');
try {
if(!$dbForExternal->deleteAttribute($collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$success = $dbForExternal->deleteAttribute($collectionId, $id);
$dbForInternal->deleteDocument('attributes', $attribute->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
* @param Document $collection
* @param Document $index
* @param string $projectId
*/
protected function createIndex($index, $projectId): void
protected function createIndex(Document $collection, Document $index, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $index->getCollection();
$id = $index->getAttribute('$id', '');
$collectionId = $collection->getId();
$key = $index->getAttribute('key', '');
$type = $index->getAttribute('type', '');
$attributes = $index->getAttribute('attributes', []);
$lengths = $index->getAttribute('lengths', []);
$orders = $index->getAttribute('orders', []);
$success = $dbForExternal->createIndex($collectionId, $id, $type, $attributes, $lengths, $orders);
if ($success) {
$dbForExternal->removeIndexInQueue($collectionId, $id);
try {
if(!$dbForExternal->createIndex($collectionId, $key, $type, $attributes, $lengths, $orders)) {
throw new Exception('Failed to create Index');
}
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
* @param Document $collection
* @param Document $index
* @param string $projectId
*/
protected function deleteIndex($index, $projectId): void
protected function deleteIndex(Document $collection, Document $index, string $projectId): void
{
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
$collectionId = $index->getCollection();
$id = $index->getAttribute('$id');
$collectionId = $collection->getId();
$key = $index->getAttribute('key');
$success = $dbForExternal->deleteIndex($collectionId, $id);
try {
if(!$dbForExternal->deleteIndex($collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$dbForInternal->deleteDocument('indexes', $index->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
}

View file

@ -38,14 +38,14 @@
"appwrite/php-clamav": "1.1.*",
"appwrite/php-runtimes": "0.4.*",
"utopia-php/framework": "0.17.*",
"utopia-php/framework": "0.18.*",
"utopia-php/abuse": "0.6.*",
"utopia-php/analytics": "0.2.*",
"utopia-php/audit": "0.6.*",
"utopia-php/cache": "0.4.*",
"utopia-php/cli": "0.11.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.9.*",
"utopia-php/database": "dev-feat-adjusted-query-validator as 0.10.0",
"utopia-php/locale": "0.4.*",
"utopia-php/registry": "0.5.*",
"utopia-php/preloader": "0.2.*",
@ -53,7 +53,7 @@
"utopia-php/swoole": "0.2.*",
"utopia-php/storage": "0.5.*",
"utopia-php/image": "0.5.*",
"resque/php-resque": "1.3.6",
"matomo/device-detector": "4.2.3",
"dragonmantank/cron-expression": "3.1.0",

41
composer.lock generated
View file

@ -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": "6489948fde57f58412fdda5737e5a77e",
"content-hash": "aac413429914bd9299a7ae722f00cef8",
"packages": [
{
"name": "adhocore/jwt",
@ -1984,16 +1984,16 @@
},
{
"name": "utopia-php/database",
"version": "0.9.0",
"version": "dev-feat-adjusted-query-validator",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "f9b1836621df7e14300f1622cb8b8d6fcfedfdaf"
"reference": "cb73391371f70ddb54bc0000064b15c5f173cb7a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/f9b1836621df7e14300f1622cb8b8d6fcfedfdaf",
"reference": "f9b1836621df7e14300f1622cb8b8d6fcfedfdaf",
"url": "https://api.github.com/repos/utopia-php/database/zipball/cb73391371f70ddb54bc0000064b15c5f173cb7a",
"reference": "cb73391371f70ddb54bc0000064b15c5f173cb7a",
"shasum": ""
},
"require": {
@ -2041,9 +2041,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.9.0"
"source": "https://github.com/utopia-php/database/tree/feat-adjusted-query-validator"
},
"time": "2021-08-18T19:08:47+00:00"
"time": "2021-08-23T14:18:47+00:00"
},
{
"name": "utopia-php/domains",
@ -2101,16 +2101,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.17.3",
"version": "0.18.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/framework.git",
"reference": "0274f6b3e49db2af0d702edf278ec7504dc99878"
"reference": "f577522a5eb8009967b893fb7ad4ee70d3f7c0db"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/0274f6b3e49db2af0d702edf278ec7504dc99878",
"reference": "0274f6b3e49db2af0d702edf278ec7504dc99878",
"url": "https://api.github.com/repos/utopia-php/framework/zipball/f577522a5eb8009967b893fb7ad4ee70d3f7c0db",
"reference": "f577522a5eb8009967b893fb7ad4ee70d3f7c0db",
"shasum": ""
},
"require": {
@ -2144,9 +2144,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/framework/issues",
"source": "https://github.com/utopia-php/framework/tree/0.17.3"
"source": "https://github.com/utopia-php/framework/tree/0.18.0"
},
"time": "2021-08-03T13:57:01+00:00"
"time": "2021-08-19T04:58:47+00:00"
},
{
"name": "utopia-php/image",
@ -6254,9 +6254,18 @@
"time": "2015-12-17T08:42:14+00:00"
}
],
"aliases": [],
"aliases": [
{
"package": "utopia-php/database",
"version": "dev-feat-adjusted-query-validator",
"alias": "0.10.0",
"alias_normalized": "0.10.0.0"
}
],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"utopia-php/database": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@ -6278,5 +6287,5 @@
"platform-overrides": {
"php": "8.0"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "2.0.0"
}

View file

@ -7,7 +7,7 @@ version: '3'
services:
traefik:
image: traefik:2.3
image: traefik:2.5
container_name: appwrite-traefik
command:
- --log.level=DEBUG
@ -211,6 +211,7 @@ services:
volumes:
- ./app:/usr/src/code/app
- ./src:/usr/src/code/src
# - ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database
depends_on:
- redis
- mariadb
@ -427,6 +428,8 @@ services:
redis:
image: redis:6.0-alpine
container_name: appwrite-redis
ports:
- "6379:6379"
networks:
- appwrite
volumes:

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.account.create('email@example.com', 'password');
let promise = sdk.account.create('', 'email@example.com', 'password');
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.createDocument('[COLLECTION_ID]', {});
let promise = sdk.database.createDocument('[COLLECTION_ID]', '', {});
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.storage.createFile(document.getElementById('uploader').files[0]);
let promise = sdk.storage.createFile('', document.getElementById('uploader').files[0]);
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.teams.create('[NAME]');
let promise = sdk.teams.create('', '[NAME]');
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.createCollection('', '[NAME]', '', '');
let promise = sdk.database.createCollection('', '[NAME]', 'document', '', '');
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.createUrlAttribute('[COLLECTION_ID]', '', null, false);
let promise = sdk.database.createUrlAttribute('[COLLECTION_ID]', '', false);
promise.then(function (response) {
console.log(response); // Success

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.listCollectionLogs('[COLLECTION_ID]');
let promise = sdk.database.getCollectionLogs('[COLLECTION_ID]');
promise.then(function (response) {
console.log(response); // Success

View file

@ -0,0 +1,14 @@
let sdk = new Appwrite();
sdk
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.listCollectionLogs('[COLLECTION_ID]');
promise.then(function (response) {
console.log(response); // Success
}, function (error) {
console.log(error); // Failure
});

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID
;
let promise = sdk.database.updateCollection('[COLLECTION_ID]', '[NAME]');
let promise = sdk.database.updateCollection('[COLLECTION_ID]', '[NAME]', 'document');
promise.then(function (response) {
console.log(response); // Success

View file

@ -88,22 +88,27 @@ 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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
return uri;}};this.database={listCollections:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(collectionId,name,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createCollection:(collectionId,name,permission,read,write)=>__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"');}
if(typeof permission==='undefined'){throw new AppwriteException('Missing required parameter: "permission"');}
if(typeof read==='undefined'){throw new AppwriteException('Missing required parameter: "read"');}
if(typeof write==='undefined'){throw new AppwriteException('Missing required parameter: "write"');}
let path='/database/collections';let payload={};if(typeof collectionId!=='undefined'){payload['collectionId']=collectionId;}
if(typeof name!=='undefined'){payload['name']=name;}
if(typeof permission!=='undefined'){payload['permission']=permission;}
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':'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)=>__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,permission,read,write)=>__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"');}
if(typeof permission==='undefined'){throw new AppwriteException('Missing required parameter: "permission"');}
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
if(typeof permission!=='undefined'){payload['permission']=permission;}
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);}),deleteCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
@ -156,12 +161,10 @@ if(typeof size!=='undefined'){payload['size']=size;}
if(typeof required!=='undefined'){payload['required']=required;}
if(typeof xdefault!=='undefined'){payload['xdefault']=xdefault;}
if(typeof array!=='undefined'){payload['array']=array;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createUrlAttribute:(collectionId,attributeId,size,required,xdefault,array)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createUrlAttribute:(collectionId,attributeId,required,xdefault,array)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
if(typeof size==='undefined'){throw new AppwriteException('Missing required parameter: "size"');}
if(typeof required==='undefined'){throw new AppwriteException('Missing required parameter: "required"');}
let path='/database/collections/{collectionId}/attributes/url'.replace('{collectionId}',collectionId);let payload={};if(typeof attributeId!=='undefined'){payload['attributeId']=attributeId;}
if(typeof size!=='undefined'){payload['size']=size;}
if(typeof required!=='undefined'){payload['required']=required;}
if(typeof xdefault!=='undefined'){payload['xdefault']=xdefault;}
if(typeof array!=='undefined'){payload['array']=array;}
@ -169,10 +172,11 @@ const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteAttribute:(collectionId,attributeId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,queries,limit,offset,orderAttributes,orderTypes)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,queries,limit,offset,after,orderAttributes,orderTypes)=>__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 queries!=='undefined'){payload['queries']=queries;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof after!=='undefined'){payload['after']=after;}
if(typeof orderAttributes!=='undefined'){payload['orderAttributes']=orderAttributes;}
if(typeof orderTypes!=='undefined'){payload['orderTypes']=orderTypes;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDocument:(collectionId,documentId,data,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
@ -201,14 +205,15 @@ let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}'
if(typeof type!=='undefined'){payload['type']=type;}
if(typeof attributes!=='undefined'){payload['attributes']=attributes;}
if(typeof orders!=='undefined'){payload['orders']=orders;}
console.log(collectionId,indexId,type,attributes,orders);const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
let path='/database/collections/{collectionId}/indexes/{indexId}'.replace('{collectionId}',collectionId).replace('{indexId}',indexId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
let path='/database/collections/{collectionId}/indexes/{indexId}'.replace('{collectionId}',collectionId).replace('{indexId}',indexId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listCollectionLogs:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/logs'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',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;}
let path='/database/collections/{collectionId}/logs'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.functions={list:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(functionId,name,execute,runtime,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"');}
@ -233,9 +238,10 @@ 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(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,limit,offset)=>__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,limit,offset,after)=>__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 limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof after!=='undefined'){payload['after']=after;}
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(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
@ -243,10 +249,11 @@ if(typeof executionId==='undefined'){throw new AppwriteException('Missing requir
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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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"');}
@ -259,9 +266,10 @@ let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionI
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);}),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;}
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);}),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,after,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 after!=='undefined'){payload['after']=after;}
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:(projectId,name,teamId,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"');}
@ -387,9 +395,10 @@ 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(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;}
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,after,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 after!=='undefined'){payload['after']=after;}
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:(fileId,file,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
if(typeof file==='undefined'){throw new AppwriteException('Missing required parameter: "file"');}
@ -421,9 +430,10 @@ 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(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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/teams';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
return uri;}};this.teams={list:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(teamId,name,roles)=>__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"');}
@ -435,10 +445,11 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n
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(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}'.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,after,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 after!=='undefined'){payload['after']=after;}
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"');}
@ -462,9 +473,10 @@ if(typeof userId==='undefined'){throw new AppwriteException('Missing required pa
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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/users';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
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,after,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 after!=='undefined'){payload['after']=after;}
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:(userId,email,password,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
@ -2313,7 +2325,7 @@ return'';}).add("runtimeLogo",function($value,env){if(env&&env.RUNTIMES&&env.RUN
return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.RUNTIMES[$value]){return env.RUNTIMES[$value].version;}
return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '}
return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.$id]){return $value[attribute.$id];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];}
return null;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);}

View file

@ -88,22 +88,27 @@ 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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
return uri;}};this.database={listCollections:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(collectionId,name,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createCollection:(collectionId,name,permission,read,write)=>__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"');}
if(typeof permission==='undefined'){throw new AppwriteException('Missing required parameter: "permission"');}
if(typeof read==='undefined'){throw new AppwriteException('Missing required parameter: "read"');}
if(typeof write==='undefined'){throw new AppwriteException('Missing required parameter: "write"');}
let path='/database/collections';let payload={};if(typeof collectionId!=='undefined'){payload['collectionId']=collectionId;}
if(typeof name!=='undefined'){payload['name']=name;}
if(typeof permission!=='undefined'){payload['permission']=permission;}
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':'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)=>__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,permission,read,write)=>__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"');}
if(typeof permission==='undefined'){throw new AppwriteException('Missing required parameter: "permission"');}
let path='/database/collections/{collectionId}'.replace('{collectionId}',collectionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
if(typeof permission!=='undefined'){payload['permission']=permission;}
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);}),deleteCollection:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
@ -156,12 +161,10 @@ if(typeof size!=='undefined'){payload['size']=size;}
if(typeof required!=='undefined'){payload['required']=required;}
if(typeof xdefault!=='undefined'){payload['xdefault']=xdefault;}
if(typeof array!=='undefined'){payload['array']=array;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createUrlAttribute:(collectionId,attributeId,size,required,xdefault,array)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),createUrlAttribute:(collectionId,attributeId,required,xdefault,array)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
if(typeof size==='undefined'){throw new AppwriteException('Missing required parameter: "size"');}
if(typeof required==='undefined'){throw new AppwriteException('Missing required parameter: "required"');}
let path='/database/collections/{collectionId}/attributes/url'.replace('{collectionId}',collectionId);let payload={};if(typeof attributeId!=='undefined'){payload['attributeId']=attributeId;}
if(typeof size!=='undefined'){payload['size']=size;}
if(typeof required!=='undefined'){payload['required']=required;}
if(typeof xdefault!=='undefined'){payload['xdefault']=xdefault;}
if(typeof array!=='undefined'){payload['array']=array;}
@ -169,10 +172,11 @@ const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteAttribute:(collectionId,attributeId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof attributeId==='undefined'){throw new AppwriteException('Missing required parameter: "attributeId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,queries,limit,offset,orderAttributes,orderTypes)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/attributes/{attributeId}'.replace('{collectionId}',collectionId).replace('{attributeId}',attributeId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDocuments:(collectionId,queries,limit,offset,after,orderAttributes,orderTypes)=>__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 queries!=='undefined'){payload['queries']=queries;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof after!=='undefined'){payload['after']=after;}
if(typeof orderAttributes!=='undefined'){payload['orderAttributes']=orderAttributes;}
if(typeof orderTypes!=='undefined'){payload['orderTypes']=orderTypes;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDocument:(collectionId,documentId,data,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
@ -201,14 +205,15 @@ let path='/database/collections/{collectionId}/indexes'.replace('{collectionId}'
if(typeof type!=='undefined'){payload['type']=type;}
if(typeof attributes!=='undefined'){payload['attributes']=attributes;}
if(typeof orders!=='undefined'){payload['orders']=orders;}
console.log(collectionId,indexId,type,attributes,orders);const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
let path='/database/collections/{collectionId}/indexes/{indexId}'.replace('{collectionId}',collectionId).replace('{indexId}',indexId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteIndex:(collectionId,indexId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
if(typeof indexId==='undefined'){throw new AppwriteException('Missing required parameter: "indexId"');}
let path='/database/collections/{collectionId}/indexes/{indexId}'.replace('{collectionId}',collectionId).replace('{indexId}',indexId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listCollectionLogs:(collectionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/logs'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',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;}
let path='/database/collections/{collectionId}/logs'.replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.functions={list:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(functionId,name,execute,runtime,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"');}
@ -233,9 +238,10 @@ 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(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,limit,offset)=>__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,limit,offset,after)=>__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 limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof after!=='undefined'){payload['after']=after;}
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(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
@ -243,10 +249,11 @@ if(typeof executionId==='undefined'){throw new AppwriteException('Missing requir
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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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"');}
@ -259,9 +266,10 @@ let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionI
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);}),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;}
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);}),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,after,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 after!=='undefined'){payload['after']=after;}
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:(projectId,name,teamId,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"');}
@ -387,9 +395,10 @@ 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(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;}
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,after,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 after!=='undefined'){payload['after']=after;}
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:(fileId,file,read,write)=>__awaiter(this,void 0,void 0,function*(){if(typeof fileId==='undefined'){throw new AppwriteException('Missing required parameter: "fileId"');}
if(typeof file==='undefined'){throw new AppwriteException('Missing required parameter: "file"');}
@ -421,9 +430,10 @@ 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(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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/teams';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
return uri;}};this.teams={list:(search,limit,offset,after,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 after!=='undefined'){payload['after']=after;}
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:(teamId,name,roles)=>__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"');}
@ -435,10 +445,11 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n
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(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}'.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,after,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 after!=='undefined'){payload['after']=after;}
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"');}
@ -462,9 +473,10 @@ if(typeof userId==='undefined'){throw new AppwriteException('Missing required pa
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,offset,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/users';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
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,after,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 after!=='undefined'){payload['after']=after;}
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:(userId,email,password,name)=>__awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}

View file

@ -296,7 +296,7 @@ return'';}).add("runtimeLogo",function($value,env){if(env&&env.RUNTIMES&&env.RUN
return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.RUNTIMES[$value]){return env.RUNTIMES[$value].version;}
return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '}
return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.$id]){return $value[attribute.$id];}
$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];}
return null;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -906,11 +906,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listCollections: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
listCollections: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/database/collections';
let payload = {};
if (typeof search !== 'undefined') {
@ -922,6 +923,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -937,18 +941,22 @@
*
* @param {string} collectionId
* @param {string} name
* @param {string} permission
* @param {string} read
* @param {string} write
* @throws {AppwriteException}
* @returns {Promise}
*/
createCollection: (collectionId, name, read, write) => __awaiter(this, void 0, void 0, function* () {
createCollection: (collectionId, name, permission, read, write) => __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"');
}
if (typeof permission === 'undefined') {
throw new AppwriteException('Missing required parameter: "permission"');
}
if (typeof read === 'undefined') {
throw new AppwriteException('Missing required parameter: "read"');
}
@ -963,6 +971,9 @@
if (typeof name !== 'undefined') {
payload['name'] = name;
}
if (typeof permission !== 'undefined') {
payload['permission'] = permission;
}
if (typeof read !== 'undefined') {
payload['read'] = read;
}
@ -1002,23 +1013,30 @@
*
* @param {string} collectionId
* @param {string} name
* @param {string} permission
* @param {string} read
* @param {string} write
* @throws {AppwriteException}
* @returns {Promise}
*/
updateCollection: (collectionId, name, read, write) => __awaiter(this, void 0, void 0, function* () {
updateCollection: (collectionId, name, permission, read, write) => __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"');
}
if (typeof permission === 'undefined') {
throw new AppwriteException('Missing required parameter: "permission"');
}
let path = '/database/collections/{collectionId}'.replace('{collectionId}', collectionId);
let payload = {};
if (typeof name !== 'undefined') {
payload['name'] = name;
}
if (typeof permission !== 'undefined') {
payload['permission'] = permission;
}
if (typeof read !== 'undefined') {
payload['read'] = read;
}
@ -1345,23 +1363,19 @@
*
* @param {string} collectionId
* @param {string} attributeId
* @param {number} size
* @param {boolean} required
* @param {string} xdefault
* @param {boolean} array
* @throws {AppwriteException}
* @returns {Promise}
*/
createUrlAttribute: (collectionId, attributeId, size, required, xdefault, array) => __awaiter(this, void 0, void 0, function* () {
createUrlAttribute: (collectionId, attributeId, required, xdefault, array) => __awaiter(this, void 0, void 0, function* () {
if (typeof collectionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "collectionId"');
}
if (typeof attributeId === 'undefined') {
throw new AppwriteException('Missing required parameter: "attributeId"');
}
if (typeof size === 'undefined') {
throw new AppwriteException('Missing required parameter: "size"');
}
if (typeof required === 'undefined') {
throw new AppwriteException('Missing required parameter: "required"');
}
@ -1370,9 +1384,6 @@
if (typeof attributeId !== 'undefined') {
payload['attributeId'] = attributeId;
}
if (typeof size !== 'undefined') {
payload['size'] = size;
}
if (typeof required !== 'undefined') {
payload['required'] = required;
}
@ -1445,12 +1456,13 @@
* @param {string[]} queries
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string[]} orderAttributes
* @param {string[]} orderTypes
* @throws {AppwriteException}
* @returns {Promise}
*/
listDocuments: (collectionId, queries, limit, offset, orderAttributes, orderTypes) => __awaiter(this, void 0, void 0, function* () {
listDocuments: (collectionId, queries, limit, offset, after, orderAttributes, orderTypes) => __awaiter(this, void 0, void 0, function* () {
if (typeof collectionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "collectionId"');
}
@ -1465,6 +1477,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderAttributes !== 'undefined') {
payload['orderAttributes'] = orderAttributes;
}
@ -1670,8 +1685,6 @@
if (typeof orders !== 'undefined') {
payload['orders'] = orders;
}
console.log(collectionId, indexId, type, attributes, orders);
const uri = new URL(this.config.endpoint + path);
return yield this.call('post', uri, {
'content-type': 'application/json',
@ -1724,7 +1737,7 @@
}, payload);
}),
/**
* Get Collection Logs
* List Collection Logs
*
* Get the collection activity logs list by its unique ID.
*
@ -1754,11 +1767,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
list: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
list: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/functions';
let payload = {};
if (typeof search !== 'undefined') {
@ -1770,6 +1784,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -1941,10 +1958,11 @@
* @param {string} functionId
* @param {number} limit
* @param {number} offset
* @param {string} after
* @throws {AppwriteException}
* @returns {Promise}
*/
listExecutions: (functionId, limit, offset) => __awaiter(this, void 0, void 0, function* () {
listExecutions: (functionId, limit, offset, after) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
@ -1956,6 +1974,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
@ -2051,11 +2072,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listTags: (functionId, search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
listTags: (functionId, search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
@ -2070,6 +2092,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -2516,11 +2541,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
list: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
list: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/projects';
let payload = {};
if (typeof search !== 'undefined') {
@ -2532,6 +2558,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -3457,11 +3486,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listFiles: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
listFiles: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/storage/files';
let payload = {};
if (typeof search !== 'undefined') {
@ -3473,6 +3503,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -3728,11 +3761,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
list: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
list: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/teams';
let payload = {};
if (typeof search !== 'undefined') {
@ -3744,6 +3778,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -3869,11 +3906,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
getMemberships: (teamId, search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
getMemberships: (teamId, search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
if (typeof teamId === 'undefined') {
throw new AppwriteException('Missing required parameter: "teamId"');
}
@ -3888,6 +3926,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -4088,11 +4129,12 @@
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} after
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
list: (search, limit, offset, orderType) => __awaiter(this, void 0, void 0, function* () {
list: (search, limit, offset, after, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/users';
let payload = {};
if (typeof search !== 'undefined') {
@ -4104,6 +4146,9 @@
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof after !== 'undefined') {
payload['after'] = after;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
@ -4544,4 +4589,4 @@
Object.defineProperty(exports, '__esModule', { value: true });
}(this.window = this.window || {}, null, window));
}(this.window = this.window || {}, null, window));

View file

@ -275,8 +275,8 @@ window.ls.filter
return $value;
})
.add("documentAttribute", function($value, attribute) {
if($value[attribute.$id]) {
return $value[attribute.$id];
if($value[attribute.key]) {
return $value[attribute.key];
}
return null;

View file

@ -20,13 +20,17 @@
z-index: 1;
opacity: 1!important;
&.hide {
display: none;
}
&:before {
content: "";
position: absolute;
// content: "";
// position: absolute;
width: 100%;
height: 100%;
z-index: 0;
background: var(--config-color-background-focus);
// background: var(--config-color-background-focus);
}
&.inline {

View file

@ -783,6 +783,12 @@
"css": "key",
"code": 59479,
"src": "elusive"
},
{
"uid": "3256ef03b16e7ab51235bc7378b53bb5",
"css": "boolean",
"code": 61957,
"src": "fontawesome"
}
]
}

View file

@ -1209,6 +1209,12 @@ ol {
.pull-start;
}
i.avatar {
text-align: center;
background: var(--config-color-dark);
color: var(--config-color-background-fade);
}
&:last-child {
border-bottom: none;
}

File diff suppressed because one or more lines are too long

View file

@ -835,11 +835,7 @@
}
}
.scroll-to {
display: none;
}
@media @desktops {
.logo {
.top {

View file

@ -42,6 +42,7 @@ abstract class Migration
'0.9.1' => 'V08',
'0.9.2' => 'V08',
'0.9.3' => 'V08',
'0.9.4' => 'V08',
'0.10.0' => 'V08', // TODO Eldad: `I need this to pass the tests`
];

View file

@ -91,7 +91,7 @@ class OpenAPI3 extends Format
$usedModels = [];
foreach ($this->routes as $route) { /** @var \Utopia\Route $route */
$url = \str_replace('/v1', '', $route->getURL());
$url = \str_replace('/v1', '', $route->getPath());
$scope = $route->getLabel('scope', '');
$hide = $route->getLabel('sdk.hide', false);
$consumes = [$route->getLabel('sdk.request.type', 'application/json')];

View file

@ -89,7 +89,7 @@ class Swagger2 extends Format
$usedModels = [];
foreach ($this->routes as $route) { /** @var \Utopia\Route $route */
$url = \str_replace('/v1', '', $route->getURL());
$url = \str_replace('/v1', '', $route->getPath());
$scope = $route->getLabel('scope', '');
$hide = $route->getLabel('sdk.hide', false);
$consumes = [$route->getLabel('sdk.request.type', 'application/json')];

View file

@ -10,17 +10,11 @@ class Attribute extends Model
public function __construct()
{
$this
->addRule('$collection', [
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Collection ID.',
'description' => 'Attribute Key.',
'default' => '',
'example' => '5e5ea5c16d55',
])
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Attribute ID.',
'default' => '',
'example' => '60ccf71b98a2d',
'example' => 'fullName',
])
->addRule('type', [
'type' => self::TYPE_STRING,
@ -28,6 +22,12 @@ class Attribute extends Model
'default' => '',
'example' => 'string',
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Attribute status. Possible values: `available`, `processing`, `deleting`, or `failed`',
'default' => '',
'example' => 'available',
])
->addRule('size', [
'type' => self::TYPE_STRING,
'description' => 'Attribute size.',

View file

@ -35,7 +35,13 @@ class Collection extends Model
'type' => self::TYPE_STRING,
'description' => 'Collection name.',
'default' => '',
'example' => '',
'example' => 'My Collection',
])
->addRule('permission', [
'type' => self::TYPE_STRING,
'description' => 'Collection permission model. Possible values: `document` or `collection`',
'default' => '',
'example' => 'document',
])
->addRule('attributes', [
'type' => Response::MODEL_ATTRIBUTE,
@ -51,20 +57,6 @@ class Collection extends Model
'example' => new stdClass,
'array' => true
])
->addRule('attributesInQueue', [
'type' => Response::MODEL_ATTRIBUTE,
'description' => 'Collection attributes in creation queue.',
'default' => [],
'example' => new stdClass,
'array' => true
])
->addRule('indexesInQueue', [
'type' => Response::MODEL_INDEX,
'description' => 'Collection indexes in creation queue.',
'default' => [],
'example' => new stdClass,
'array' => true
])
;
}

View file

@ -43,7 +43,7 @@ class Func extends Model
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Function status. Possible values: disabled, enabled',
'description' => 'Function status. Possible values: `disabled`, `enabled`',
'default' => '',
'example' => 'enabled',
])

View file

@ -10,11 +10,11 @@ class Index extends Model
public function __construct()
{
$this
->addRule('$id', [
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Index ID.',
'description' => 'Index Key.',
'default' => '',
'example' => '',
'example' => 'index1',
])
->addRule('type', [
'type' => self::TYPE_STRING,
@ -22,6 +22,12 @@ class Index extends Model
'default' => '',
'example' => '',
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Index status. Possible values: `available`, `processing`, `deleting`, or `failed`',
'default' => '',
'example' => 'available',
])
->addRule('attributes', [
'type' => self::TYPE_STRING,
'description' => 'Index attributes.',

View file

@ -20,6 +20,7 @@ trait DatabaseBase
'name' => 'Movies',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document',
]);
$this->assertEquals($movies['headers']['status-code'], 201);
@ -43,8 +44,6 @@ trait DatabaseBase
'required' => true,
]);
sleep(2);
$releaseYear = $this->client->call(Client::METHOD_POST, '/database/collections/' . $data['moviesId'] . '/attributes/integer', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
@ -54,8 +53,6 @@ trait DatabaseBase
'required' => true,
]);
sleep(2);
$actors = $this->client->call(Client::METHOD_POST, '/database/collections/' . $data['moviesId'] . '/attributes/string', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
@ -68,26 +65,26 @@ trait DatabaseBase
]);
$this->assertEquals($title['headers']['status-code'], 201);
$this->assertEquals($title['body']['$id'], 'title');
$this->assertEquals($title['body']['key'], 'title');
$this->assertEquals($title['body']['type'], 'string');
$this->assertEquals($title['body']['size'], 256);
$this->assertEquals($title['body']['required'], true);
$this->assertEquals($releaseYear['headers']['status-code'], 201);
$this->assertEquals($releaseYear['body']['$id'], 'releaseYear');
$this->assertEquals($releaseYear['body']['key'], 'releaseYear');
$this->assertEquals($releaseYear['body']['type'], 'integer');
$this->assertEquals($releaseYear['body']['size'], 0);
$this->assertEquals($releaseYear['body']['required'], true);
$this->assertEquals($actors['headers']['status-code'], 201);
$this->assertEquals($actors['body']['$id'], 'actors');
$this->assertEquals($actors['body']['key'], 'actors');
$this->assertEquals($actors['body']['type'], 'string');
$this->assertEquals($actors['body']['size'], 256);
$this->assertEquals($actors['body']['required'], false);
$this->assertEquals($actors['body']['array'], true);
// wait for database worker to create attributes
sleep(5);
sleep(2);
$movies = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'], array_merge([
'content-type' => 'application/json',
@ -95,13 +92,11 @@ trait DatabaseBase
'x-appwrite-key' => $this->getProject()['apiKey']
]), []);
$this->assertIsArray($movies['body']['attributesInQueue']);
$this->assertCount(0, $movies['body']['attributesInQueue']);
$this->assertIsArray($movies['body']['attributes']);
$this->assertCount(3, $movies['body']['attributes']);
$this->assertEquals($movies['body']['attributes'][0]['$id'], $title['body']['$id']);
$this->assertEquals($movies['body']['attributes'][1]['$id'], $releaseYear['body']['$id']);
$this->assertEquals($movies['body']['attributes'][2]['$id'], $actors['body']['$id']);
$this->assertEquals($movies['body']['attributes'][0]['key'], $title['body']['key']);
$this->assertEquals($movies['body']['attributes'][1]['key'], $releaseYear['body']['key']);
$this->assertEquals($movies['body']['attributes'][2]['key'], $actors['body']['key']);
return $data;
}
@ -122,13 +117,13 @@ trait DatabaseBase
]);
$this->assertEquals($titleIndex['headers']['status-code'], 201);
$this->assertEquals($titleIndex['body']['$id'], 'titleIndex');
$this->assertEquals($titleIndex['body']['key'], 'titleIndex');
$this->assertEquals($titleIndex['body']['type'], 'fulltext');
$this->assertCount(1, $titleIndex['body']['attributes']);
$this->assertEquals($titleIndex['body']['attributes'][0], 'title');
// wait for database worker to create index
sleep(5);
sleep(2);
$movies = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'], array_merge([
'content-type' => 'application/json',
@ -138,7 +133,7 @@ trait DatabaseBase
$this->assertIsArray($movies['body']['indexes']);
$this->assertCount(1, $movies['body']['indexes']);
$this->assertEquals($movies['body']['indexes'][0]['$id'], $titleIndex['body']['$id']);
$this->assertEquals($movies['body']['indexes'][0]['key'], $titleIndex['body']['key']);
return $data;
}
@ -243,8 +238,8 @@ trait DatabaseBase
$this->assertCount(1, $document3['body']['$read']);
$this->assertCount(1, $document3['body']['$write']);
$this->assertCount(2, $document3['body']['actors']);
$this->assertEquals($document2['body']['actors'][0], 'Tom Holland');
$this->assertEquals($document2['body']['actors'][1], 'Zendaya Maree Stoermer');
$this->assertEquals($document3['body']['actors'][0], 'Tom Holland');
$this->assertEquals($document3['body']['actors'][1], 'Zendaya Maree Stoermer');
$this->assertEquals($document4['headers']['status-code'], 400);
@ -264,6 +259,7 @@ trait DatabaseBase
'orderTypes' => ['ASC'],
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals(1944, $documents['body']['documents'][0]['releaseYear']);
$this->assertEquals(2017, $documents['body']['documents'][1]['releaseYear']);
$this->assertEquals(2019, $documents['body']['documents'][2]['releaseYear']);
@ -277,6 +273,7 @@ trait DatabaseBase
'orderTypes' => ['DESC'],
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals(1944, $documents['body']['documents'][2]['releaseYear']);
$this->assertEquals(2017, $documents['body']['documents'][1]['releaseYear']);
$this->assertEquals(2019, $documents['body']['documents'][0]['releaseYear']);
@ -298,6 +295,7 @@ trait DatabaseBase
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals($base['headers']['status-code'], 200);
$this->assertEquals('Captain America', $base['body']['documents'][0]['title']);
$this->assertEquals('Spider-Man: Far From Home', $base['body']['documents'][1]['title']);
$this->assertEquals('Spider-Man: Homecoming', $base['body']['documents'][2]['title']);
@ -310,6 +308,7 @@ trait DatabaseBase
'after' => $base['body']['documents'][0]['$id']
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals($base['body']['documents'][1]['$id'], $documents['body']['documents'][0]['$id']);
$this->assertEquals($base['body']['documents'][2]['$id'], $documents['body']['documents'][1]['$id']);
$this->assertCount(2, $documents['body']['documents']);
@ -321,6 +320,7 @@ trait DatabaseBase
'after' => $base['body']['documents'][2]['$id']
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEmpty($documents['body']['documents']);
/**
@ -334,6 +334,7 @@ trait DatabaseBase
'orderTypes' => ['ASC'],
]);
$this->assertEquals($base['headers']['status-code'], 200);
$this->assertEquals(1944, $base['body']['documents'][0]['releaseYear']);
$this->assertEquals(2017, $base['body']['documents'][1]['releaseYear']);
$this->assertEquals(2019, $base['body']['documents'][2]['releaseYear']);
@ -348,6 +349,7 @@ trait DatabaseBase
'after' => $base['body']['documents'][1]['$id']
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals($base['body']['documents'][2]['$id'], $documents['body']['documents'][0]['$id']);
$this->assertCount(1, $documents['body']['documents']);
@ -362,6 +364,7 @@ trait DatabaseBase
'orderTypes' => ['DESC'],
]);
$this->assertEquals($base['headers']['status-code'], 200);
$this->assertEquals(1944, $base['body']['documents'][2]['releaseYear']);
$this->assertEquals(2017, $base['body']['documents'][1]['releaseYear']);
$this->assertEquals(2019, $base['body']['documents'][0]['releaseYear']);
@ -376,6 +379,7 @@ trait DatabaseBase
'after' => $base['body']['documents'][1]['$id']
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals($base['body']['documents'][2]['$id'], $documents['body']['documents'][0]['$id']);
$this->assertCount(1, $documents['body']['documents']);
@ -408,6 +412,7 @@ trait DatabaseBase
'orderTypes' => ['ASC'],
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals(1944, $documents['body']['documents'][0]['releaseYear']);
$this->assertCount(1, $documents['body']['documents']);
@ -421,6 +426,7 @@ trait DatabaseBase
'orderTypes' => ['ASC'],
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals(2017, $documents['body']['documents'][0]['releaseYear']);
$this->assertEquals(2019, $documents['body']['documents'][1]['releaseYear']);
$this->assertCount(2, $documents['body']['documents']);
@ -431,41 +437,46 @@ trait DatabaseBase
/**
* @depends testCreateDocument
*/
public function testDocumentsListSuccessSearch(array $data):array
{
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['title.search("Captain America")'],
]);
// public function testDocumentsListSuccessSearch(array $data):array
// {
// $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'queries' => ['title.search("Captain America")'],
// ]);
$this->assertEquals(1944, $documents['body']['documents'][0]['releaseYear']);
$this->assertCount(1, $documents['body']['documents']);
// var_dump($documents);
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['title.search("Homecoming")'],
]);
// $this->assertEquals($documents['headers']['status-code'], 200);
// $this->assertEquals(1944, $documents['body']['documents'][0]['releaseYear']);
// $this->assertCount(1, $documents['body']['documents']);
$this->assertEquals(2017, $documents['body']['documents'][0]['releaseYear']);
$this->assertCount(1, $documents['body']['documents']);
// $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'queries' => ['title.search("Homecoming")'],
// ]);
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['title.search("spider")'],
]);
// $this->assertEquals($documents['headers']['status-code'], 200);
// $this->assertEquals(2017, $documents['body']['documents'][0]['releaseYear']);
// $this->assertCount(1, $documents['body']['documents']);
$this->assertEquals(2019, $documents['body']['documents'][0]['releaseYear']);
$this->assertEquals(2017, $documents['body']['documents'][1]['releaseYear']);
$this->assertCount(2, $documents['body']['documents']);
// $documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
// 'content-type' => 'application/json',
// 'x-appwrite-project' => $this->getProject()['$id'],
// ], $this->getHeaders()), [
// 'queries' => ['title.search("spider")'],
// ]);
return [];
}
// $this->assertEquals($documents['headers']['status-code'], 200);
// $this->assertEquals(2019, $documents['body']['documents'][0]['releaseYear']);
// $this->assertEquals(2017, $documents['body']['documents'][1]['releaseYear']);
// $this->assertCount(2, $documents['body']['documents']);
// return [];
// }
// TODO@kodumbeats test for empty searches and misformatted queries
/**
@ -626,6 +637,7 @@ trait DatabaseBase
'name' => 'invalidDocumentStructure',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document',
]);
$this->assertEquals(201, $collection['headers']['status-code']);
@ -742,7 +754,7 @@ trait DatabaseBase
// $this->assertEquals('Minimum value must be lesser than maximum value', $invalidRange['body']['message']);
// wait for worker to add attributes
sleep(15);
sleep(2);
$collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $collectionId, array_merge([
'content-type' => 'application/json',
@ -751,7 +763,6 @@ trait DatabaseBase
]), []);
$this->assertCount(7, $collection['body']['attributes']);
// $this->assertCount(0, $collection['body']['attributesInQueue']);
/**
* Test for successful validation
@ -937,7 +948,6 @@ trait DatabaseBase
'write' => ['user:'.$this->getUser()['$id']],
]);
$this->assertEquals(400, $badEmail['headers']['status-code']);
$this->assertEquals(400, $badIp['headers']['status-code']);
$this->assertEquals(400, $badUrl['headers']['status-code']);
@ -950,8 +960,8 @@ trait DatabaseBase
$this->assertEquals('Invalid document structure: Attribute "url" has invalid format. Value must be a valid URL', $badUrl['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "range" has invalid format. Value must be a valid range between 1 and 10', $badRange['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "floatRange" has invalid format. Value must be a valid range between 1 and 1', $badFloatRange['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "upperBound" has invalid format. Value must be a valid range between inf and 10', $tooHigh['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "lowerBound" has invalid format. Value must be a valid range between 5 and inf', $tooLow['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "upperBound" has invalid format. Value must be a valid range between -9,223,372,036,854,775,808 and 10', $tooHigh['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "lowerBound" has invalid format. Value must be a valid range between 5 and 9,223,372,036,854,775,808', $tooLow['body']['message']);
}
/**

View file

@ -27,6 +27,7 @@ class DatabaseCustomServerTest extends Scope
'collectionId' => 'first',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document'
]);
$test2 = $this->client->call(Client::METHOD_POST, '/database/collections', array_merge([
@ -38,6 +39,7 @@ class DatabaseCustomServerTest extends Scope
'collectionId' => 'second',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document'
]);
$collections = $this->client->call(Client::METHOD_GET, '/database/collections', array_merge([
@ -109,6 +111,7 @@ class DatabaseCustomServerTest extends Scope
'name' => 'Actors',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document'
]);
$this->assertEquals($actors['headers']['status-code'], 201);
@ -145,7 +148,7 @@ class DatabaseCustomServerTest extends Scope
]);
// Wait for database worker to finish creating attributes
sleep(5);
sleep(2);
$index = $this->client->call(Client::METHOD_POST, '/database/collections/' . $actors['body']['$id'] . '/indexes', array_merge([
'content-type' => 'application/json',
@ -160,7 +163,7 @@ class DatabaseCustomServerTest extends Scope
]);
// Wait for database worker to finish creating index
sleep(5);
sleep(2);
$collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $actors['body']['$id'], array_merge([
'content-type' => 'application/json',
@ -168,24 +171,27 @@ class DatabaseCustomServerTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey']
]), []);
$unneededId = $unneeded['body']['$id'];
$unneededId = $unneeded['body']['key'];
$this->assertEquals($collection['headers']['status-code'], 200);
$this->assertIsArray($collection['body']['attributes']);
$this->assertCount(3, $collection['body']['attributes']);
$this->assertEquals($collection['body']['attributes'][0]['$id'], $firstName['body']['$id']);
$this->assertEquals($collection['body']['attributes'][1]['$id'], $lastName['body']['$id']);
$this->assertEquals($collection['body']['attributes'][2]['$id'], $unneeded['body']['$id']);
$this->assertEquals($collection['body']['attributes'][0]['key'], $firstName['body']['key']);
$this->assertEquals($collection['body']['attributes'][1]['key'], $lastName['body']['key']);
$this->assertEquals($collection['body']['attributes'][2]['key'], $unneeded['body']['key']);
$this->assertCount(1, $collection['body']['indexes']);
$this->assertEquals($collection['body']['indexes'][0]['$id'], $index['body']['$id']);
$this->assertEquals($collection['body']['indexes'][0]['key'], $index['body']['key']);
// Delete attribute
$this->client->call(Client::METHOD_DELETE, '/database/collections/' . $actors ['body']['$id'] . '/attributes/' . $unneededId, array_merge([
$attribute = $this->client->call(Client::METHOD_DELETE, '/database/collections/' . $actors ['body']['$id'] . '/attributes/' . $unneededId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
sleep(5);
$this->assertEquals($attribute['headers']['status-code'], 204);
sleep(2);
$collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $actors['body']['$id'], array_merge([
'content-type' => 'application/json',
@ -193,16 +199,18 @@ class DatabaseCustomServerTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey']
]), []);
$this->assertEquals($collection['headers']['status-code'], 200);
$this->assertIsArray($collection['body']['attributes']);
$this->assertCount(2, $collection['body']['attributes']);
$this->assertEquals($collection['body']['attributes'][0]['$id'], $firstName['body']['$id']);
$this->assertEquals($collection['body']['attributes'][1]['$id'], $lastName['body']['$id']);
$this->assertEquals($collection['body']['attributes'][0]['key'], $firstName['body']['key']);
$this->assertEquals($collection['body']['attributes'][1]['key'], $lastName['body']['key']);
return [
'collectionId' => $actors['body']['$id'],
'indexId' => $index['body']['$id'],
'indexId' => $index['body']['key'],
];
}
/**
* @depends testDeleteAttribute
*/
@ -214,14 +222,16 @@ class DatabaseCustomServerTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals($index['headers']['status-code'], 204);
// Wait for database worker to finish deleting index
sleep(5);
sleep(2);
$collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['collectionId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), []);
]), []);
$this->assertCount(0, $collection['body']['indexes']);

View file

@ -21,6 +21,7 @@ trait WebhooksBase
'name' => 'Actors',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document',
]);
$this->assertEquals($actors['headers']['status-code'], 201);
@ -72,9 +73,9 @@ trait WebhooksBase
]);
$this->assertEquals($firstName['headers']['status-code'], 201);
$this->assertEquals($firstName['body']['$id'], 'firstName');
$this->assertEquals($firstName['body']['key'], 'firstName');
$this->assertEquals($lastName['headers']['status-code'], 201);
$this->assertEquals($lastName['body']['$id'], 'lastName');
$this->assertEquals($lastName['body']['key'], 'lastName');
// wait for database worker to kick in
sleep(10);
@ -88,8 +89,8 @@ trait WebhooksBase
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
$this->assertNotEmpty($webhook['data']['$id']);
$this->assertEquals($webhook['data']['$id'], 'lastName');
$this->assertNotEmpty($webhook['data']['key']);
$this->assertEquals($webhook['data']['key'], 'lastName');
// TODO@kodumbeats test webhook for removing attribute

View file

@ -28,6 +28,7 @@ class WebhooksCustomServerTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Actors1',
'permission' => 'document',
]);
$this->assertEquals($actors['headers']['status-code'], 200);
@ -70,7 +71,7 @@ class WebhooksCustomServerTest extends Scope
]);
$this->assertEquals($index['headers']['status-code'], 201);
$this->assertEquals($index['body']['$id'], 'fullname');
$this->assertEquals($index['body']['key'], 'fullname');
// wait for database worker to create index
sleep(5);
@ -125,6 +126,7 @@ class WebhooksCustomServerTest extends Scope
'name' => 'Demo',
'read' => ['role:all'],
'write' => ['role:all'],
'permission' => 'document'
]);
$this->assertEquals($actors['headers']['status-code'], 201);