mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 08:58:35 +00:00
Merge remote-tracking branch 'origin/0.16.x' into feat-sdk-version-bump
# Conflicts: # app/config/platforms.php
This commit is contained in:
commit
13fa712cc5
63 changed files with 1826 additions and 2358 deletions
14
CHANGES.md
14
CHANGES.md
|
|
@ -12,6 +12,20 @@
|
|||
- `createExecution` parameter `async` default value was changed from `true` to `false` [#3781](https://github.com/appwrite/appwrite/pull/3781)
|
||||
- String attribute `status` has been refactored to a Boolean attribute `enabled` in the functions collection [#3798](https://github.com/appwrite/appwrite/pull/3798)
|
||||
- `time` attribute in Execution response model has been reanamed to `duration` to be more consistent with other response models. [#3801](https://github.com/appwrite/appwrite/pull/3801)
|
||||
- Renamed the following list endpoints to stay consistent with other endpoints [#3825](https://github.com/appwrite/appwrite/pull/3825)
|
||||
- `getMemberships` to `listMemberships` in Teams API
|
||||
- `getMemberships` to `listMemberships` in Users API
|
||||
- `getLogs` to `listLogs` in Users API
|
||||
- `getLogs` to `listLogs` in Accounts API
|
||||
- `getSessions` to `listSessions` in Accounts API
|
||||
- `getSessions` to `listSessions` in Users API
|
||||
- `getCountries` to `listCountries` in Locale API
|
||||
- `getCountriesEU` to `listCountriesEU` in Locale API
|
||||
- `getCountriesPhones` to `listCountriesPhones` in Locale API
|
||||
- `getContinents` to `listContinents` in Locale API
|
||||
- `getCurrencies` to `listCurrencies` in Locale API
|
||||
- `getLanguages` to `listLanguages` in Locale API
|
||||
|
||||
|
||||
## Features
|
||||
- Added the UI to see the Parent ID of all resources within the UI. [#3653](https://github.com/appwrite/appwrite/pull/3653)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/config/specs/open-api3-1.0.0-client.json
Normal file
1
app/config/specs/open-api3-1.0.0-client.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/open-api3-1.0.0-console.json
Normal file
1
app/config/specs/open-api3-1.0.0-console.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/open-api3-1.0.0-server.json
Normal file
1
app/config/specs/open-api3-1.0.0-server.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/config/specs/swagger2-1.0.0-client.json
Normal file
1
app/config/specs/swagger2-1.0.0-client.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/swagger2-1.0.0-console.json
Normal file
1
app/config/specs/swagger2-1.0.0-console.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/swagger2-1.0.0-server.json
Normal file
1
app/config/specs/swagger2-1.0.0-server.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1311,14 +1311,14 @@ App::get('/v1/account/prefs')
|
|||
});
|
||||
|
||||
App::get('/v1/account/sessions')
|
||||
->desc('Get Account Sessions')
|
||||
->desc('List Account Sessions')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'account')
|
||||
->label('usage.metric', 'users.{scope}.requests.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'getSessions')
|
||||
->label('sdk.description', '/docs/references/account/get-sessions.md')
|
||||
->label('sdk.method', 'listSessions')
|
||||
->label('sdk.description', '/docs/references/account/list-sessions.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION_LIST)
|
||||
|
|
@ -1346,14 +1346,14 @@ App::get('/v1/account/sessions')
|
|||
});
|
||||
|
||||
App::get('/v1/account/logs')
|
||||
->desc('Get Account Logs')
|
||||
->desc('List Account Logs')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'account')
|
||||
->label('usage.metric', 'users.{scope}.requests.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'getLogs')
|
||||
->label('sdk.description', '/docs/references/account/get-logs.md')
|
||||
->label('sdk.method', 'listLogs')
|
||||
->label('sdk.description', '/docs/references/account/list-logs.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LOG_LIST)
|
||||
|
|
|
|||
|
|
@ -1941,7 +1941,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
|
||||
try {
|
||||
$document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), new Document($data));
|
||||
$document->setAttribute('$collection', $collectionId);
|
||||
$document->setAttribute('$collectionId', $collectionId);
|
||||
$document->setAttribute('$databaseId', $databaseId);
|
||||
} catch (StructureException $exception) {
|
||||
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
|
||||
} catch (DuplicateException $exception) {
|
||||
|
|
@ -2046,7 +2047,11 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
|||
/**
|
||||
* Reset $collection attribute to remove prefix.
|
||||
*/
|
||||
$documents = array_map(fn(Document $document) => $document->setAttribute('$collection', $collectionId), $documents);
|
||||
$documents = array_map(function (Document $document) use ($collectionId, $databaseId) {
|
||||
$document->setAttribute('$collectionId', $collectionId);
|
||||
$document->setAttribute('$databaseId', $databaseId);
|
||||
return $document;
|
||||
}, $documents);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $total,
|
||||
|
|
@ -2110,7 +2115,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
|||
/**
|
||||
* Reset $collection attribute to remove prefix.
|
||||
*/
|
||||
$document->setAttribute('$collection', $collectionId);
|
||||
$document->setAttribute('$collectionId', $collectionId);
|
||||
$document->setAttribute('$databaseId', $databaseId);
|
||||
|
||||
$response->dynamic($document, Response::MODEL_DOCUMENT);
|
||||
});
|
||||
|
|
@ -2329,7 +2335,8 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
|||
/**
|
||||
* Reset $collection attribute to remove prefix.
|
||||
*/
|
||||
$document->setAttribute('$collection', $collectionId);
|
||||
$document->setAttribute('$collectionId', $collectionId);
|
||||
$document->setAttribute('$databaseId', $databaseId);
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
} catch (DuplicateException) {
|
||||
|
|
@ -2421,7 +2428,8 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
|||
/**
|
||||
* Reset $collection attribute to remove prefix.
|
||||
*/
|
||||
$document->setAttribute('$collection', $collectionId);
|
||||
$document->setAttribute('$collectionId', $collectionId);
|
||||
$document->setAttribute('$databaseId', $databaseId);
|
||||
|
||||
$deletes
|
||||
->setType(DELETE_TYPE_AUDIT)
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ App::get('/v1/locale/countries')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getCountries')
|
||||
->label('sdk.description', '/docs/references/locale/get-countries.md')
|
||||
->label('sdk.method', 'listCountries')
|
||||
->label('sdk.description', '/docs/references/locale/list-countries.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
|
||||
|
|
@ -104,8 +104,8 @@ App::get('/v1/locale/countries/eu')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getCountriesEU')
|
||||
->label('sdk.description', '/docs/references/locale/get-countries-eu.md')
|
||||
->label('sdk.method', 'listCountriesEU')
|
||||
->label('sdk.description', '/docs/references/locale/list-countries-eu.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_COUNTRY_LIST)
|
||||
|
|
@ -137,8 +137,8 @@ App::get('/v1/locale/countries/phones')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getCountriesPhones')
|
||||
->label('sdk.description', '/docs/references/locale/get-countries-phones.md')
|
||||
->label('sdk.method', 'listCountriesPhones')
|
||||
->label('sdk.description', '/docs/references/locale/list-countries-phones.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PHONE_LIST)
|
||||
|
|
@ -169,8 +169,8 @@ App::get('/v1/locale/continents')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getContinents')
|
||||
->label('sdk.description', '/docs/references/locale/get-continents.md')
|
||||
->label('sdk.method', 'listContinents')
|
||||
->label('sdk.description', '/docs/references/locale/list-continents.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_CONTINENT_LIST)
|
||||
|
|
@ -199,8 +199,8 @@ App::get('/v1/locale/currencies')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getCurrencies')
|
||||
->label('sdk.description', '/docs/references/locale/get-currencies.md')
|
||||
->label('sdk.method', 'listCurrencies')
|
||||
->label('sdk.description', '/docs/references/locale/list-currencies.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_CURRENCY_LIST)
|
||||
|
|
@ -220,8 +220,8 @@ App::get('/v1/locale/languages')
|
|||
->label('scope', 'locale.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'locale')
|
||||
->label('sdk.method', 'getLanguages')
|
||||
->label('sdk.description', '/docs/references/locale/get-languages.md')
|
||||
->label('sdk.method', 'listLanguages')
|
||||
->label('sdk.description', '/docs/references/locale/list-languages.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LANGUAGE_LIST)
|
||||
|
|
|
|||
|
|
@ -463,13 +463,13 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
});
|
||||
|
||||
App::get('/v1/teams/:teamId/memberships')
|
||||
->desc('Get Team Memberships')
|
||||
->desc('List Team Memberships')
|
||||
->groups(['api', 'teams'])
|
||||
->label('scope', 'teams.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
->label('sdk.method', 'getMemberships')
|
||||
->label('sdk.description', '/docs/references/teams/get-team-members.md')
|
||||
->label('sdk.method', 'listMemberships')
|
||||
->label('sdk.description', '/docs/references/teams/list-team-members.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
|
|
|
|||
|
|
@ -449,14 +449,14 @@ App::get('/v1/users/:userId/prefs')
|
|||
});
|
||||
|
||||
App::get('/v1/users/:userId/sessions')
|
||||
->desc('Get User Sessions')
|
||||
->desc('List User Sessions')
|
||||
->groups(['api', 'users'])
|
||||
->label('scope', 'users.read')
|
||||
->label('usage.metric', 'users.{scope}.requests.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'users')
|
||||
->label('sdk.method', 'getSessions')
|
||||
->label('sdk.description', '/docs/references/users/get-user-sessions.md')
|
||||
->label('sdk.method', 'listSessions')
|
||||
->label('sdk.description', '/docs/references/users/list-user-sessions.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION_LIST)
|
||||
|
|
@ -491,14 +491,14 @@ App::get('/v1/users/:userId/sessions')
|
|||
});
|
||||
|
||||
App::get('/v1/users/:userId/memberships')
|
||||
->desc('Get User Memberships')
|
||||
->desc('List User Memberships')
|
||||
->groups(['api', 'users'])
|
||||
->label('scope', 'users.read')
|
||||
->label('usage.metric', 'users.{scope}.requests.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'users')
|
||||
->label('sdk.method', 'getMemberships')
|
||||
->label('sdk.description', '/docs/references/users/get-user-memberships.md')
|
||||
->label('sdk.method', 'listMemberships')
|
||||
->label('sdk.description', '/docs/references/users/list-user-memberships.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
|
|
@ -531,14 +531,14 @@ App::get('/v1/users/:userId/memberships')
|
|||
});
|
||||
|
||||
App::get('/v1/users/:userId/logs')
|
||||
->desc('Get User Logs')
|
||||
->desc('List User Logs')
|
||||
->groups(['api', 'users'])
|
||||
->label('scope', 'users.read')
|
||||
->label('usage.metric', 'users.{scope}.requests.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'users')
|
||||
->label('sdk.method', 'getLogs')
|
||||
->label('sdk.description', '/docs/references/users/get-user-logs.md')
|
||||
->label('sdk.method', 'listLogs')
|
||||
->label('sdk.description', '/docs/references/users/list-user-logs.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_LOG_LIST)
|
||||
|
|
|
|||
|
|
@ -325,9 +325,9 @@ App::get('/console/databases/document')
|
|||
->label('permission', 'public')
|
||||
->label('scope', 'console')
|
||||
->param('databaseId', '', new UID(), 'Database unique ID.')
|
||||
->param('collection', '', new UID(), 'Collection unique ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID.')
|
||||
->inject('layout')
|
||||
->action(function (string $databaseId, string $collection, View $layout) {
|
||||
->action(function (string $databaseId, string $collectionId, View $layout) {
|
||||
|
||||
$logs = new View(__DIR__ . '/../../views/console/comps/logs.phtml');
|
||||
$logs
|
||||
|
|
@ -335,7 +335,7 @@ App::get('/console/databases/document')
|
|||
->setParam('method', 'databases.listDocumentLogs')
|
||||
->setParam('params', [
|
||||
'database-id' => '{{router.params.databaseId}}',
|
||||
'collection-id' => '{{router.params.collection}}',
|
||||
'collection-id' => '{{router.params.collectionId}}',
|
||||
'document-id' => '{{router.params.id}}',
|
||||
])
|
||||
;
|
||||
|
|
@ -352,7 +352,7 @@ App::get('/console/databases/document')
|
|||
Database::PERMISSION_DELETE,
|
||||
])
|
||||
->setParam('params', [
|
||||
'collection-id' => '{{router.params.collection}}',
|
||||
'collection-id' => '{{router.params.collectionId}}',
|
||||
'database-id' => '{{router.params.databaseId}}',
|
||||
'document-id' => '{{router.params.id}}',
|
||||
]);
|
||||
|
|
@ -362,7 +362,7 @@ App::get('/console/databases/document')
|
|||
$page
|
||||
->setParam('new', false)
|
||||
->setParam('database', $databaseId)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('collection', $collectionId)
|
||||
->setParam('permissions', $permissions)
|
||||
->setParam('logs', $logs)
|
||||
;
|
||||
|
|
@ -377,9 +377,9 @@ App::get('/console/databases/document/new')
|
|||
->label('permission', 'public')
|
||||
->label('scope', 'console')
|
||||
->param('databaseId', '', new UID(), 'Database unique ID.')
|
||||
->param('collection', '', new UID(), 'Collection unique ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID.')
|
||||
->inject('layout')
|
||||
->action(function (string $databaseId, string $collection, View $layout) {
|
||||
->action(function (string $databaseId, string $collectionId, View $layout) {
|
||||
|
||||
$permissions = new View(__DIR__ . '/../../views/console/comps/permissions-matrix.phtml');
|
||||
|
||||
|
|
@ -392,7 +392,7 @@ App::get('/console/databases/document/new')
|
|||
Database::PERMISSION_DELETE,
|
||||
])
|
||||
->setParam('params', [
|
||||
'collection-id' => '{{router.params.collection}}',
|
||||
'collection-id' => '{{router.params.collectionId}}',
|
||||
'database-id' => '{{router.params.databaseId}}',
|
||||
'document-id' => '{{router.params.id}}',
|
||||
]);
|
||||
|
|
@ -402,7 +402,7 @@ App::get('/console/databases/document/new')
|
|||
$page
|
||||
->setParam('new', true)
|
||||
->setParam('database', $databaseId)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('collection', $collectionId)
|
||||
->setParam('permissions', $permissions)
|
||||
->setParam('logs', new View())
|
||||
;
|
||||
|
|
|
|||
27
app/http.php
27
app/http.php
|
|
@ -38,8 +38,7 @@ $http
|
|||
'http_compression_level' => 6,
|
||||
'package_max_length' => $payloadSize,
|
||||
'buffer_output_size' => $payloadSize,
|
||||
])
|
||||
;
|
||||
]);
|
||||
|
||||
$http->on('WorkerStart', function ($server, $workerId) {
|
||||
Console::success('Worker ' . ++$workerId . ' started successfully');
|
||||
|
|
@ -81,13 +80,16 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
}
|
||||
} while ($attempts < $max);
|
||||
|
||||
App::setResource('db', fn() => $db);
|
||||
App::setResource('cache', fn() => $redis);
|
||||
App::setResource('db', fn () => $db);
|
||||
App::setResource('cache', fn () => $redis);
|
||||
|
||||
$dbForConsole = $app->getResource('dbForConsole'); /** @var Utopia\Database\Database $dbForConsole */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
$dbForConsole = $app->getResource('dbForConsole');
|
||||
|
||||
Console::success('[Setup] - Server database init started...');
|
||||
$collections = Config::getParam('collections', []); /** @var array $collections */
|
||||
|
||||
/** @var array $collections */
|
||||
$collections = Config::getParam('collections', []);
|
||||
|
||||
if (!$dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'))) {
|
||||
$redis->flushAll();
|
||||
|
|
@ -122,9 +124,9 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
continue;
|
||||
}
|
||||
/**
|
||||
* Skip to prevent 0.15 migration issues.
|
||||
* Skip to prevent 0.16 migration issues.
|
||||
*/
|
||||
if ($key === 'databases' && $dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), 'collections')) {
|
||||
if (in_array($key, ['cache', 'variables']) && $dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), 'bucket_1')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +162,7 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
$dbForConsole->createCollection($key, $attributes, $indexes);
|
||||
}
|
||||
|
||||
if ($dbForConsole->getDocument('buckets', 'default')->isEmpty()) {
|
||||
if ($dbForConsole->getDocument('buckets', 'default')->isEmpty() && !$dbForConsole->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), 'bucket_1')) {
|
||||
Console::success('[Setup] - Creating default bucket...');
|
||||
$dbForConsole->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('default'),
|
||||
|
|
@ -244,8 +246,7 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
|||
->setContentType(Files::getFileMimeType($request->getURI()))
|
||||
->addHeader('Cache-Control', 'public, max-age=' . $time)
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $time) . ' GMT') // 45 days cache
|
||||
->send(Files::getFileContents($request->getURI()))
|
||||
;
|
||||
->send(Files::getFileContents($request->getURI()));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -255,8 +256,8 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
|||
$db = $register->get('dbPool')->get();
|
||||
$redis = $register->get('redisPool')->get();
|
||||
|
||||
App::setResource('db', fn() => $db);
|
||||
App::setResource('cache', fn() => $redis);
|
||||
App::setResource('db', fn () => $db);
|
||||
App::setResource('cache', fn () => $redis);
|
||||
|
||||
try {
|
||||
Authorization::cleanRoles();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use Utopia\Validator\Text;
|
|||
|
||||
$cli
|
||||
->task('migrate')
|
||||
->param('version', APP_VERSION_STABLE, new Text(8), 'Version to migrate to.', true)
|
||||
->param('version', APP_VERSION_STABLE, new Text(32), 'Version to migrate to.', true)
|
||||
->action(function ($version) use ($register) {
|
||||
Authorization::disable();
|
||||
if (!array_key_exists($version, Migration::$versions)) {
|
||||
|
|
@ -45,6 +45,9 @@ $cli
|
|||
$limit = 30;
|
||||
$sum = 30;
|
||||
$offset = 0;
|
||||
/**
|
||||
* @var \Utopia\Database\Document[] $projects
|
||||
*/
|
||||
$projects = [$console];
|
||||
$count = 0;
|
||||
|
||||
|
|
@ -60,6 +63,13 @@ $cli
|
|||
|
||||
while (!empty($projects)) {
|
||||
foreach ($projects as $project) {
|
||||
/**
|
||||
* Skip user projects with id 'console'
|
||||
*/
|
||||
if ($project->getId() === 'console' && $project->getInternalId() !== 'console') {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$migration
|
||||
->setProject($project, $projectDB, $consoleDB)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ $cli
|
|||
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
|
||||
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
|
||||
|
||||
if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.0-RC1', 'latest'])) {
|
||||
if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.0', 'latest'])) {
|
||||
throw new Exception('Unknown version given');
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|||
->setTwitter(APP_SOCIAL_TWITTER_HANDLE)
|
||||
->setDiscord(APP_SOCIAL_DISCORD_CHANNEL, APP_SOCIAL_DISCORD)
|
||||
->setDefaultHeaders([
|
||||
'X-Appwrite-Response-Format' => '1.0.0-RC1',
|
||||
'X-Appwrite-Response-Format' => '1.0.0',
|
||||
]);
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@
|
|||
<h2>Sessions</h2>
|
||||
|
||||
<div class="box margin-bottom"
|
||||
data-service="account.getSessions"
|
||||
data-service="account.listSessions"
|
||||
data-scope="console"
|
||||
data-name="sessions"
|
||||
data-event="load,account.deleteRemoteSession">
|
||||
|
|
@ -298,7 +298,7 @@
|
|||
<h2>Activity</h2>
|
||||
|
||||
<div
|
||||
data-service="account.getLogs"
|
||||
data-service="account.listLogs"
|
||||
data-scope="console"
|
||||
data-param-queries="limit(<?php echo APP_PAGING_LIMIT; ?>),offset({{router.params.offset|orZero}})"
|
||||
data-param-queries-cast-to="array"
|
||||
|
|
@ -340,7 +340,7 @@
|
|||
</div>
|
||||
<div class="pull-end text-align-center paging">
|
||||
<form
|
||||
data-service="account.getLogs"
|
||||
data-service="account.listLogs"
|
||||
data-event="submit"
|
||||
data-scope="console"
|
||||
data-name="securityLogs"
|
||||
|
|
@ -353,7 +353,7 @@
|
|||
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{securityLogs.total|pageTotal}}"></span>
|
||||
|
||||
<form
|
||||
data-service="account.getLogs"
|
||||
data-service="account.listLogs"
|
||||
data-event="submit"
|
||||
data-scope="console"
|
||||
data-name="securityLogs"
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ $permissions = $this->getParam('permissions', null);
|
|||
<template x-for="doc in documents">
|
||||
<tr>
|
||||
<td data-title="$id: ">
|
||||
<a :href="`/console/databases/document?id=${doc.$id}&collection=${doc.$collection}&databaseId=${databaseId}&project=${project}`" x-text="doc.$id"></a>
|
||||
<a :href="`/console/databases/document?id=${doc.$id}&collectionId=${doc.$collectionId}&databaseId=${databaseId}&project=${project}`" x-text="doc.$id"></a>
|
||||
</td>
|
||||
<template x-for="attr in attributes">
|
||||
<td x-show="attr.status === 'available'" :data-title="attr.key + ':'">
|
||||
<a :href="`/console/databases/document?id=${doc.$id}&collection=${doc.$collection}&databaseId=${databaseId}&project=${project}`">
|
||||
<a :href="`/console/databases/document?id=${doc.$id}&collectionId=${doc.$collectionId}&databaseId=${databaseId}&project=${project}`">
|
||||
<span x-text="doc[attr.key] ?? 'n/a'"></span>
|
||||
</a>
|
||||
</td>
|
||||
|
|
@ -136,7 +136,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<a data-ls-if="0 < {{project-collection.attributes.length}}" data-ls-attrs="href=/console/databases/document/new?collection={{router.params.id}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}" class="button">
|
||||
<a data-ls-if="0 < {{project-collection.attributes.length}}" data-ls-attrs="href=/console/databases/document/new?collectionId={{router.params.id}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}" class="button">
|
||||
Add Document
|
||||
</a>
|
||||
<a data-ls-if="!{{project-collection.attributes.length}}" data-ls-attrs="href=/console/databases/collection/attributes?id={{router.params.id}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}" class="button">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
?>
|
||||
<div
|
||||
data-service="databases.getCollection"
|
||||
data-param-collection-id="{{router.params.collection}}"
|
||||
data-param-collection-id="{{router.params.collectionId}}"
|
||||
data-param-database-id="{{router.params.databaseId}}"
|
||||
data-scope="sdk"
|
||||
data-event="load,databases.updateDocument"
|
||||
|
|
@ -15,7 +15,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
|
||||
<div
|
||||
data-service="databases.getDocument"
|
||||
data-param-collection-id="{{router.params.collection}}"
|
||||
data-param-collection-id="{{router.params.collectionId}}"
|
||||
data-param-database-id="{{router.params.databaseId}}"
|
||||
data-param-document-id="{{router.params.id}}"
|
||||
data-scope="sdk"
|
||||
|
|
@ -25,7 +25,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
|
||||
<div class="cover">
|
||||
<h1 class="zone xl margin-bottom-large">
|
||||
<a data-ls-attrs="href=/console/databases/collection?id={{router.params.collection}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> <span data-ls-bind="{{project-collection.name}}"></span></a>
|
||||
<a data-ls-attrs="href=/console/databases/collection?id={{router.params.collectionId}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> <span data-ls-bind="{{project-collection.name}}"></span></a>
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
|
||||
<div class="zone xl margin-bottom-no">
|
||||
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
|
||||
<li data-state="/console/databases/document?id={{router.params.id}}&collection={{router.params.collection}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}">
|
||||
<li data-state="/console/databases/document?id={{router.params.id}}&collectionId={{router.params.collectionId}}&databaseId={{router.params.databaseId}}&project={{router.params.project}}">
|
||||
<h2 class="margin-bottom">Overview</h2>
|
||||
|
||||
<div class="row responsive">
|
||||
|
|
@ -362,7 +362,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
|
||||
<label>Collection ID</label>
|
||||
<div class="input-copy margin-bottom">
|
||||
<input type="text" autocomplete="off" placeholder="" data-ls-bind="{{router.params.collection}}" disabled data-forms-copy class="margin-bottom-no" />
|
||||
<input type="text" autocomplete="off" placeholder="" data-ls-bind="{{router.params.collectionId}}" disabled data-forms-copy class="margin-bottom-no" />
|
||||
</div>
|
||||
|
||||
<label>Database ID</label>
|
||||
|
|
@ -395,13 +395,13 @@ $permissions = $this->getParam('permissions', null);
|
|||
data-service="databases.deleteDocument"
|
||||
data-event="submit"
|
||||
data-param-database-id="{{router.params.databaseId}}"
|
||||
data-param-collection-id="{{router.params.collection}}"
|
||||
data-param-collection-id="{{router.params.collectionId}}"
|
||||
data-param-document-id="{{project-document.$id}}"
|
||||
data-confirm="Are you sure you want to delete this document?"
|
||||
data-success="alert,trigger,redirect"
|
||||
data-success-param-alert-text="Document deleted successfully"
|
||||
data-success-param-trigger-events="databases.deleteDocument"
|
||||
data-success-param-redirect-url="/console/databases/collection?id={{router.params.collection}}&project={{router.params.project}}&databaseId={{router.params.databaseId}}"
|
||||
data-success-param-redirect-url="/console/databases/collection?id={{router.params.collectionId}}&project={{router.params.project}}&databaseId={{router.params.databaseId}}"
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to delete collection"
|
||||
data-failure-param-alert-classname="error">
|
||||
|
|
@ -413,7 +413,7 @@ $permissions = $this->getParam('permissions', null);
|
|||
</div>
|
||||
</li>
|
||||
<?php if(!$new): ?>
|
||||
<li data-state="/console/databases/document/activity?id={{router.params.id}}&collection={{router.params.collection}}&project={{router.params.project}}&databaseId={{router.params.databaseId}}">
|
||||
<li data-state="/console/databases/document/activity?id={{router.params.id}}&collectionId={{router.params.collectionId}}&project={{router.params.project}}&databaseId={{router.params.databaseId}}">
|
||||
<h2>Activity</h2>
|
||||
|
||||
<?php echo $logs->render(); ?>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ $array = $this->getParam('array', false);
|
|||
|
||||
<?php if($parent): ?>
|
||||
<input name="documentId" type="hidden" data-ls-bind="{{router.params.id}}" />
|
||||
<input name="collectionId" type="hidden" data-ls-bind="{{router.params.collection}}" />
|
||||
<input name="collectionId" type="hidden" data-ls-bind="{{router.params.collectionId}}" />
|
||||
<?php else: ?>
|
||||
<?php /*<div class="margin-bottom-small text-size-small" data-ls-if="({{<?php echo $this->escape($namespace); ?>.$id}})">
|
||||
<span data-ls-bind="Document #{{<?php echo $this->escape($namespace); ?>.$id}}"></span>
|
||||
|
|
|
|||
|
|
@ -378,13 +378,13 @@ $smtpEnabled = $this->getParam('smtpEnabled', false);
|
|||
<h2>Members</h2>
|
||||
|
||||
<div class="zone xl"
|
||||
data-service="teams.getMemberships"
|
||||
data-service="teams.listMemberships"
|
||||
data-scope="console"
|
||||
data-event="load,teams.createMembership,teams.deleteMembership,teams.createMembership.resent"
|
||||
data-name="members"
|
||||
data-param-team-id="{{console-project.teamId}}"
|
||||
data-success="trigger"
|
||||
data-success-param-trigger-events="teams.getMemberships">
|
||||
data-success-param-trigger-events="teams.listMemberships">
|
||||
|
||||
<div class="box margin-bottom">
|
||||
<ul data-ls-loop="members.memberships" data-ls-as="member" class="list">
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
<h3 class="margin-bottom">Members</h3>
|
||||
|
||||
<div
|
||||
data-service="teams.getMemberships"
|
||||
data-service="teams.listMemberships"
|
||||
data-event="load,teams.create,teams.update,teams.delete,teams.deleteMembership,teams.createMembership"
|
||||
data-param-team-id="{{router.params.id}}"
|
||||
data-param-queries="limit(<?php echo APP_PAGING_LIMIT; ?>),offset({{router.params.offset|orZero}}),orderDesc('')"
|
||||
|
|
@ -168,7 +168,7 @@
|
|||
|
||||
<div class="clear text-align-center paging pull-end">
|
||||
<form
|
||||
data-service="teams.getMemberships"
|
||||
data-service="teams.listMemberships"
|
||||
data-event="submit"
|
||||
data-param-team-id="{{router.params.id}}"
|
||||
data-param-search="{{router.params.search}}"
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{project-members.total|pageTotal}}"></span>
|
||||
|
||||
<form
|
||||
data-service="teams.getMemberships"
|
||||
data-service="teams.listMemberships"
|
||||
data-event="submit"
|
||||
data-param-team-id="{{router.params.id}}"
|
||||
data-param-search="{{router.params.search}}"
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@
|
|||
<h2>Memberships</h2>
|
||||
|
||||
<div
|
||||
data-service="users.getMemberships"
|
||||
data-service="users.listMemberships"
|
||||
data-name="memberships"
|
||||
data-param-user-id="{{router.params.id}}"
|
||||
data-event="load,users.update,teams.deleteMembership">
|
||||
|
|
@ -493,7 +493,7 @@
|
|||
<h2>Sessions</h2>
|
||||
|
||||
<div
|
||||
data-service="users.getSessions"
|
||||
data-service="users.listSessions"
|
||||
data-name="sessions"
|
||||
data-param-user-id="{{router.params.id}}"
|
||||
data-event="load,users.update">
|
||||
|
|
@ -570,7 +570,7 @@
|
|||
<h2>Activity</h2>
|
||||
|
||||
<div
|
||||
data-service="users.getLogs"
|
||||
data-service="users.listLogs"
|
||||
data-name="logs"
|
||||
data-param-user-id="{{router.params.id}}"
|
||||
data-event="load,logs-load">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
bootstrap="app/init.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
|
|
|
|||
52
public/dist/scripts/app-all.js
vendored
52
public/dist/scripts/app-all.js
vendored
|
|
@ -12,7 +12,7 @@ Service.CHUNK_SIZE=5*1024*1024;class Query{}
|
|||
Query.equal=(attribute,value)=>Query.addQuery(attribute,"equal",value);Query.notEqual=(attribute,value)=>Query.addQuery(attribute,"notEqual",value);Query.lessThan=(attribute,value)=>Query.addQuery(attribute,"lessThan",value);Query.lessThanEqual=(attribute,value)=>Query.addQuery(attribute,"lessThanEqual",value);Query.greaterThan=(attribute,value)=>Query.addQuery(attribute,"greaterThan",value);Query.greaterThanEqual=(attribute,value)=>Query.addQuery(attribute,"greaterThanEqual",value);Query.search=(attribute,value)=>Query.addQuery(attribute,"search",value);Query.orderDesc=(attribute)=>`orderDesc("${attribute}")`;Query.orderAsc=(attribute)=>`orderAsc("${attribute}")`;Query.cursorAfter=(documentId)=>`cursorAfter("${documentId}")`;Query.cursorBefore=(documentId)=>`cursorBefore("${documentId}")`;Query.limit=(limit)=>`limit(${limit})`;Query.offset=(offset)=>`offset(${offset})`;Query.addQuery=(attribute,method,value)=>value instanceof Array?`${method}("${attribute}", [${value
|
||||
.map((v) => Query.parseValues(v))
|
||||
.join(",")}])`:`${method}("${attribute}", [${Query.parseValues(value)}])`;Query.parseValues=(value)=>typeof value==="string"||value instanceof String?`"${value}"`:`${value}`;class AppwriteException extends Error{constructor(message,code=0,type='',response=''){super(message);this.name='AppwriteException';this.message=message;this.code=code;this.type=type;this.response=response;}}
|
||||
class Client{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-name':'Console','x-sdk-platform':'console','x-sdk-language':'web','x-sdk-version':'6.1.0-RC1','X-Appwrite-Response-Format':'1.0.0-RC1',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1)
|
||||
class Client{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-name':'Console','x-sdk-platform':'console','x-sdk-language':'web','x-sdk-version':'7.0.0','X-Appwrite-Response-Format':'1.0.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1)
|
||||
return;const channels=new URLSearchParams();channels.set('project',this.config.project);this.realtime.channels.forEach(channel=>{channels.append('channels[]',channel);});const url=this.config.endpointRealtime+'/realtime?'+channels.toString();if(url!==this.realtime.url||!this.realtime.socket||((_a=this.realtime.socket)===null||_a===void 0?void 0:_a.readyState)>WebSocket.OPEN){if(this.realtime.socket&&((_b=this.realtime.socket)===null||_b===void 0?void 0:_b.readyState)<WebSocket.CLOSING){this.realtime.reconnect=false;this.realtime.socket.close();}
|
||||
this.realtime.url=url;this.realtime.socket=new WebSocket(url);this.realtime.socket.addEventListener('message',this.realtime.onMessage);this.realtime.socket.addEventListener('open',_event=>{this.realtime.reconnectAttempts=0;});this.realtime.socket.addEventListener('close',event=>{var _a,_b,_c;if(!this.realtime.reconnect||(((_b=(_a=this.realtime)===null||_a===void 0?void 0:_a.lastMessage)===null||_b===void 0?void 0:_b.type)==='error'&&((_c=this.realtime)===null||_c===void 0?void 0:_c.lastMessage.data).code===1008)){this.realtime.reconnect=true;return;}
|
||||
const timeout=this.realtime.getTimeout();console.error(`Realtime got disconnected. Reconnect will be attempted in ${timeout / 1000} seconds.`,event.reason);setTimeout(()=>{this.realtime.reconnectAttempts++;this.realtime.createSocket();},timeout);});}},onMessage:(event)=>{var _a,_b;try{const message=JSON.parse(event.data);this.realtime.lastMessage=message;switch(message.type){case'connected':const cookie=JSON.parse((_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'{}');const session=cookie===null||cookie===void 0?void 0:cookie[`a_session_${this.config.project}`];const messageData=message.data;if(session&&!messageData.user){(_b=this.realtime.socket)===null||_b===void 0?void 0:_b.send(JSON.stringify({type:'authentication',data:{session}}));}
|
||||
|
|
@ -56,7 +56,7 @@ let path='/account/email';let payload={};if(typeof email!=='undefined'){payload[
|
|||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
createJWT(){return __awaiter(this,void 0,void 0,function*(){let path='/account/jwt';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
getLogs(queries){return __awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
listLogs(queries){return __awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateName(name){return __awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/account/name';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
|
|
@ -88,7 +88,7 @@ if(typeof secret!=='undefined'){payload['secret']=secret;}
|
|||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof passwordAgain!=='undefined'){payload['passwordAgain']=passwordAgain;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('put',uri,{'content-type':'application/json',},payload);});}
|
||||
getSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
deleteSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
createAnonymousSession(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions/anonymous';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
createEmailSession(email,password){return __awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
|
|
@ -174,10 +174,9 @@ if(typeof width!=='undefined'){payload['width']=width;}
|
|||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
const uri=new URL(this.client.config.endpoint+path);payload['project']=this.client.config.project;for(const[key,value]of Object.entries(Service.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}
|
||||
getInitials(name,width,height,color,background){let path='/avatars/initials';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
getInitials(name,width,height,background){let path='/avatars/initials';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof color!=='undefined'){payload['color']=color;}
|
||||
if(typeof background!=='undefined'){payload['background']=background;}
|
||||
const uri=new URL(this.client.config.endpoint+path);payload['project']=this.client.config.project;for(const[key,value]of Object.entries(Service.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}
|
||||
|
|
@ -214,8 +213,6 @@ const uri=new URL(this.client.config.endpoint+path);return yield this.client.cal
|
|||
createCollection(databaseId,collectionId,name,permissions,documentSecurity){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof permissions==='undefined'){throw new AppwriteException('Missing required parameter: "permissions"');}
|
||||
if(typeof documentSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "documentSecurity"');}
|
||||
let path='/databases/{databaseId}/collections'.replace('{databaseId}',databaseId);let payload={};if(typeof collectionId!=='undefined'){payload['collectionId']=collectionId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
|
|
@ -224,10 +221,9 @@ const uri=new URL(this.client.config.endpoint+path);return yield this.client.cal
|
|||
getCollection(databaseId,collectionId){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/databases/{databaseId}/collections/{collectionId}'.replace('{databaseId}',databaseId).replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateCollection(databaseId,collectionId,name,documentSecurity,permissions,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
updateCollection(databaseId,collectionId,name,permissions,documentSecurity,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof documentSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "documentSecurity"');}
|
||||
let path='/databases/{databaseId}/collections/{collectionId}'.replace('{databaseId}',databaseId).replace('{collectionId}',collectionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
if(typeof documentSecurity!=='undefined'){payload['documentSecurity']=documentSecurity;}
|
||||
|
|
@ -406,7 +402,7 @@ class Functions extends Service{constructor(client){super(client);}
|
|||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
create(functionId,name,execute,runtime,events,schedule,timeout){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
create(functionId,name,execute,runtime,events,schedule,timeout,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
if(typeof runtime==='undefined'){throw new AppwriteException('Missing required parameter: "runtime"');}
|
||||
|
|
@ -417,13 +413,14 @@ if(typeof runtime!=='undefined'){payload['runtime']=runtime;}
|
|||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
if(typeof enabled!=='undefined'){payload['enabled']=enabled;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
listRuntimes(){return __awaiter(this,void 0,void 0,function*(){let path='/functions/runtimes';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getUsage(range){return __awaiter(this,void 0,void 0,function*(){let path='/functions/usage';let payload={};if(typeof range!=='undefined'){payload['range']=range;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
get(functionId){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
update(functionId,name,execute,events,schedule,timeout){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
update(functionId,name,execute,events,schedule,timeout,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
|
|
@ -431,6 +428,7 @@ if(typeof execute!=='undefined'){payload['execute']=execute;}
|
|||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
if(typeof enabled!=='undefined'){payload['enabled']=enabled;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('put',uri,{'content-type':'application/json',},payload);});}
|
||||
delete(functionId){return __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.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
@ -478,10 +476,8 @@ let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId
|
|||
getFunctionUsage(functionId,range){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listVariables(functionId,queries,search){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/variables'.replace('{functionId}',functionId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listVariables(functionId){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/variables'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
createVariable(functionId,key,value){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof key==='undefined'){throw new AppwriteException('Missing required parameter: "key"');}
|
||||
if(typeof value==='undefined'){throw new AppwriteException('Missing required parameter: "value"');}
|
||||
|
|
@ -513,12 +509,12 @@ getStorageLocal(){return __awaiter(this,void 0,void 0,function*(){let path='/hea
|
|||
getTime(){return __awaiter(this,void 0,void 0,function*(){let path='/health/time';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
class Locale extends Service{constructor(client){super(client);}
|
||||
get(){return __awaiter(this,void 0,void 0,function*(){let path='/locale';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getContinents(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountries(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountriesEU(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountriesPhones(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCurrencies(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getLanguages(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
listContinents(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountries(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountriesEU(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountriesPhones(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCurrencies(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listLanguages(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
class Projects extends Service{constructor(client){super(client);}
|
||||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
|
|
@ -685,9 +681,8 @@ class Storage extends Service{constructor(client){super(client);}
|
|||
listBuckets(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/storage/buckets';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
createBucket(bucketId,name,fileSecurity,permissions,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
createBucket(bucketId,name,permissions,fileSecurity,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof fileSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "fileSecurity"');}
|
||||
let path='/storage/buckets';let payload={};if(typeof bucketId!=='undefined'){payload['bucketId']=bucketId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
|
|
@ -701,9 +696,8 @@ if(typeof antivirus!=='undefined'){payload['antivirus']=antivirus;}
|
|||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
getBucket(bucketId){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
let path='/storage/buckets/{bucketId}'.replace('{bucketId}',bucketId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateBucket(bucketId,name,fileSecurity,permissions,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
updateBucket(bucketId,name,permissions,fileSecurity,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof fileSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "fileSecurity"');}
|
||||
let path='/storage/buckets/{bucketId}'.replace('{bucketId}',bucketId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
if(typeof fileSecurity!=='undefined'){payload['fileSecurity']=fileSecurity;}
|
||||
|
|
@ -793,7 +787,7 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n
|
|||
listLogs(teamId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}/logs'.replace('{teamId}',teamId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getMemberships(teamId,queries,search){return __awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
listMemberships(teamId,queries,search){return __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 queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
@ -919,10 +913,10 @@ updateEmail(userId,email){return __awaiter(this,void 0,void 0,function*(){if(typ
|
|||
if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
let path='/users/{userId}/email'.replace('{userId}',userId);let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
getLogs(userId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listLogs(userId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/logs'.replace('{userId}',userId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getMemberships(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listMemberships(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/memberships'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateName(userId,name){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
|
|
@ -942,7 +936,7 @@ updatePrefs(userId,prefs){return __awaiter(this,void 0,void 0,function*(){if(typ
|
|||
if(typeof prefs==='undefined'){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
let path='/users/{userId}/prefs'.replace('{userId}',userId);let payload={};if(typeof prefs!=='undefined'){payload['prefs']=prefs;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
getSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
deleteSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
|
|||
52
public/dist/scripts/app-dep.js
vendored
52
public/dist/scripts/app-dep.js
vendored
|
|
@ -12,7 +12,7 @@ Service.CHUNK_SIZE=5*1024*1024;class Query{}
|
|||
Query.equal=(attribute,value)=>Query.addQuery(attribute,"equal",value);Query.notEqual=(attribute,value)=>Query.addQuery(attribute,"notEqual",value);Query.lessThan=(attribute,value)=>Query.addQuery(attribute,"lessThan",value);Query.lessThanEqual=(attribute,value)=>Query.addQuery(attribute,"lessThanEqual",value);Query.greaterThan=(attribute,value)=>Query.addQuery(attribute,"greaterThan",value);Query.greaterThanEqual=(attribute,value)=>Query.addQuery(attribute,"greaterThanEqual",value);Query.search=(attribute,value)=>Query.addQuery(attribute,"search",value);Query.orderDesc=(attribute)=>`orderDesc("${attribute}")`;Query.orderAsc=(attribute)=>`orderAsc("${attribute}")`;Query.cursorAfter=(documentId)=>`cursorAfter("${documentId}")`;Query.cursorBefore=(documentId)=>`cursorBefore("${documentId}")`;Query.limit=(limit)=>`limit(${limit})`;Query.offset=(offset)=>`offset(${offset})`;Query.addQuery=(attribute,method,value)=>value instanceof Array?`${method}("${attribute}", [${value
|
||||
.map((v) => Query.parseValues(v))
|
||||
.join(",")}])`:`${method}("${attribute}", [${Query.parseValues(value)}])`;Query.parseValues=(value)=>typeof value==="string"||value instanceof String?`"${value}"`:`${value}`;class AppwriteException extends Error{constructor(message,code=0,type='',response=''){super(message);this.name='AppwriteException';this.message=message;this.code=code;this.type=type;this.response=response;}}
|
||||
class Client{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-name':'Console','x-sdk-platform':'console','x-sdk-language':'web','x-sdk-version':'6.1.0-RC1','X-Appwrite-Response-Format':'1.0.0-RC1',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1)
|
||||
class Client{constructor(){this.config={endpoint:'https://HOSTNAME/v1',endpointRealtime:'',project:'',key:'',jwt:'',locale:'',mode:'',};this.headers={'x-sdk-name':'Console','x-sdk-platform':'console','x-sdk-language':'web','x-sdk-version':'7.0.0','X-Appwrite-Response-Format':'1.0.0',};this.realtime={socket:undefined,timeout:undefined,url:'',channels:new Set(),subscriptions:new Map(),subscriptionsCounter:0,reconnect:true,reconnectAttempts:0,lastMessage:undefined,connect:()=>{clearTimeout(this.realtime.timeout);this.realtime.timeout=window===null||window===void 0?void 0:window.setTimeout(()=>{this.realtime.createSocket();},50);},getTimeout:()=>{switch(true){case this.realtime.reconnectAttempts<5:return 1000;case this.realtime.reconnectAttempts<15:return 5000;case this.realtime.reconnectAttempts<100:return 10000;default:return 60000;}},createSocket:()=>{var _a,_b;if(this.realtime.channels.size<1)
|
||||
return;const channels=new URLSearchParams();channels.set('project',this.config.project);this.realtime.channels.forEach(channel=>{channels.append('channels[]',channel);});const url=this.config.endpointRealtime+'/realtime?'+channels.toString();if(url!==this.realtime.url||!this.realtime.socket||((_a=this.realtime.socket)===null||_a===void 0?void 0:_a.readyState)>WebSocket.OPEN){if(this.realtime.socket&&((_b=this.realtime.socket)===null||_b===void 0?void 0:_b.readyState)<WebSocket.CLOSING){this.realtime.reconnect=false;this.realtime.socket.close();}
|
||||
this.realtime.url=url;this.realtime.socket=new WebSocket(url);this.realtime.socket.addEventListener('message',this.realtime.onMessage);this.realtime.socket.addEventListener('open',_event=>{this.realtime.reconnectAttempts=0;});this.realtime.socket.addEventListener('close',event=>{var _a,_b,_c;if(!this.realtime.reconnect||(((_b=(_a=this.realtime)===null||_a===void 0?void 0:_a.lastMessage)===null||_b===void 0?void 0:_b.type)==='error'&&((_c=this.realtime)===null||_c===void 0?void 0:_c.lastMessage.data).code===1008)){this.realtime.reconnect=true;return;}
|
||||
const timeout=this.realtime.getTimeout();console.error(`Realtime got disconnected. Reconnect will be attempted in ${timeout / 1000} seconds.`,event.reason);setTimeout(()=>{this.realtime.reconnectAttempts++;this.realtime.createSocket();},timeout);});}},onMessage:(event)=>{var _a,_b;try{const message=JSON.parse(event.data);this.realtime.lastMessage=message;switch(message.type){case'connected':const cookie=JSON.parse((_a=window.localStorage.getItem('cookieFallback'))!==null&&_a!==void 0?_a:'{}');const session=cookie===null||cookie===void 0?void 0:cookie[`a_session_${this.config.project}`];const messageData=message.data;if(session&&!messageData.user){(_b=this.realtime.socket)===null||_b===void 0?void 0:_b.send(JSON.stringify({type:'authentication',data:{session}}));}
|
||||
|
|
@ -56,7 +56,7 @@ let path='/account/email';let payload={};if(typeof email!=='undefined'){payload[
|
|||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
createJWT(){return __awaiter(this,void 0,void 0,function*(){let path='/account/jwt';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
getLogs(queries){return __awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
listLogs(queries){return __awaiter(this,void 0,void 0,function*(){let path='/account/logs';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateName(name){return __awaiter(this,void 0,void 0,function*(){if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
let path='/account/name';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
|
|
@ -88,7 +88,7 @@ if(typeof secret!=='undefined'){payload['secret']=secret;}
|
|||
if(typeof password!=='undefined'){payload['password']=password;}
|
||||
if(typeof passwordAgain!=='undefined'){payload['passwordAgain']=passwordAgain;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('put',uri,{'content-type':'application/json',},payload);});}
|
||||
getSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
deleteSessions(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
createAnonymousSession(){return __awaiter(this,void 0,void 0,function*(){let path='/account/sessions/anonymous';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
createEmailSession(email,password){return __awaiter(this,void 0,void 0,function*(){if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
|
|
@ -174,10 +174,9 @@ if(typeof width!=='undefined'){payload['width']=width;}
|
|||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
const uri=new URL(this.client.config.endpoint+path);payload['project']=this.client.config.project;for(const[key,value]of Object.entries(Service.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}
|
||||
getInitials(name,width,height,color,background){let path='/avatars/initials';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
getInitials(name,width,height,background){let path='/avatars/initials';let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof width!=='undefined'){payload['width']=width;}
|
||||
if(typeof height!=='undefined'){payload['height']=height;}
|
||||
if(typeof color!=='undefined'){payload['color']=color;}
|
||||
if(typeof background!=='undefined'){payload['background']=background;}
|
||||
const uri=new URL(this.client.config.endpoint+path);payload['project']=this.client.config.project;for(const[key,value]of Object.entries(Service.flatten(payload))){uri.searchParams.append(key,value);}
|
||||
return uri;}
|
||||
|
|
@ -214,8 +213,6 @@ const uri=new URL(this.client.config.endpoint+path);return yield this.client.cal
|
|||
createCollection(databaseId,collectionId,name,permissions,documentSecurity){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof permissions==='undefined'){throw new AppwriteException('Missing required parameter: "permissions"');}
|
||||
if(typeof documentSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "documentSecurity"');}
|
||||
let path='/databases/{databaseId}/collections'.replace('{databaseId}',databaseId);let payload={};if(typeof collectionId!=='undefined'){payload['collectionId']=collectionId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
|
|
@ -224,10 +221,9 @@ const uri=new URL(this.client.config.endpoint+path);return yield this.client.cal
|
|||
getCollection(databaseId,collectionId){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
let path='/databases/{databaseId}/collections/{collectionId}'.replace('{databaseId}',databaseId).replace('{collectionId}',collectionId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateCollection(databaseId,collectionId,name,documentSecurity,permissions,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
updateCollection(databaseId,collectionId,name,permissions,documentSecurity,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof databaseId==='undefined'){throw new AppwriteException('Missing required parameter: "databaseId"');}
|
||||
if(typeof collectionId==='undefined'){throw new AppwriteException('Missing required parameter: "collectionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof documentSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "documentSecurity"');}
|
||||
let path='/databases/{databaseId}/collections/{collectionId}'.replace('{databaseId}',databaseId).replace('{collectionId}',collectionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
if(typeof documentSecurity!=='undefined'){payload['documentSecurity']=documentSecurity;}
|
||||
|
|
@ -406,7 +402,7 @@ class Functions extends Service{constructor(client){super(client);}
|
|||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
create(functionId,name,execute,runtime,events,schedule,timeout){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
create(functionId,name,execute,runtime,events,schedule,timeout,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
if(typeof runtime==='undefined'){throw new AppwriteException('Missing required parameter: "runtime"');}
|
||||
|
|
@ -417,13 +413,14 @@ if(typeof runtime!=='undefined'){payload['runtime']=runtime;}
|
|||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
if(typeof enabled!=='undefined'){payload['enabled']=enabled;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
listRuntimes(){return __awaiter(this,void 0,void 0,function*(){let path='/functions/runtimes';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getUsage(range){return __awaiter(this,void 0,void 0,function*(){let path='/functions/usage';let payload={};if(typeof range!=='undefined'){payload['range']=range;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
get(functionId){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
update(functionId,name,execute,events,schedule,timeout){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
update(functionId,name,execute,events,schedule,timeout,enabled){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof execute==='undefined'){throw new AppwriteException('Missing required parameter: "execute"');}
|
||||
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
|
|
@ -431,6 +428,7 @@ if(typeof execute!=='undefined'){payload['execute']=execute;}
|
|||
if(typeof events!=='undefined'){payload['events']=events;}
|
||||
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
|
||||
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
|
||||
if(typeof enabled!=='undefined'){payload['enabled']=enabled;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('put',uri,{'content-type':'application/json',},payload);});}
|
||||
delete(functionId){return __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.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
@ -478,10 +476,8 @@ let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId
|
|||
getFunctionUsage(functionId,range){return __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.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listVariables(functionId,queries,search){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/variables'.replace('{functionId}',functionId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listVariables(functionId){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
let path='/functions/{functionId}/variables'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
createVariable(functionId,key,value){return __awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
|
||||
if(typeof key==='undefined'){throw new AppwriteException('Missing required parameter: "key"');}
|
||||
if(typeof value==='undefined'){throw new AppwriteException('Missing required parameter: "value"');}
|
||||
|
|
@ -513,12 +509,12 @@ getStorageLocal(){return __awaiter(this,void 0,void 0,function*(){let path='/hea
|
|||
getTime(){return __awaiter(this,void 0,void 0,function*(){let path='/health/time';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
class Locale extends Service{constructor(client){super(client);}
|
||||
get(){return __awaiter(this,void 0,void 0,function*(){let path='/locale';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getContinents(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountries(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountriesEU(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCountriesPhones(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getCurrencies(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getLanguages(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
listContinents(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/continents';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountries(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountriesEU(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/eu';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCountriesPhones(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/countries/phones';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listCurrencies(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/currencies';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
listLanguages(){return __awaiter(this,void 0,void 0,function*(){let path='/locale/languages';let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}}
|
||||
class Projects extends Service{constructor(client){super(client);}
|
||||
list(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/projects';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
|
|
@ -685,9 +681,8 @@ class Storage extends Service{constructor(client){super(client);}
|
|||
listBuckets(queries,search){return __awaiter(this,void 0,void 0,function*(){let path='/storage/buckets';let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
createBucket(bucketId,name,fileSecurity,permissions,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
createBucket(bucketId,name,permissions,fileSecurity,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof fileSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "fileSecurity"');}
|
||||
let path='/storage/buckets';let payload={};if(typeof bucketId!=='undefined'){payload['bucketId']=bucketId;}
|
||||
if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
|
|
@ -701,9 +696,8 @@ if(typeof antivirus!=='undefined'){payload['antivirus']=antivirus;}
|
|||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('post',uri,{'content-type':'application/json',},payload);});}
|
||||
getBucket(bucketId){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
let path='/storage/buckets/{bucketId}'.replace('{bucketId}',bucketId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateBucket(bucketId,name,fileSecurity,permissions,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
updateBucket(bucketId,name,permissions,fileSecurity,enabled,maximumFileSize,allowedFileExtensions,compression,encryption,antivirus){return __awaiter(this,void 0,void 0,function*(){if(typeof bucketId==='undefined'){throw new AppwriteException('Missing required parameter: "bucketId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
if(typeof fileSecurity==='undefined'){throw new AppwriteException('Missing required parameter: "fileSecurity"');}
|
||||
let path='/storage/buckets/{bucketId}'.replace('{bucketId}',bucketId);let payload={};if(typeof name!=='undefined'){payload['name']=name;}
|
||||
if(typeof permissions!=='undefined'){payload['permissions']=permissions;}
|
||||
if(typeof fileSecurity!=='undefined'){payload['fileSecurity']=fileSecurity;}
|
||||
|
|
@ -793,7 +787,7 @@ let path='/teams/{teamId}'.replace('{teamId}',teamId);let payload={};const uri=n
|
|||
listLogs(teamId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
let path='/teams/{teamId}/logs'.replace('{teamId}',teamId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getMemberships(teamId,queries,search){return __awaiter(this,void 0,void 0,function*(){if(typeof teamId==='undefined'){throw new AppwriteException('Missing required parameter: "teamId"');}
|
||||
listMemberships(teamId,queries,search){return __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 queries!=='undefined'){payload['queries']=queries;}
|
||||
if(typeof search!=='undefined'){payload['search']=search;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
@ -919,10 +913,10 @@ updateEmail(userId,email){return __awaiter(this,void 0,void 0,function*(){if(typ
|
|||
if(typeof email==='undefined'){throw new AppwriteException('Missing required parameter: "email"');}
|
||||
let path='/users/{userId}/email'.replace('{userId}',userId);let payload={};if(typeof email!=='undefined'){payload['email']=email;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
getLogs(userId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listLogs(userId,queries){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/logs'.replace('{userId}',userId);let payload={};if(typeof queries!=='undefined'){payload['queries']=queries;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
getMemberships(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listMemberships(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/memberships'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
updateName(userId,name){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
if(typeof name==='undefined'){throw new AppwriteException('Missing required parameter: "name"');}
|
||||
|
|
@ -942,7 +936,7 @@ updatePrefs(userId,prefs){return __awaiter(this,void 0,void 0,function*(){if(typ
|
|||
if(typeof prefs==='undefined'){throw new AppwriteException('Missing required parameter: "prefs"');}
|
||||
let path='/users/{userId}/prefs'.replace('{userId}',userId);let payload={};if(typeof prefs!=='undefined'){payload['prefs']=prefs;}
|
||||
const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('patch',uri,{'content-type':'application/json',},payload);});}
|
||||
getSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
listSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('get',uri,{'content-type':'application/json',},payload);});}
|
||||
deleteSessions(userId){return __awaiter(this,void 0,void 0,function*(){if(typeof userId==='undefined'){throw new AppwriteException('Missing required parameter: "userId"');}
|
||||
let path='/users/{userId}/sessions'.replace('{userId}',userId);let payload={};const uri=new URL(this.client.config.endpoint+path);return yield this.client.call('delete',uri,{'content-type':'application/json',},payload);});}
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@
|
|||
'x-sdk-name': 'Console',
|
||||
'x-sdk-platform': 'console',
|
||||
'x-sdk-language': 'web',
|
||||
'x-sdk-version': '6.1.0-RC1',
|
||||
'X-Appwrite-Response-Format': '1.0.0-RC1',
|
||||
'x-sdk-version': '7.0.0',
|
||||
'X-Appwrite-Response-Format': '1.0.0',
|
||||
};
|
||||
this.realtime = {
|
||||
socket: undefined,
|
||||
|
|
@ -561,7 +561,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get Account Logs
|
||||
* List Account Logs
|
||||
*
|
||||
* Get currently logged in user list of latest security activity logs. Each
|
||||
* log returns user IP address, location and date and time of log.
|
||||
|
|
@ -570,7 +570,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLogs(queries) {
|
||||
listLogs(queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/account/logs';
|
||||
let payload = {};
|
||||
|
|
@ -814,7 +814,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get Account Sessions
|
||||
* List Account Sessions
|
||||
*
|
||||
* Get currently logged in user list of active sessions across different
|
||||
* devices.
|
||||
|
|
@ -822,7 +822,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getSessions() {
|
||||
listSessions() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/account/sessions';
|
||||
let payload = {};
|
||||
|
|
@ -1567,12 +1567,11 @@
|
|||
* @param {string} name
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {string} color
|
||||
* @param {string} background
|
||||
* @throws {AppwriteException}
|
||||
* @returns {URL}
|
||||
*/
|
||||
getInitials(name, width, height, color, background) {
|
||||
getInitials(name, width, height, background) {
|
||||
let path = '/avatars/initials';
|
||||
let payload = {};
|
||||
if (typeof name !== 'undefined') {
|
||||
|
|
@ -1584,9 +1583,6 @@
|
|||
if (typeof height !== 'undefined') {
|
||||
payload['height'] = height;
|
||||
}
|
||||
if (typeof color !== 'undefined') {
|
||||
payload['color'] = color;
|
||||
}
|
||||
if (typeof background !== 'undefined') {
|
||||
payload['background'] = background;
|
||||
}
|
||||
|
|
@ -1856,12 +1852,6 @@
|
|||
if (typeof name === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "name"');
|
||||
}
|
||||
if (typeof permissions === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "permissions"');
|
||||
}
|
||||
if (typeof documentSecurity === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "documentSecurity"');
|
||||
}
|
||||
let path = '/databases/{databaseId}/collections'.replace('{databaseId}', databaseId);
|
||||
let payload = {};
|
||||
if (typeof collectionId !== 'undefined') {
|
||||
|
|
@ -1917,13 +1907,13 @@
|
|||
* @param {string} databaseId
|
||||
* @param {string} collectionId
|
||||
* @param {string} name
|
||||
* @param {boolean} documentSecurity
|
||||
* @param {string[]} permissions
|
||||
* @param {boolean} documentSecurity
|
||||
* @param {boolean} enabled
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateCollection(databaseId, collectionId, name, documentSecurity, permissions, enabled) {
|
||||
updateCollection(databaseId, collectionId, name, permissions, documentSecurity, enabled) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
|
|
@ -1934,9 +1924,6 @@
|
|||
if (typeof name === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "name"');
|
||||
}
|
||||
if (typeof documentSecurity === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "documentSecurity"');
|
||||
}
|
||||
let path = '/databases/{databaseId}/collections/{collectionId}'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId);
|
||||
let payload = {};
|
||||
if (typeof name !== 'undefined') {
|
||||
|
|
@ -3040,10 +3027,11 @@
|
|||
* @param {string[]} events
|
||||
* @param {string} schedule
|
||||
* @param {number} timeout
|
||||
* @param {boolean} enabled
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
create(functionId, name, execute, runtime, events, schedule, timeout) {
|
||||
create(functionId, name, execute, runtime, events, schedule, timeout, enabled) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof functionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "functionId"');
|
||||
|
|
@ -3080,6 +3068,9 @@
|
|||
if (typeof timeout !== 'undefined') {
|
||||
payload['timeout'] = timeout;
|
||||
}
|
||||
if (typeof enabled !== 'undefined') {
|
||||
payload['enabled'] = enabled;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('post', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -3158,10 +3149,11 @@
|
|||
* @param {string[]} events
|
||||
* @param {string} schedule
|
||||
* @param {number} timeout
|
||||
* @param {boolean} enabled
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
update(functionId, name, execute, events, schedule, timeout) {
|
||||
update(functionId, name, execute, events, schedule, timeout, enabled) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof functionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "functionId"');
|
||||
|
|
@ -3189,6 +3181,9 @@
|
|||
if (typeof timeout !== 'undefined') {
|
||||
payload['timeout'] = timeout;
|
||||
}
|
||||
if (typeof enabled !== 'undefined') {
|
||||
payload['enabled'] = enabled;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('put', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -3569,24 +3564,16 @@
|
|||
* Get a list of all variables of a specific function.
|
||||
*
|
||||
* @param {string} functionId
|
||||
* @param {string[]} queries
|
||||
* @param {string} search
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listVariables(functionId, queries, search) {
|
||||
listVariables(functionId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof functionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "functionId"');
|
||||
}
|
||||
let path = '/functions/{functionId}/variables'.replace('{functionId}', functionId);
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -3953,7 +3940,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getContinents() {
|
||||
listContinents() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/continents';
|
||||
let payload = {};
|
||||
|
|
@ -3972,7 +3959,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getCountries() {
|
||||
listCountries() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/countries';
|
||||
let payload = {};
|
||||
|
|
@ -3991,7 +3978,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getCountriesEU() {
|
||||
listCountriesEU() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/countries/eu';
|
||||
let payload = {};
|
||||
|
|
@ -4010,7 +3997,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getCountriesPhones() {
|
||||
listCountriesPhones() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/countries/phones';
|
||||
let payload = {};
|
||||
|
|
@ -4030,7 +4017,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getCurrencies() {
|
||||
listCurrencies() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/currencies';
|
||||
let payload = {};
|
||||
|
|
@ -4049,7 +4036,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLanguages() {
|
||||
listLanguages() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/locale/languages';
|
||||
let payload = {};
|
||||
|
|
@ -5126,8 +5113,8 @@
|
|||
*
|
||||
* @param {string} bucketId
|
||||
* @param {string} name
|
||||
* @param {boolean} fileSecurity
|
||||
* @param {string[]} permissions
|
||||
* @param {boolean} fileSecurity
|
||||
* @param {boolean} enabled
|
||||
* @param {number} maximumFileSize
|
||||
* @param {string[]} allowedFileExtensions
|
||||
|
|
@ -5137,7 +5124,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
createBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
createBucket(bucketId, name, permissions, fileSecurity, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof bucketId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "bucketId"');
|
||||
|
|
@ -5145,9 +5132,6 @@
|
|||
if (typeof name === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "name"');
|
||||
}
|
||||
if (typeof fileSecurity === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "fileSecurity"');
|
||||
}
|
||||
let path = '/storage/buckets';
|
||||
let payload = {};
|
||||
if (typeof bucketId !== 'undefined') {
|
||||
|
|
@ -5216,8 +5200,8 @@
|
|||
*
|
||||
* @param {string} bucketId
|
||||
* @param {string} name
|
||||
* @param {boolean} fileSecurity
|
||||
* @param {string[]} permissions
|
||||
* @param {boolean} fileSecurity
|
||||
* @param {boolean} enabled
|
||||
* @param {number} maximumFileSize
|
||||
* @param {string[]} allowedFileExtensions
|
||||
|
|
@ -5227,7 +5211,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
updateBucket(bucketId, name, permissions, fileSecurity, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof bucketId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "bucketId"');
|
||||
|
|
@ -5235,9 +5219,6 @@
|
|||
if (typeof name === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "name"');
|
||||
}
|
||||
if (typeof fileSecurity === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "fileSecurity"');
|
||||
}
|
||||
let path = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
|
||||
let payload = {};
|
||||
if (typeof name !== 'undefined') {
|
||||
|
|
@ -5866,7 +5847,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get Team Memberships
|
||||
* List Team Memberships
|
||||
*
|
||||
* Use this endpoint to list a team's members using the team's ID. All team
|
||||
* members have read access to this endpoint.
|
||||
|
|
@ -5877,7 +5858,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getMemberships(teamId, queries, search) {
|
||||
listMemberships(teamId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof teamId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "teamId"');
|
||||
|
|
@ -6652,7 +6633,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get User Logs
|
||||
* List User Logs
|
||||
*
|
||||
* Get the user activity logs list by its unique ID.
|
||||
*
|
||||
|
|
@ -6661,7 +6642,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLogs(userId, queries) {
|
||||
listLogs(userId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof userId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "userId"');
|
||||
|
|
@ -6678,7 +6659,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get User Memberships
|
||||
* List User Memberships
|
||||
*
|
||||
* Get the user membership list by its unique ID.
|
||||
*
|
||||
|
|
@ -6686,7 +6667,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getMemberships(userId) {
|
||||
listMemberships(userId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof userId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "userId"');
|
||||
|
|
@ -6840,7 +6821,7 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* Get User Sessions
|
||||
* List User Sessions
|
||||
*
|
||||
* Get the user sessions list by its unique ID.
|
||||
*
|
||||
|
|
@ -6848,7 +6829,7 @@
|
|||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getSessions(userId) {
|
||||
listSessions(userId) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof userId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "userId"');
|
||||
|
|
|
|||
|
|
@ -286,8 +286,8 @@ class Realtime extends Adapter
|
|||
}
|
||||
|
||||
$channels[] = 'documents';
|
||||
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getCollection() . '.documents';
|
||||
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getCollection() . '.documents.' . $payload->getId();
|
||||
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents';
|
||||
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents.' . $payload->getId();
|
||||
|
||||
$roles = $collection->getAttribute('documentSecurity', false)
|
||||
? \array_merge($collection->getRead(), $payload->getRead())
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ use Utopia\App;
|
|||
use Utopia\Database\ID;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
|
||||
abstract class Migration
|
||||
{
|
||||
/**
|
||||
|
|
@ -39,18 +41,8 @@ abstract class Migration
|
|||
* @var array
|
||||
*/
|
||||
public static array $versions = [
|
||||
'0.13.0' => 'V12',
|
||||
'0.13.1' => 'V12',
|
||||
'0.13.2' => 'V12',
|
||||
'0.13.3' => 'V12',
|
||||
'0.13.4' => 'V12',
|
||||
'0.14.0' => 'V13',
|
||||
'0.14.1' => 'V13',
|
||||
'0.14.2' => 'V13',
|
||||
'0.15.0' => 'V14',
|
||||
'0.15.1' => 'V14',
|
||||
'0.15.2' => 'V14',
|
||||
'0.15.3' => 'V14'
|
||||
'1.0.0-RC1' => 'V15',
|
||||
'1.0.0' => 'V15'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -62,6 +54,7 @@ abstract class Migration
|
|||
{
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
|
||||
$this->collections = array_merge([
|
||||
'_metadata' => [
|
||||
'$id' => ID::custom('_metadata'),
|
||||
|
|
@ -105,66 +98,74 @@ abstract class Migration
|
|||
*/
|
||||
public function forEachDocument(callable $callback): void
|
||||
{
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
|
||||
foreach ($this->collections as $collection) {
|
||||
if ($collection['$collection'] !== Database::METADATA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sum = 0;
|
||||
$nextDocument = null;
|
||||
$collectionCount = $this->projectDB->count($collection['$id']);
|
||||
Console::log('Migrating Collection ' . $collection['$id'] . ':');
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
\Co\run(function (array $collection, callable $callback) {
|
||||
foreach ($this->documentsIterator($collection['$id']) as $document) {
|
||||
go(function (Document $document, callable $callback) {
|
||||
if (empty($document->getId()) || empty($document->getCollection())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$old = $document->getArrayCopy();
|
||||
$new = call_user_func($callback, $document);
|
||||
|
||||
if (is_null($new) || !self::hasDifference($new->getArrayCopy(), $old)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$new = $this->projectDB->updateDocument($document->getCollection(), $document->getId(), $document);
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Failed to update document: ' . $th->getMessage());
|
||||
return;
|
||||
}
|
||||
}, $document, $callback);
|
||||
}
|
||||
$documents = $this->projectDB->find($collection['$id'], $queries);
|
||||
$count = count($documents);
|
||||
$sum += $count;
|
||||
|
||||
Console::log($sum . ' / ' . $collectionCount);
|
||||
|
||||
\Co\run(function (array $documents, callable $callback) {
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $document, callable $callback) {
|
||||
if (empty($document->getId()) || empty($document->getCollection())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$old = $document->getArrayCopy();
|
||||
$new = call_user_func($callback, $document);
|
||||
|
||||
if (is_null($new) || !self::hasDifference($new->getArrayCopy(), $old)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$new = $this->projectDB->updateDocument($document->getCollection(), $document->getId(), $document);
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Failed to update document: ' . $th->getMessage());
|
||||
return;
|
||||
|
||||
if ($document && $new->getId() !== $document->getId()) {
|
||||
throw new Exception('Duplication Error');
|
||||
}
|
||||
}
|
||||
}, $document, $callback);
|
||||
}
|
||||
}, $documents, $callback);
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextDocument = null;
|
||||
} else {
|
||||
$nextDocument = end($documents);
|
||||
}
|
||||
} while (!is_null($nextDocument));
|
||||
}, $collection, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an iterator for all documents on a collection.
|
||||
*
|
||||
* @param string $collectionId
|
||||
* @return iterable<Document>
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function documentsIterator(string $collectionId): iterable
|
||||
{
|
||||
$sum = 0;
|
||||
$nextDocument = null;
|
||||
$collectionCount = $this->projectDB->count($collectionId);
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find($collectionId, $queries);
|
||||
$count = count($documents);
|
||||
$sum += $count;
|
||||
|
||||
Console::log($sum . ' / ' . $collectionCount);
|
||||
foreach ($documents as $document) {
|
||||
yield $document;
|
||||
}
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextDocument = null;
|
||||
} else {
|
||||
$nextDocument = end($documents);
|
||||
}
|
||||
} while (!is_null($nextDocument));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks 2 arrays for differences.
|
||||
*
|
||||
|
|
@ -265,6 +266,8 @@ abstract class Migration
|
|||
}
|
||||
|
||||
$attribute = $attributes[$attributeKey];
|
||||
$filters = $attribute['filters'] ?? [];
|
||||
$default = $attribute['default'] ?? null;
|
||||
|
||||
$database->createAttribute(
|
||||
collection: $collectionId,
|
||||
|
|
@ -272,12 +275,12 @@ abstract class Migration
|
|||
type: $attribute['type'],
|
||||
size: $attribute['size'],
|
||||
required: $attribute['required'] ?? false,
|
||||
default: $attribute['default'] ?? null,
|
||||
default: in_array('json', $filters) ? json_encode($default) : $default,
|
||||
signed: $attribute['signed'] ?? false,
|
||||
array: $attribute['array'] ?? false,
|
||||
format: $attribute['format'] ?? '',
|
||||
formatOptions: $attribute['formatOptions'] ?? [],
|
||||
filters: $attribute['filters'] ?? [],
|
||||
filters: $filters,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -287,13 +290,15 @@ abstract class Migration
|
|||
* @param \Utopia\Database\Database $database
|
||||
* @param string $collectionId
|
||||
* @param string $indexId
|
||||
* @param string|null $from
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws \Utopia\Database\Exception\Duplicate
|
||||
* @throws \Utopia\Database\Exception\Limit
|
||||
*/
|
||||
public function createIndexFromCollection(Database $database, string $collectionId, string $indexId): void
|
||||
public function createIndexFromCollection(Database $database, string $collectionId, string $indexId, string $from = null): void
|
||||
{
|
||||
$from ??= $collectionId;
|
||||
$collection = Config::getParam('collections', [])[$collectionId] ?? null;
|
||||
|
||||
if (is_null($collection)) {
|
||||
|
|
|
|||
|
|
@ -1,617 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Migration\Version;
|
||||
|
||||
use Appwrite\Migration\Migration;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class V12 extends Migration
|
||||
{
|
||||
/**
|
||||
* @var \PDO $pdo
|
||||
*/
|
||||
private $pdo;
|
||||
|
||||
public function execute(): void
|
||||
{
|
||||
global $register;
|
||||
Console::log('Migrating project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
|
||||
$this->pdo = $register->get('db');
|
||||
|
||||
Console::info('Migrating Project Schemas');
|
||||
$this->migrateProjectSchema($this->project->getId());
|
||||
|
||||
/**
|
||||
* Switch to migrated Console Project
|
||||
*/
|
||||
if ($this->project->getId() === 'console') {
|
||||
$this->consoleDB->setNamespace('_console');
|
||||
$this->projectDB->setNamespace('_console');
|
||||
}
|
||||
|
||||
Console::info('Migrating Permissions');
|
||||
$this->fixPermissions();
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCustomCollections();
|
||||
$this->fixCollections();
|
||||
Console::info('Migrating Documents');
|
||||
$this->forEachDocument([$this, 'fixDocument']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Project Tables.
|
||||
*
|
||||
* @param string $projectId
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws \PDOException
|
||||
*/
|
||||
private function migrateProjectSchema(string $projectId): void
|
||||
{
|
||||
/**
|
||||
* Remove empty generated Console Project.
|
||||
*/
|
||||
if ($this->consoleDB->getNamespace() === '_project_console' && $projectId === 'console') {
|
||||
$all = ['_console_bucket_1', '_console_bucket_1_perms'];
|
||||
foreach ($this->collections as $collection) {
|
||||
$all[] = "_{$projectId}_{$collection['$id']}";
|
||||
$all[] = "_{$projectId}_{$collection['$id']}_perms";
|
||||
}
|
||||
$this->pdo->prepare('DROP TABLE IF EXISTS ' . implode(', ', $all) . ';')->execute();
|
||||
} elseif ($this->projectDB->getNamespace() === '_console') {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename Database Tables.
|
||||
*/
|
||||
foreach ($this->collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
/**
|
||||
* Skip new tables that don't exists on old schema.
|
||||
*/
|
||||
if (in_array($id, ['buckets', 'deployments', 'builds'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_project_{$projectId}_{$id}` RENAME TO `_{$projectId}_{$id}`")->execute();
|
||||
$this->pdo->prepare("CREATE TABLE IF NOT EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$projectId}_{$id}_perms` (
|
||||
`_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`_type` VARCHAR(12) NOT NULL,
|
||||
`_permission` VARCHAR(255) NOT NULL,
|
||||
`_document` VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE INDEX `_index1` (`_type`,`_document`,`_permission`),
|
||||
INDEX `_index2` (`_permission`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;")->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate all Collection Structure.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function fixCollections(): void
|
||||
{
|
||||
foreach ($this->collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
/**
|
||||
* Skip new tables that don't exists on old schema.
|
||||
*/
|
||||
if (in_array($id, ['buckets', 'deployments', 'builds'])) {
|
||||
continue;
|
||||
}
|
||||
Console::log("- {$id}");
|
||||
switch ($id) {
|
||||
case 'sessions':
|
||||
try {
|
||||
/**
|
||||
* Rename providerToken to providerAccessToken
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'providerToken', 'providerAccessToken');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'providerAccessToken' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create providerRefreshToken
|
||||
*/
|
||||
$this->projectDB->createAttribute(collection: $id, id: 'providerRefreshToken', type: Database::VAR_STRING, size: 16384, signed: true, required: false, filters: ['encrypt']);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'providerRefreshToken' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create providerAccessTokenExpiry
|
||||
*/
|
||||
$this->projectDB->createAttribute(collection: $id, id: 'providerAccessTokenExpiry', type: Database::VAR_INTEGER, size: 0, required: false);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'providerAccessTokenExpiry' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'memberships':
|
||||
try {
|
||||
/**
|
||||
* Add search attribute and index to memberships.
|
||||
*/
|
||||
$this->projectDB->createAttribute(collection: $id, id: 'search', type: Database::VAR_STRING, size: 16384, required: false);
|
||||
$this->projectDB->createIndex(collection: $id, id: '_key_search', type: Database::INDEX_FULLTEXT, attributes: ['search']);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'search' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
|
||||
case 'files':
|
||||
/**
|
||||
* Create bucket table if not exists.
|
||||
*/
|
||||
$this->createCollection('buckets');
|
||||
|
||||
if (!$this->projectDB->findOne('buckets', [Query::equal('$id', ['default'])])) {
|
||||
$this->projectDB->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('default'),
|
||||
'$collection' => ID::custom('buckets'),
|
||||
'dateCreated' => \time(),
|
||||
'dateUpdated' => \time(),
|
||||
'name' => 'Default',
|
||||
'permission' => 'file',
|
||||
'maximumFileSize' => (int) App::getEnv('_APP_STORAGE_LIMIT', 0), // 10MB
|
||||
'allowedFileExtensions' => [],
|
||||
'enabled' => true,
|
||||
'encryption' => true,
|
||||
'antivirus' => true,
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'search' => 'buckets Default',
|
||||
]));
|
||||
$this->createCollection('files', 'bucket_1');
|
||||
|
||||
/**
|
||||
* Migrate all files to default Bucket.
|
||||
*/
|
||||
$nextDocument = null;
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find('files', $queries);
|
||||
$count = count($documents);
|
||||
\Co\run(function (array $documents) {
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $document) {
|
||||
/**
|
||||
* Update File Path
|
||||
*/
|
||||
$path = "/storage/uploads/app-{$this->project->getId()}";
|
||||
$new = str_replace($path, "{$path}/default", $document->getAttribute('path'));
|
||||
$document->setAttribute('path', $new);
|
||||
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new values.
|
||||
*/
|
||||
$document
|
||||
->setAttribute('bucketId', 'default')
|
||||
->setAttribute('chunksTotal', 1)
|
||||
->setAttribute('chunksUploaded', 1);
|
||||
|
||||
$this->projectDB->createDocument('bucket_1', $document);
|
||||
}, $document);
|
||||
}
|
||||
}, $documents);
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextDocument = null;
|
||||
} else {
|
||||
$nextDocument = end($documents);
|
||||
$nextDocument->setAttribute('$collection', 'files');
|
||||
}
|
||||
} while (!is_null($nextDocument));
|
||||
|
||||
/**
|
||||
* Rename folder on volumes.
|
||||
*/
|
||||
$path = "/storage/uploads/app-{$this->project->getId()}";
|
||||
|
||||
if (is_dir("{$path}/")) {
|
||||
mkdir("/storage/uploads/app-{$this->project->getId()}/default");
|
||||
|
||||
foreach (new \DirectoryIterator($path) as $fileinfo) {
|
||||
if ($fileinfo->isDir() && !$fileinfo->isDot() && $fileinfo->getFilename() !== 'default') {
|
||||
rename("{$path}/{$fileinfo->getFilename()}", "{$path}/default/{$fileinfo->getFilename()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'functions':
|
||||
try {
|
||||
/**
|
||||
* Rename tag to deployment
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'tag', 'deployment');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deployment' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create deployments table if not exists.
|
||||
*/
|
||||
$this->createCollection('deployments');
|
||||
|
||||
/**
|
||||
* Create builds table if not exists.
|
||||
*/
|
||||
$this->createCollection('builds');
|
||||
|
||||
break;
|
||||
|
||||
case 'executions':
|
||||
try {
|
||||
/**
|
||||
* Rename tag to deployment
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'tagId', 'deploymentId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Create statusCode
|
||||
*/
|
||||
$this->projectDB->createAttribute(collection: $id, id: 'statusCode', type: Database::VAR_INTEGER, size: 0, required: false);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'statusCode' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'teams':
|
||||
try {
|
||||
/**
|
||||
* Rename tag to deployment
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'sum', 'total');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'total' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates permissions to dedicated table.
|
||||
*
|
||||
* @param \Utopia\Database\Document $document
|
||||
* @param string $internalId
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @throws \PDOException
|
||||
*/
|
||||
protected function migratePermissionsToDedicatedTable(string $collection, Document $document): void
|
||||
{
|
||||
$sql = "SELECT _read, _write FROM `{$this->projectDB->getDefaultDatabase()}`.`{$this->projectDB->getNamespace()}_{$collection}` WHERE _uid = {$this->pdo->quote($document->getid())}";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute();
|
||||
|
||||
$permissions = $stmt->fetch();
|
||||
|
||||
$read = json_decode($permissions['_read'] ?? null) ?? [];
|
||||
$write = json_decode($permissions['_write'] ?? null) ?? [];
|
||||
|
||||
$permissions = [];
|
||||
foreach ($read as $permission) {
|
||||
$permissions[] = "('read', '{$permission}', '{$document->getId()}')";
|
||||
}
|
||||
|
||||
foreach ($write as $permission) {
|
||||
$permissions[] = "('write', '{$permission}', '{$document->getId()}')";
|
||||
}
|
||||
|
||||
if (!empty($permissions)) {
|
||||
$queryPermissions = "INSERT IGNORE INTO `{$this->projectDB->getDefaultDatabase()}`.`{$this->projectDB->getNamespace()}_{$collection}_perms` (_type, _permission, _document) VALUES " . implode(', ', $permissions);
|
||||
$stmtPermissions = $this->pdo->prepare($queryPermissions);
|
||||
$stmtPermissions->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates all user's database collections.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function migrateCustomCollections(): void
|
||||
{
|
||||
$nextCollection = null;
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextCollection !== null) {
|
||||
$queries[] = Query::cursorAfter($nextCollection);
|
||||
}
|
||||
$documents = $this->projectDB->find('collections', $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $collection) {
|
||||
$id = $collection->getId();
|
||||
$projectId = $this->project->getId();
|
||||
$internalId = $collection->getInternalId();
|
||||
|
||||
if ($this->projectDB->exists(App::getEnv('_APP_DB_SCHEMA', 'appwrite'), "collection_{$internalId}")) {
|
||||
return;
|
||||
}
|
||||
Console::log("- {$id} ({$collection->getAttribute('name')})");
|
||||
|
||||
/**
|
||||
* Rename user's colletion table schema
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_project_{$projectId}_collection_{$id}` RENAME TO `_{$projectId}_collection_{$internalId}`")->execute();
|
||||
$this->pdo->prepare("CREATE TABLE IF NOT EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$projectId}_collection_{$internalId}_perms` (
|
||||
`_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`_type` VARCHAR(12) NOT NULL,
|
||||
`_permission` VARCHAR(255) NOT NULL,
|
||||
`_document` VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (`_id`),
|
||||
UNIQUE INDEX `_index1` (`_type`,`_document`,`_permission`),
|
||||
INDEX `_index2` (`_permission`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;")->execute();
|
||||
|
||||
/**
|
||||
* Update metadata table.
|
||||
*/
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$projectId}__metadata`
|
||||
SET
|
||||
_uid = 'collection_{$internalId}',
|
||||
name = 'collection_{$internalId}'
|
||||
WHERE _uid = 'collection_{$id}';
|
||||
")->execute();
|
||||
|
||||
|
||||
$nextDocument = null;
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find('collection_' . $internalId, $queries);
|
||||
$count = count($documents);
|
||||
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $document, string $internalId) {
|
||||
$this->migratePermissionsToDedicatedTable("collection_{$internalId}", $document);
|
||||
}, $document, $internalId);
|
||||
}
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextDocument = null;
|
||||
} else {
|
||||
$nextDocument = end($documents);
|
||||
}
|
||||
} while (!is_null($nextDocument));
|
||||
|
||||
/**
|
||||
* Remove _read and _write columns
|
||||
*/
|
||||
$this->pdo->prepare("
|
||||
ALTER TABLE `{$this->projectDB->getDefaultDatabase()}`.`{$this->projectDB->getNamespace()}_collection_{$internalId}`
|
||||
DROP COLUMN _read,
|
||||
DROP COLUMN _write
|
||||
")->execute();
|
||||
}, $document);
|
||||
}
|
||||
}, $documents);
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextCollection = null;
|
||||
} else {
|
||||
$nextCollection = end($documents);
|
||||
}
|
||||
} while (!is_null($nextCollection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate all Permission to new System with dedicated Table.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function fixPermissions()
|
||||
{
|
||||
foreach ($this->collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
/**
|
||||
* Skip new tables that don't exists on old schema.
|
||||
*/
|
||||
if (in_array($id, ['buckets', 'deployments', 'builds'])) {
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* Check if permissions have already been migrated.
|
||||
*/
|
||||
try {
|
||||
$stmtCheck = $this->pdo->prepare("SHOW COLUMNS from `{$this->projectDB->getDefaultDatabase()}`.`{$this->projectDB->getNamespace()}_{$id}` LIKE '_read'");
|
||||
$stmtCheck->execute();
|
||||
|
||||
if (empty($stmtCheck->fetchAll())) {
|
||||
continue;
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
if ($th->getCode() === "42S02") {
|
||||
continue;
|
||||
}
|
||||
throw $th;
|
||||
}
|
||||
|
||||
|
||||
Console::log("- {$collection['$id']}");
|
||||
$nextDocument = null;
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextDocument !== null) {
|
||||
$queries[] = Query::cursorAfter($nextDocument);
|
||||
}
|
||||
$documents = $this->projectDB->find($id, $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $document) {
|
||||
$this->migratePermissionsToDedicatedTable($document->getCollection(), $document);
|
||||
}, $document);
|
||||
}
|
||||
}, $documents);
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextDocument = null;
|
||||
} else {
|
||||
$nextDocument = end($documents);
|
||||
}
|
||||
} while (!is_null($nextDocument));
|
||||
|
||||
/**
|
||||
* Remove _read and _write columns
|
||||
*/
|
||||
$this->pdo->prepare("
|
||||
ALTER TABLE `{$this->projectDB->getDefaultDatabase()}`.`{$this->projectDB->getNamespace()}_{$id}`
|
||||
DROP COLUMN _read,
|
||||
DROP COLUMN _write
|
||||
")->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeout to give MariaDB some room to breath
|
||||
*/
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
* @param \Utopia\Database\Document $document
|
||||
* @return \Utopia\Database\Document
|
||||
*/
|
||||
protected function fixDocument(Document $document)
|
||||
{
|
||||
switch ($document->getCollection()) {
|
||||
case 'projects':
|
||||
/**
|
||||
* Bump Project version number.
|
||||
*/
|
||||
$document->setAttribute('version', '0.13.0');
|
||||
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'email', 'name'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'teams':
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'functions':
|
||||
$document->setAttribute('deployment', null);
|
||||
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'name', 'runtime'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'executions':
|
||||
/**
|
||||
* Populate search string from Migration to 0.12.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'functionId'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'memberships':
|
||||
/**
|
||||
* Populate search string.
|
||||
*/
|
||||
if (empty($document->getAttribute('search'))) {
|
||||
$document->setAttribute('search', $this->buildSearchAttribute(['$id', 'userId'], $document));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'sessions':
|
||||
$document
|
||||
->setAttribute('providerRefreshToken', '')
|
||||
->setAttribute('providerAccessTokenExpiry', 0)
|
||||
->setAttribute('providerAccessToken', $document->getAttribute('providerToken', ''))
|
||||
->removeAttribute('providerToken');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a search string for a fulltext index.
|
||||
*
|
||||
* @param array $values
|
||||
* @param Document $document
|
||||
* @return string
|
||||
*/
|
||||
private function buildSearchAttribute(array $values, Document $document): string
|
||||
{
|
||||
$values = array_filter(array_map(fn (string $value) => $document->getAttribute($value) ?? '', $values));
|
||||
|
||||
return implode(' ', $values);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,337 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Migration\Version;
|
||||
|
||||
use Appwrite\Migration\Migration;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class V13 extends Migration
|
||||
{
|
||||
public array $events = [
|
||||
'account.create',
|
||||
'account.update.email',
|
||||
'account.update.name',
|
||||
'account.update.password',
|
||||
'account.update.prefs',
|
||||
'account.recovery.create',
|
||||
'account.recovery.update',
|
||||
'account.verification.create',
|
||||
'account.verification.update',
|
||||
'account.delete',
|
||||
'account.sessions.create',
|
||||
'account.sessions.delete',
|
||||
'database.collections.create',
|
||||
'database.collections.update',
|
||||
'database.collections.delete',
|
||||
'database.attributes.create',
|
||||
'database.attributes.delete',
|
||||
'database.indexes.create',
|
||||
'database.indexes.delete',
|
||||
'database.documents.create',
|
||||
'database.documents.update',
|
||||
'database.documents.delete',
|
||||
'functions.create',
|
||||
'functions.update',
|
||||
'functions.delete',
|
||||
'functions.deployments.create',
|
||||
'functions.deployments.update',
|
||||
'functions.deployments.delete',
|
||||
'functions.executions.create',
|
||||
'functions.executions.update',
|
||||
'storage.files.create',
|
||||
'storage.files.update',
|
||||
'storage.files.delete',
|
||||
'storage.buckets.create',
|
||||
'storage.buckets.update',
|
||||
'storage.buckets.delete',
|
||||
'users.create',
|
||||
'users.update.prefs',
|
||||
'users.update.email',
|
||||
'users.update.name',
|
||||
'users.update.password',
|
||||
'users.update.status',
|
||||
'users.sessions.delete',
|
||||
'users.delete',
|
||||
'teams.create',
|
||||
'teams.update',
|
||||
'teams.delete',
|
||||
'teams.memberships.create',
|
||||
'teams.memberships.update',
|
||||
'teams.memberships.update.status',
|
||||
'teams.memberships.delete'
|
||||
];
|
||||
|
||||
public function execute(): void
|
||||
{
|
||||
Console::log('Migrating project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
Console::info('Migrating Documents');
|
||||
$this->forEachDocument([$this, 'fixDocument']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate all Collections.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function migrateCollections(): void
|
||||
{
|
||||
foreach ($this->collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
Console::log("- {$id}");
|
||||
switch ($id) {
|
||||
case 'projects':
|
||||
try {
|
||||
/**
|
||||
* Rename providers to authProviders.
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'providers', 'authProviders');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'providers' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'users':
|
||||
try {
|
||||
/**
|
||||
* Recreate sessions for new subquery.
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'sessions');
|
||||
$this->projectDB->createAttribute(
|
||||
collection: $id,
|
||||
id: 'sessions',
|
||||
required: false,
|
||||
type: Database::VAR_STRING,
|
||||
format: '',
|
||||
size: 16384,
|
||||
filters: ['subQuerySessions']
|
||||
);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'sessions' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Recreate tokens for new subquery.
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'tokens');
|
||||
$this->projectDB->createAttribute(
|
||||
collection: $id,
|
||||
id: 'tokens',
|
||||
required: false,
|
||||
type: Database::VAR_STRING,
|
||||
format: '',
|
||||
size: 16384,
|
||||
filters: ['subQueryTokens']
|
||||
);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'tokens' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Recreate memberships for new subquery.
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'memberships');
|
||||
$this->projectDB->createAttribute(
|
||||
collection: $id,
|
||||
id: 'memberships',
|
||||
required: false,
|
||||
type: Database::VAR_STRING,
|
||||
format: '',
|
||||
size: 16384,
|
||||
filters: ['subQueryMemberships']
|
||||
);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'memberships' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'sessions':
|
||||
try {
|
||||
/**
|
||||
* Add new index for users.
|
||||
*/
|
||||
$this->projectDB->createIndex(collection: $id, id: '_key_user', type: Database::INDEX_KEY, attributes: ['userId'], orders: [Database::ORDER_ASC]);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'builds':
|
||||
try {
|
||||
/**
|
||||
* Increase stdout size.
|
||||
*/
|
||||
$this->projectDB->updateAttribute($id, 'stdout', size: 1_000_000);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'stdout' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Increase stderr size.
|
||||
*/
|
||||
$this->projectDB->updateAttribute($id, 'stderr', size: 1_000_000);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'stderr' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'executions':
|
||||
try {
|
||||
/**
|
||||
* Rename stdout to response.
|
||||
* Increase response size.
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'stdout', 'response');
|
||||
$this->projectDB->updateAttribute($id, 'response', size: 1_000_000);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'stdout' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Increase stderr size.
|
||||
*/
|
||||
$this->projectDB->updateAttribute($id, 'stderr', size: 1_000_000);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'stderr' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'stats':
|
||||
try {
|
||||
/**
|
||||
* Increase value size ot BIGINT.
|
||||
*/
|
||||
$this->projectDB->updateAttribute($id, 'value', size: 8);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'size' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'tokens':
|
||||
try {
|
||||
/**
|
||||
* Create new Tokens collection.
|
||||
*/
|
||||
$this->createCollection('tokens');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'tokens': {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
* @param \Utopia\Database\Document $document
|
||||
* @return \Utopia\Database\Document
|
||||
*/
|
||||
protected function fixDocument(Document $document)
|
||||
{
|
||||
switch ($document->getCollection()) {
|
||||
case 'projects':
|
||||
/**
|
||||
* Bump Project version number.
|
||||
*/
|
||||
$document->setAttribute('version', '0.14.0');
|
||||
|
||||
break;
|
||||
|
||||
case 'functions':
|
||||
/**
|
||||
* Migrate events.
|
||||
*/
|
||||
if (!empty($document->getAttribute('events'))) {
|
||||
$document->setAttribute('events', $this->migrateEvents($document->getAttribute('events')));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'webhooks':
|
||||
/**
|
||||
* Migrate events.
|
||||
*/
|
||||
if (!empty($document->getAttribute('events'))) {
|
||||
$document->setAttribute('events', $this->migrateEvents($document->getAttribute('events')));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'users':
|
||||
/**
|
||||
* Remove deleted users.
|
||||
*/
|
||||
if ($document->getAttribute('deleted', false) === true) {
|
||||
$this->projectDB->deleteDocument('users', $document->getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
public function migrateEvents(array $events): array
|
||||
{
|
||||
return array_filter(array_unique(array_map(function ($event) {
|
||||
if (!in_array($event, $this->events)) {
|
||||
return $event;
|
||||
}
|
||||
$parts = \explode('.', $event);
|
||||
$first = array_shift($parts);
|
||||
switch ($first) {
|
||||
case 'account':
|
||||
case 'users':
|
||||
$first = 'users';
|
||||
|
||||
switch ($parts[0]) {
|
||||
case 'recovery':
|
||||
case 'sessions':
|
||||
case 'verification':
|
||||
$second = array_shift($parts);
|
||||
return 'users.*.' . $second . '.*.' . implode('.', $parts);
|
||||
|
||||
default:
|
||||
return 'users.*.' . implode('.', $parts);
|
||||
}
|
||||
case 'functions':
|
||||
switch ($parts[0]) {
|
||||
case 'deployments':
|
||||
case 'executions':
|
||||
$second = array_shift($parts);
|
||||
return 'functions.*.' . $second . '.*.' . implode('.', $parts);
|
||||
|
||||
default:
|
||||
return 'functions.*.' . implode('.', $parts);
|
||||
}
|
||||
case 'teams':
|
||||
switch ($parts[0]) {
|
||||
case 'memberships':
|
||||
$second = array_shift($parts);
|
||||
return 'teams.*.' . $second . '.*.' . implode('.', $parts);
|
||||
|
||||
default:
|
||||
return 'teams.*.' . implode('.', $parts);
|
||||
}
|
||||
case 'storage':
|
||||
$second = array_shift($parts);
|
||||
switch ($second) {
|
||||
case 'buckets':
|
||||
return 'buckets.*.' . implode('.', $parts);
|
||||
case 'files':
|
||||
return 'buckets.*.' . $second . '.*.' . implode('.', $parts);
|
||||
} // intentional fallthrough
|
||||
case 'database':
|
||||
$second = array_shift($parts);
|
||||
switch ($second) {
|
||||
case 'collections':
|
||||
return 'collections.*.' . implode('.', $parts);
|
||||
case 'documents':
|
||||
case 'indexes':
|
||||
case 'attributes':
|
||||
return 'collections.*.' . $second . '.*.' . implode('.', $parts);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}, $events)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,806 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Migration\Version;
|
||||
|
||||
use Appwrite\Migration\Migration;
|
||||
use Exception;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class V14 extends Migration
|
||||
{
|
||||
/**
|
||||
* @var \PDO $pdo
|
||||
*/
|
||||
private $pdo;
|
||||
|
||||
public function execute(): void
|
||||
{
|
||||
global $register;
|
||||
$this->pdo = $register->get('db');
|
||||
|
||||
if ($this->project->getId() === 'console' && $this->project->getInternalId() !== 'console') {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SubQueries for Speed.
|
||||
*/
|
||||
foreach (['subQueryAttributes', 'subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships'] as $name) {
|
||||
Database::addFilter($name, fn () => null, fn () => []);
|
||||
}
|
||||
|
||||
Console::log('Migrating project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
Console::info('Create Default Database Layer');
|
||||
$this->createDatabaseLayer();
|
||||
if ($this->project->getId() !== 'console') {
|
||||
Console::info('Migrating Database Collections');
|
||||
$this->migrateCustomCollections();
|
||||
}
|
||||
Console::info('Migrating Documents');
|
||||
$this->forEachDocument([$this, 'fixDocument']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default Database for existing Projects.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function createDatabaseLayer(): void
|
||||
{
|
||||
try {
|
||||
if (!$this->projectDB->exists('databases')) {
|
||||
$this->createCollection('databases');
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
if ($this->project->getInternalId() === 'console') {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->createDocument('databases', new Document([
|
||||
'$id' => ID::custom('default'),
|
||||
'name' => 'Default',
|
||||
'search' => 'default Default'
|
||||
]));
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates all Files.
|
||||
*
|
||||
* @param \Utopia\Database\Document $bucket
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function migrateBucketFiles(Document $bucket): void
|
||||
{
|
||||
$nextFile = null;
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextFile !== null) {
|
||||
$queries[] = Query::cursorAfter($nextFile);
|
||||
}
|
||||
$documents = $this->projectDB->find("bucket_{$bucket->getInternalId()}", $queries);
|
||||
$count = count($documents);
|
||||
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $bucket, Document $document) {
|
||||
Console::log("Migrating File {$document->getId()}");
|
||||
try {
|
||||
/**
|
||||
* Migrate $createdAt.
|
||||
*/
|
||||
if (empty($document->getCreatedAt())) {
|
||||
$document->setAttribute('$createdAt', $document->getAttribute('dateCreated'));
|
||||
$this->projectDB->updateDocument("bucket_{$bucket->getInternalId()}", $document->getId(), $document);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
}, $bucket, $document);
|
||||
}
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextFile = null;
|
||||
} else {
|
||||
$nextFile = end($documents);
|
||||
}
|
||||
} while (!is_null($nextFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates all Database Collections.
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function migrateCustomCollections(): void
|
||||
{
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_collections` RENAME TO `_{$this->project->getInternalId()}_database_1`")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_collections_perms` RENAME TO `_{$this->project->getInternalId()}_database_1_perms`")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update metadata table.
|
||||
*/
|
||||
try {
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}__metadata`
|
||||
SET
|
||||
_uid = 'database_1',
|
||||
name = 'database_1'
|
||||
WHERE _uid = 'collections';
|
||||
")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Add Database ID for Collections.
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, 'database_1', 'databaseId', 'collections');
|
||||
|
||||
/**
|
||||
* Add Database Internal ID for Collections.
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, 'database_1', 'databaseInternalId', 'collections');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
$nextCollection = null;
|
||||
|
||||
do {
|
||||
$queries = [Query::limit($this->limit)];
|
||||
if ($nextCollection !== null) {
|
||||
$queries[] = Query::cursorAfter($nextCollection);
|
||||
}
|
||||
$documents = $this->projectDB->find('database_1', $queries);
|
||||
$count = count($documents);
|
||||
|
||||
\Co\run(function (array $documents) {
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $collection) {
|
||||
$id = $collection->getId();
|
||||
$internalId = $collection->getInternalId();
|
||||
|
||||
Console::log("- {$id} ({$collection->getAttribute('name')})");
|
||||
|
||||
try {
|
||||
/**
|
||||
* Rename user's colletion table schema
|
||||
*/
|
||||
$this->createNewMetaData("collection_{$internalId}", "database_1_collection_{$internalId}");
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Update metadata table.
|
||||
*/
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}__metadata`
|
||||
SET
|
||||
_uid = 'database_1_collection_{$internalId}',
|
||||
name = 'database_1_collection_{$internalId}'
|
||||
WHERE _uid = 'collection_{$internalId}';
|
||||
")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Update internal ID's.
|
||||
*/
|
||||
$collection
|
||||
->setAttribute('databaseId', 'default')
|
||||
->setAttribute('databaseInternalId', '1');
|
||||
$this->projectDB->updateDocument('database_1', $collection->getId(), $collection);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
/**
|
||||
* Migrate Attributes
|
||||
*/
|
||||
$this->migrateAttributesAndCollections('attributes', $collection);
|
||||
/**
|
||||
* Migrate Indexes
|
||||
*/
|
||||
$this->migrateAttributesAndCollections('indexes', $collection);
|
||||
}, $document);
|
||||
}
|
||||
}, $documents);
|
||||
|
||||
if ($count !== $this->limit) {
|
||||
$nextCollection = null;
|
||||
} else {
|
||||
$nextCollection = end($documents);
|
||||
}
|
||||
} while (!is_null($nextCollection));
|
||||
}
|
||||
|
||||
protected function migrateAttributesAndCollections(string $type, Document $collection): void
|
||||
{
|
||||
/**
|
||||
* Offset pagination instead of cursor, since documents are re-created!
|
||||
*/
|
||||
$offset = 0;
|
||||
$attributesCount = $this->projectDB->count($type, queries: [Query::equal('collectionId', [$collection->getId()])]);
|
||||
|
||||
do {
|
||||
$queries = [
|
||||
Query::limit($this->limit),
|
||||
Query::offset($offset),
|
||||
Query::equal('collectionId', [$collection->getId()]),
|
||||
];
|
||||
$documents = $this->projectDB->find($type, $queries);
|
||||
$offset += $this->limit;
|
||||
|
||||
foreach ($documents as $document) {
|
||||
go(function (Document $document, string $internalId, string $type) {
|
||||
try {
|
||||
/**
|
||||
* Skip already migrated Documents.
|
||||
*/
|
||||
if (!is_null($document->getAttribute('databaseId'))) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Add Internal ID 'collectionInternalId' for Subqueries.
|
||||
*/
|
||||
$document->setAttribute('collectionInternalId', $internalId);
|
||||
/**
|
||||
* Add Internal ID 'databaseInternalId' for Subqueries.
|
||||
*/
|
||||
$document->setAttribute('databaseInternalId', '1');
|
||||
/**
|
||||
* Add Internal ID 'databaseId'.
|
||||
*/
|
||||
$document->setAttribute('databaseId', 'default');
|
||||
|
||||
/**
|
||||
* Re-create Attribute.
|
||||
*/
|
||||
$this->projectDB->deleteDocument($document->getCollection(), $document->getId());
|
||||
$this->projectDB->createDocument($document->getCollection(), $document->setAttribute('$id', "1_{$internalId}_{$document->getAttribute('key')}"));
|
||||
} catch (\Throwable $th) {
|
||||
Console::error("Failed to {$type} document: " . $th->getMessage());
|
||||
}
|
||||
}, $document, $collection->getInternalId(), $type);
|
||||
}
|
||||
} while ($offset < $attributesCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate all Collections.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function migrateCollections(): void
|
||||
{
|
||||
foreach ($this->collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
Console::log("- {$id}");
|
||||
|
||||
$this->createNewMetaData($id);
|
||||
|
||||
$this->projectDB->setNamespace("_{$this->project->getInternalId()}");
|
||||
|
||||
switch ($id) {
|
||||
case 'attributes':
|
||||
case 'indexes':
|
||||
try {
|
||||
/**
|
||||
* Create 'databaseInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'databaseId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'databaseInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create 'databaseInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'databaseInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'databaseInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Create 'collectionInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'collectionInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'collectionInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_collection' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_collection');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_db_collection');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_collection' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'projects':
|
||||
try {
|
||||
/**
|
||||
* Create 'teamInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'teamInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'teamInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'platforms':
|
||||
case 'domains':
|
||||
try {
|
||||
/**
|
||||
* Create 'projectInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_project' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_project');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'keys':
|
||||
try {
|
||||
/**
|
||||
* Create 'projectInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create 'expire' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'expire');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'expire' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_project' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_project');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'webhooks':
|
||||
try {
|
||||
/**
|
||||
* Create 'signatureKey' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'signatureKey');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'signatureKey' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create 'projectInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_project' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_project');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'users':
|
||||
try {
|
||||
/**
|
||||
* Create 'phone' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'phone');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'phone' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create 'phoneVerification' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'phoneVerification');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'phoneVerification' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create '_key_phone' index
|
||||
*/
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_phone');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_phone' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'tokens':
|
||||
case 'sessions':
|
||||
try {
|
||||
/**
|
||||
* Create 'userInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'userInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_user' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_user');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_user');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'memberships':
|
||||
try {
|
||||
/**
|
||||
* Create 'teamInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'teamInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'teamInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create 'userInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'userInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_unique' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_unique');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_unique');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_unique' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_team' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_team');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_team');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_team' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Re-Create '_key_user' index
|
||||
*/
|
||||
@$this->projectDB->deleteIndex($id, '_key_user');
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_user');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
usleep(50000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
* @param \Utopia\Database\Document $document
|
||||
* @return \Utopia\Database\Document
|
||||
*/
|
||||
protected function fixDocument(Document $document)
|
||||
{
|
||||
switch ($document->getCollection()) {
|
||||
case 'projects':
|
||||
/**
|
||||
* Bump Project version number.
|
||||
*/
|
||||
$document->setAttribute('version', '0.15.0');
|
||||
|
||||
if (!empty($document->getAttribute('teamId')) && is_null($document->getAttribute('teamInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('teams', $document->getAttribute('teamId'))->getInternalId();
|
||||
$document->setAttribute('teamInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'keys':
|
||||
/**
|
||||
* Add new 'expire' attribute and default to never (0).
|
||||
*/
|
||||
if (is_null($document->getAttribute('expire'))) {
|
||||
$document->setAttribute('expire', 0);
|
||||
}
|
||||
/**
|
||||
* Add Internal ID 'projectId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('projectId')) && is_null($document->getAttribute('projectInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('projects', $document->getAttribute('projectId'))->getInternalId();
|
||||
$document->setAttribute('projectInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'audit':
|
||||
/**
|
||||
* Add Database Layer to collection resource.
|
||||
*/
|
||||
if (str_starts_with($document->getAttribute('resource'), 'collection/')) {
|
||||
$document
|
||||
->setAttribute('resource', "database/default/{$document->getAttribute('resource')}")
|
||||
->setAttribute('event', "databases.default.{$document->getAttribute('event')}");
|
||||
}
|
||||
|
||||
if (str_starts_with($document->getAttribute('resource'), 'document/')) {
|
||||
$collectionId = explode('.', $document->getAttribute('event'))[1];
|
||||
$document
|
||||
->setAttribute('resource', "database/default/collection/{$collectionId}/{$document->getAttribute('resource')}")
|
||||
->setAttribute('event', "databases.default.{$document->getAttribute('event')}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'stats':
|
||||
/**
|
||||
* Add Database Layer to stats metric.
|
||||
*/
|
||||
if (str_starts_with($document->getAttribute('metric'), 'database.')) {
|
||||
$metric = ltrim($document->getAttribute('metric'), 'database.');
|
||||
$document->setAttribute('metric', "databases.default.{$metric}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'webhooks':
|
||||
/**
|
||||
* Add new 'signatureKey' attribute and generate a random value.
|
||||
*/
|
||||
if (empty($document->getAttribute('signatureKey'))) {
|
||||
$document->setAttribute('signatureKey', \bin2hex(\random_bytes(64)));
|
||||
}
|
||||
/**
|
||||
* Add Internal ID 'projectId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('projectId')) && is_null($document->getAttribute('projectInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('projects', $document->getAttribute('projectId'))->getInternalId();
|
||||
$document->setAttribute('projectInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'domains':
|
||||
/**
|
||||
* Add Internal ID 'projectId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('projectId')) && is_null($document->getAttribute('projectInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('projects', $document->getAttribute('projectId'))->getInternalId();
|
||||
$document->setAttribute('projectInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'tokens':
|
||||
case 'sessions':
|
||||
/**
|
||||
* Add Internal ID 'userId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('userId')) && is_null($document->getAttribute('userInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('users', $document->getAttribute('userId'))->getInternalId();
|
||||
$document->setAttribute('userInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'memberships':
|
||||
/**
|
||||
* Add Internal ID 'userId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('userId')) && is_null($document->getAttribute('userInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('users', $document->getAttribute('userId'))->getInternalId();
|
||||
$document->setAttribute('userInternalId', $internalId);
|
||||
}
|
||||
/**
|
||||
* Add Internal ID 'teamId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('teamId')) && is_null($document->getAttribute('teamInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('teams', $document->getAttribute('teamId'))->getInternalId();
|
||||
$document->setAttribute('teamInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'platforms':
|
||||
/**
|
||||
* Migrate dateCreated to $createdAt.
|
||||
*/
|
||||
if (empty($document->getCreatedAt())) {
|
||||
$document->setAttribute('$createdAt', $document->getAttribute('dateCreated'));
|
||||
}
|
||||
/**
|
||||
* Migrate dateUpdated to $updatedAt.
|
||||
*/
|
||||
if (empty($document->getUpdatedAt())) {
|
||||
$document->setAttribute('$updatedAt', $document->getAttribute('dateUpdated'));
|
||||
}
|
||||
/**
|
||||
* Add Internal ID 'projectId' for Subqueries.
|
||||
*/
|
||||
if (!empty($document->getAttribute('projectId')) && is_null($document->getAttribute('projectInternalId'))) {
|
||||
$internalId = $this->projectDB->getDocument('projects', $document->getAttribute('projectId'))->getInternalId();
|
||||
$document->setAttribute('projectInternalId', $internalId);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'buckets':
|
||||
/**
|
||||
* Migrate dateCreated to $createdAt.
|
||||
*/
|
||||
if (empty($document->getCreatedAt())) {
|
||||
$document->setAttribute('$createdAt', $document->getAttribute('dateCreated'));
|
||||
}
|
||||
/**
|
||||
* Migrate dateUpdated to $updatedAt.
|
||||
*/
|
||||
if (empty($document->getUpdatedAt())) {
|
||||
$document->setAttribute('$updatedAt', $document->getAttribute('dateUpdated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate all Storage Buckets to use Internal ID.
|
||||
*/
|
||||
$internalId = $this->projectDB->getDocument('buckets', $document->getId())->getInternalId();
|
||||
$this->createNewMetaData("bucket_{$internalId}");
|
||||
|
||||
/**
|
||||
* Migrate all Storage Bucket Files.
|
||||
*/
|
||||
$this->migrateBucketFiles($document);
|
||||
|
||||
break;
|
||||
case 'users':
|
||||
/**
|
||||
* Set 'phoneVerification' to false if not set.
|
||||
*/
|
||||
if (is_null($document->getAttribute('phoneVerification'))) {
|
||||
$document->setAttribute('phoneVerification', false);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'functions':
|
||||
/**
|
||||
* Migrate dateCreated to $createdAt.
|
||||
*/
|
||||
if (empty($document->getCreatedAt())) {
|
||||
$document->setAttribute('$createdAt', $document->getAttribute('dateCreated'));
|
||||
}
|
||||
/**
|
||||
* Migrate dateUpdated to $updatedAt.
|
||||
*/
|
||||
if (empty($document->getUpdatedAt())) {
|
||||
$document->setAttribute('$updatedAt', $document->getAttribute('dateUpdated'));
|
||||
}
|
||||
|
||||
break;
|
||||
case 'deployments':
|
||||
case 'executions':
|
||||
case 'teams':
|
||||
/**
|
||||
* Migrate dateCreated to $createdAt.
|
||||
*/
|
||||
if (empty($document->getCreatedAt())) {
|
||||
$document->setAttribute('$createdAt', $document->getAttribute('dateCreated'));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new metadata that was introduced for a collection and enforces the Internal ID.
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
protected function createNewMetaData(string $id, string $to = null): void
|
||||
{
|
||||
$to ??= $id;
|
||||
/**
|
||||
* Skip files collection.
|
||||
*/
|
||||
if (in_array($id, ['files', 'databases'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
/**
|
||||
* Replace project UID with Internal ID.
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getId()}_{$id}` RENAME TO `_{$this->project->getInternalId()}_{$to}`")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Replace project UID with Internal ID on permissions table.
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getId()}_{$id}_perms` RENAME TO `_{$this->project->getInternalId()}_{$to}_perms`")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Add _createdAt attribute.
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE `_{$this->project->getInternalId()}_{$to}` ADD COLUMN IF NOT EXISTS `_createdAt` int unsigned DEFAULT NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Add _updatedAt attribute.
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE `_{$this->project->getInternalId()}_{$to}` ADD COLUMN IF NOT EXISTS `_updatedAt` int unsigned DEFAULT NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create index for _createdAt.
|
||||
*/
|
||||
$this->pdo->prepare("CREATE INDEX IF NOT EXISTS `_created_at` ON `_{$this->project->getInternalId()}_{$to}` (`_createdAt`)")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
try {
|
||||
/**
|
||||
* Create index for _updatedAt.
|
||||
*/
|
||||
$this->pdo->prepare("CREATE INDEX IF NOT EXISTS `_updated_at` ON `_{$this->project->getInternalId()}_{$to}` (`_updatedAt`)")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating {$id} Collection: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
1489
src/Appwrite/Migration/Version/V15.php
Normal file
1489
src/Appwrite/Migration/Version/V15.php
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -36,12 +36,18 @@ class Document extends Any
|
|||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('$collection', [
|
||||
->addRule('$collectionId', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Collection ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c15117e',
|
||||
])
|
||||
->addRule('$databaseId', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Database ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c15117e',
|
||||
])
|
||||
->addRule('$createdAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Document creation date in ISO 8601 format.',
|
||||
|
|
@ -60,13 +66,13 @@ class Document extends Any
|
|||
'default' => '',
|
||||
'example' => ['read("any")'],
|
||||
'array' => true,
|
||||
])
|
||||
;
|
||||
]);
|
||||
}
|
||||
|
||||
public function filter(DatabaseDocument $document): DatabaseDocument
|
||||
{
|
||||
$document->removeAttribute('$internalId');
|
||||
$document->removeAttribute('$collection'); // $collection is the internal collection ID
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -938,6 +938,9 @@ trait DatabasesBase
|
|||
]);
|
||||
|
||||
$this->assertEquals(201, $document1['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document1['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document1['body']);
|
||||
$this->assertEquals($databaseId, $document1['body']['$databaseId']);
|
||||
$this->assertEquals($document1['body']['title'], 'Captain America');
|
||||
$this->assertEquals($document1['body']['releaseYear'], 1944);
|
||||
$this->assertIsArray($document1['body']['$permissions']);
|
||||
|
|
@ -948,6 +951,9 @@ trait DatabasesBase
|
|||
$this->assertEquals($document1['body']['birthDay'], '1975-06-12T12:12:55.000+00:00');
|
||||
|
||||
$this->assertEquals(201, $document2['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document2['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document2['body']);
|
||||
$this->assertEquals($databaseId, $document2['body']['$databaseId']);
|
||||
$this->assertEquals($document2['body']['title'], 'Spider-Man: Far From Home');
|
||||
$this->assertEquals($document2['body']['releaseYear'], 2019);
|
||||
$this->assertEquals($document2['body']['duration'], null);
|
||||
|
|
@ -960,6 +966,9 @@ trait DatabasesBase
|
|||
$this->assertEquals($document2['body']['birthDay'], null);
|
||||
|
||||
$this->assertEquals(201, $document3['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document3['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document3['body']);
|
||||
$this->assertEquals($databaseId, $document3['body']['$databaseId']);
|
||||
$this->assertEquals($document3['body']['title'], 'Spider-Man: Homecoming');
|
||||
$this->assertEquals($document3['body']['releaseYear'], 2017);
|
||||
$this->assertEquals($document3['body']['duration'], 0);
|
||||
|
|
@ -968,7 +977,7 @@ trait DatabasesBase
|
|||
$this->assertCount(2, $document3['body']['actors']);
|
||||
$this->assertEquals($document3['body']['actors'][0], 'Tom Holland');
|
||||
$this->assertEquals($document3['body']['actors'][1], 'Zendaya Maree Stoermer');
|
||||
$this->assertEquals($document3['body']['birthDay'], '1975-06-12T18:12:55.000+00:00');// UTC for NY
|
||||
$this->assertEquals($document3['body']['birthDay'], '1975-06-12T18:12:55.000+00:00'); // UTC for NY
|
||||
|
||||
$this->assertEquals(400, $document4['headers']['status-code']);
|
||||
|
||||
|
|
@ -985,7 +994,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -998,14 +1007,16 @@ trait DatabasesBase
|
|||
$this->assertCount(3, $documents['body']['documents']);
|
||||
|
||||
foreach ($documents['body']['documents'] as $document) {
|
||||
$this->assertEquals($data['moviesId'], $document['$collection']);
|
||||
$this->assertEquals($data['moviesId'], $document['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document);
|
||||
$this->assertEquals($databaseId, $document['$databaseId']);
|
||||
}
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderDesc("releaseYear")' ],
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1080,14 +1091,16 @@ trait DatabasesBase
|
|||
{
|
||||
$databaseId = $data['databaseId'];
|
||||
foreach ($data['documents'] as $document) {
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $document['$collection'] . '/documents/' . $document['$id'], array_merge([
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $document['$collectionId'] . '/documents/' . $document['$id'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals($response['body']['$id'], $document['$id']);
|
||||
$this->assertEquals($response['body']['$collection'], $document['$collection']);
|
||||
$this->assertEquals($document['$collectionId'], $response['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $response['body']);
|
||||
$this->assertEquals($document['$databaseId'], $response['body']['$databaseId']);
|
||||
$this->assertEquals($response['body']['title'], $document['title']);
|
||||
$this->assertEquals($response['body']['releaseYear'], $document['releaseYear']);
|
||||
$this->assertEquals($response['body']['$permissions'], $document['$permissions']);
|
||||
|
|
@ -1120,7 +1133,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $base['body']['documents'][0]['$id'] . '")' ],
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][0]['$id'] . '")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1132,7 +1145,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $base['body']['documents'][2]['$id'] . '")' ],
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][2]['$id'] . '")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1145,7 +1158,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
|
|
@ -1158,7 +1171,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1172,7 +1185,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderDesc("releaseYear")' ],
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
|
|
@ -1185,7 +1198,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")' ],
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1199,7 +1212,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("unknown")' ],
|
||||
'queries' => ['cursorAfter("unknown")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
|
|
@ -1231,7 +1244,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $base['body']['documents'][2]['$id'] . '")' ],
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][2]['$id'] . '")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1243,7 +1256,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $base['body']['documents'][0]['$id'] . '")' ],
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][0]['$id'] . '")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1256,7 +1269,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
|
|
@ -1269,7 +1282,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1283,7 +1296,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderDesc("releaseYear")' ],
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
|
|
@ -1296,7 +1309,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")' ],
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1316,7 +1329,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)', 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['limit(1)', 'orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1327,7 +1340,7 @@ trait DatabasesBase
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(2)', 'offset(1)', 'orderAsc("releaseYear")' ],
|
||||
'queries' => ['limit(2)', 'offset(1)', 'orderAsc("releaseYear")'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
|
|
@ -1514,6 +1527,9 @@ trait DatabasesBase
|
|||
$id = $document['body']['$id'];
|
||||
|
||||
$this->assertEquals(201, $document['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document['body']);
|
||||
$this->assertEquals($databaseId, $document['body']['$databaseId']);
|
||||
$this->assertEquals($document['body']['title'], 'Thor: Ragnaroc');
|
||||
$this->assertEquals($document['body']['releaseYear'], 2017);
|
||||
$this->assertEquals(true, DateTime::isValid($document['body']['$createdAt']));
|
||||
|
|
@ -1538,7 +1554,9 @@ trait DatabasesBase
|
|||
|
||||
$this->assertEquals(200, $document['headers']['status-code']);
|
||||
$this->assertEquals($document['body']['$id'], $id);
|
||||
$this->assertEquals($document['body']['$collection'], $data['moviesId']);
|
||||
$this->assertEquals($data['moviesId'], $document['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document['body']);
|
||||
$this->assertEquals($databaseId, $document['body']['$databaseId']);
|
||||
$this->assertEquals($document['body']['title'], 'Thor: Ragnarok');
|
||||
$this->assertEquals($document['body']['releaseYear'], 2017);
|
||||
$this->assertContains(Permission::read(Role::users()), $document['body']['$permissions']);
|
||||
|
|
@ -1553,6 +1571,9 @@ trait DatabasesBase
|
|||
$id = $document['body']['$id'];
|
||||
|
||||
$this->assertEquals(200, $document['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document['body']['$collectionId']);
|
||||
$this->assertArrayNotHasKey('$collection', $document['body']);
|
||||
$this->assertEquals($databaseId, $document['body']['$databaseId']);
|
||||
$this->assertEquals($document['body']['title'], 'Thor: Ragnarok');
|
||||
$this->assertEquals($document['body']['releaseYear'], 2017);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace Tests\Unit\Event\Validator;
|
|||
|
||||
use Appwrite\Event\Validator\Event;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
class EventValidatorTest extends TestCase
|
||||
{
|
||||
|
|
@ -12,7 +11,6 @@ class EventValidatorTest extends TestCase
|
|||
|
||||
public function setUp(): void
|
||||
{
|
||||
Config::load('events', __DIR__ . '/../../../../app/config/events.php');
|
||||
$this->object = new Event();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Migration;
|
||||
|
||||
use ReflectionClass;
|
||||
use Appwrite\Migration\Version\V12;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\ID;
|
||||
|
||||
class MigrationV12Test extends MigrationTest
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->migration = new V12();
|
||||
$reflector = new ReflectionClass('Appwrite\Migration\Version\V12');
|
||||
$this->method = $reflector->getMethod('fixDocument');
|
||||
$this->method->setAccessible(true);
|
||||
}
|
||||
|
||||
public function testMigrationProjects(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('project'),
|
||||
'$collection' => ID::custom('projects'),
|
||||
'name' => 'Appwrite',
|
||||
'version' => '0.12.0',
|
||||
'search' => ''
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('version'), '0.13.0');
|
||||
$this->assertEquals($document->getAttribute('search'), 'project Appwrite');
|
||||
}
|
||||
|
||||
public function testMigrationUsers(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('user'),
|
||||
'$collection' => ID::custom('users'),
|
||||
'email' => 'test@appwrite.io',
|
||||
'name' => 'Torsten Dittmann'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('search'), 'user test@appwrite.io Torsten Dittmann');
|
||||
}
|
||||
|
||||
public function testMigrationTeams(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('team'),
|
||||
'$collection' => ID::custom('teams'),
|
||||
'name' => 'Appwrite'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('search'), 'team Appwrite');
|
||||
}
|
||||
|
||||
public function testMigrationFunctions(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('function'),
|
||||
'$collection' => ID::custom('functions'),
|
||||
'name' => 'My Function',
|
||||
'runtime' => 'php-8.0'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('search'), 'function My Function php-8.0');
|
||||
}
|
||||
|
||||
public function testMigrationExecutions(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('execution'),
|
||||
'$collection' => ID::custom('executions'),
|
||||
'functionId' => ID::custom('function')
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('search'), 'execution function');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Migration;
|
||||
|
||||
use ReflectionClass;
|
||||
use Appwrite\Migration\Version\V13;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\ID;
|
||||
|
||||
class MigrationV13Test extends MigrationTest
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->migration = new V13();
|
||||
$reflector = new ReflectionClass('Appwrite\Migration\Version\V13');
|
||||
$this->method = $reflector->getMethod('fixDocument');
|
||||
$this->method->setAccessible(true);
|
||||
}
|
||||
|
||||
public function testMigrateFunctions(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('func'),
|
||||
'$collection' => ID::custom('functions'),
|
||||
'events' => ['account.create', 'users.create']
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('events'), ['users.*.create']);
|
||||
}
|
||||
|
||||
public function testMigrationWebhooks(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('webh'),
|
||||
'$collection' => ID::custom('webhooks'),
|
||||
'events' => ['account.create', 'users.create']
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('events'), ['users.*.create']);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Migration;
|
||||
|
||||
use ReflectionClass;
|
||||
use Appwrite\Migration\Version\V14;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\ID;
|
||||
|
||||
class MigrationV14Test extends MigrationTest
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->migration = new V14();
|
||||
$reflector = new ReflectionClass('Appwrite\Migration\Version\V14');
|
||||
$this->method = $reflector->getMethod('fixDocument');
|
||||
$this->method->setAccessible(true);
|
||||
}
|
||||
|
||||
public function testMigrateProjects(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('projects'),
|
||||
'version' => '0.14.0'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('version'), '0.15.0');
|
||||
$this->assertEquals($document->getAttribute('version'), '0.15.0');
|
||||
}
|
||||
|
||||
public function testMigrateKeys(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => 'keys'
|
||||
]));
|
||||
|
||||
$this->assertArrayHasKey('expire', $document->getArrayCopy());
|
||||
$this->assertEquals($document->getAttribute('expire'), 0);
|
||||
}
|
||||
|
||||
public function testMigrateWebhooks(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => 'webhooks'
|
||||
]));
|
||||
|
||||
$this->assertArrayHasKey('signatureKey', $document->getArrayCopy());
|
||||
$this->assertEquals(strlen($document->getAttribute('signatureKey')), 128);
|
||||
}
|
||||
|
||||
public function testMigrateUsers(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('users'),
|
||||
'phoneVerification' => null
|
||||
]));
|
||||
|
||||
$this->assertArrayHasKey('phoneVerification', $document->getArrayCopy());
|
||||
$this->assertFalse($document->getAttribute('phoneVerification'));
|
||||
}
|
||||
|
||||
public function testMigratePlatforms(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'$createdAt' => null,
|
||||
'$updatedAt' => null,
|
||||
'dateCreated' => 123456789,
|
||||
'dateUpdated' => 987654321
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getCreatedAt(), 123456789);
|
||||
$this->assertEquals($document->getUpdatedAt(), 987654321);
|
||||
}
|
||||
|
||||
public function testMigrateFunctions(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('functions'),
|
||||
'$createdAt' => null,
|
||||
'$updatedAt' => null,
|
||||
'dateCreated' => 123456789,
|
||||
'dateUpdated' => 987654321
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getCreatedAt(), 123456789);
|
||||
$this->assertEquals($document->getUpdatedAt(), 987654321);
|
||||
}
|
||||
|
||||
public function testMigrateDeployments(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('deployments'),
|
||||
'$createdAt' => null,
|
||||
'dateCreated' => 123456789,
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getCreatedAt(), 123456789);
|
||||
}
|
||||
|
||||
public function testMigrateExecutions(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('executions'),
|
||||
'$createdAt' => null,
|
||||
'dateCreated' => 123456789,
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getCreatedAt(), 123456789);
|
||||
}
|
||||
|
||||
public function testMigrateTeams(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('teams'),
|
||||
'$createdAt' => null,
|
||||
'dateCreated' => 123456789,
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getCreatedAt(), 123456789);
|
||||
}
|
||||
|
||||
public function testMigrateAudits(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('audit'),
|
||||
'resource' => 'collection/movies',
|
||||
'event' => 'collections.movies.create'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('resource'), 'database/default/collection/movies');
|
||||
$this->assertEquals($document->getAttribute('event'), 'databases.default.collections.movies.create');
|
||||
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('audit'),
|
||||
'resource' => 'document/avatar',
|
||||
'event' => 'collections.movies.documents.avatar.create'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('resource'), 'database/default/collection/movies/document/avatar');
|
||||
$this->assertEquals($document->getAttribute('event'), 'databases.default.collections.movies.documents.avatar.create');
|
||||
}
|
||||
|
||||
public function testMigrateStats(): void
|
||||
{
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('stats'),
|
||||
'metric' => 'database.collections.62b2039844d4277495d0.documents.create'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('metric'), 'databases.default.collections.62b2039844d4277495d0.documents.create');
|
||||
|
||||
$document = $this->fixDocument(new Document([
|
||||
'$id' => ID::custom('appwrite'),
|
||||
'$collection' => ID::custom('stats'),
|
||||
'metric' => 'users.create'
|
||||
]));
|
||||
|
||||
$this->assertEquals($document->getAttribute('metric'), 'users.create');
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue