mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 17:08:45 +00:00
commit
a001e5a473
518 changed files with 15332 additions and 3013 deletions
28
CHANGES.md
28
CHANGES.md
|
|
@ -1,3 +1,31 @@
|
|||
# Version 0.6.0 (PRE-RELEASE)
|
||||
|
||||
## Features
|
||||
|
||||
* New collections UI with ability to create and update a collection
|
||||
* New documents UI with ability to create and update a document
|
||||
* Added support for Flutter iOS & Android apps
|
||||
* Added support for default DB document values
|
||||
* Exposed health API to all the server SDKs
|
||||
* New locale for Khmer
|
||||
* Added TypeScript type hinting to the JS SDK (@zevektor)
|
||||
* Added LTR/RTL support for markdown editor
|
||||
* Added cachebuster to version number on footer
|
||||
* New OAuth logos
|
||||
* Minor fixes to the dark mode theme
|
||||
* Added JSON view for a project user
|
||||
* Removed setKey and setMode methods from all client SDKs
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
* Updated all the REST API query params to be in camelCase
|
||||
* Normalized locale phone codes response body
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* Fixed project users logout button
|
||||
* Fixed wrong target in database back link
|
||||
|
||||
# Version 0.5.3 (PRE-RELEASE)
|
||||
|
||||
## Bug Fixes
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ Before running the command, make sure you have proper write permissions to the A
|
|||
To run tests manually, run phpunit from your command line:
|
||||
|
||||
```bash
|
||||
docker exec appwrite /bin/bash -c '/usr/share/nginx/html/vendor/bin/phpunit'
|
||||
docker exec appwrite test
|
||||
```
|
||||
|
||||
## Tutorials
|
||||
|
|
|
|||
|
|
@ -126,8 +126,12 @@ COPY --from=builder /usr/local/src/vendor /usr/share/nginx/html/vendor
|
|||
|
||||
RUN mkdir -p /storage/uploads && \
|
||||
mkdir -p /storage/cache && \
|
||||
mkdir -p /storage/config && \
|
||||
mkdir -p /storage/certificates && \
|
||||
chown -Rf www-data.www-data /storage/uploads && chmod -Rf 0755 /storage/uploads && \
|
||||
chown -Rf www-data.www-data /storage/cache && chmod -Rf 0755 /storage/cache
|
||||
chown -Rf www-data.www-data /storage/cache && chmod -Rf 0755 /storage/cache && \
|
||||
chown -Rf www-data.www-data /storage/config && chmod -Rf 0755 /storage/config && \
|
||||
chown -Rf www-data.www-data /storage/certificates && chmod -Rf 0755 /storage/certificates
|
||||
|
||||
# Supervisord Conf
|
||||
COPY ./docker/supervisord.conf /etc/supervisord.conf
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ The easiest way to start running your Appwrite server is by running our docker-c
|
|||
docker run -it --rm \
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume "$(pwd)"/appwrite:/install/appwrite:rw \
|
||||
-e version=0.5.3 \
|
||||
-e version=0.6.0 \
|
||||
appwrite/install
|
||||
```
|
||||
|
||||
|
|
|
|||
28
app/app.php
28
app/app.php
|
|
@ -16,6 +16,7 @@ use Appwrite\Database\Database;
|
|||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Network\Validators\Origin;
|
||||
|
||||
/*
|
||||
* Configuration files
|
||||
|
|
@ -51,11 +52,11 @@ $clients = array_unique(array_merge($clientsConsole, array_map(function ($node)
|
|||
return false;
|
||||
}))));
|
||||
|
||||
$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $roles, $webhook, $audit, $usage, $clients) {
|
||||
$utopia->init(function () use ($utopia, $request, $response, &$user, $project, $console, $roles, $webhook, $audit, $usage, $clients) {
|
||||
|
||||
$route = $utopia->match($request);
|
||||
|
||||
if(!empty($route->getLabel('sdk.platform', [])) && empty($project->getId())) {
|
||||
if(!empty($route->getLabel('sdk.platform', [])) && empty($project->getId()) && ($route->getLabel('scope', '') !== 'public')) {
|
||||
throw new Exception('Missing or unknown project ID', 400);
|
||||
}
|
||||
|
||||
|
|
@ -96,16 +97,15 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
|
|||
* Adding Appwrite API domains to allow XDOMAIN communication
|
||||
* Skip this check for non-web platforms which are not requiredto send an origin header
|
||||
*/
|
||||
$origin = parse_url($request->getServer('HTTP_ORIGIN', $request->getServer('HTTP_REFERER', '')), PHP_URL_HOST);
|
||||
|
||||
if (!empty($origin)
|
||||
&& !in_array($origin, $clients)
|
||||
&& in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
|
||||
&& empty($request->getHeader('X-Appwrite-Key', ''))
|
||||
) {
|
||||
throw new Exception('Access from this client host is forbidden', 403);
|
||||
}
|
||||
$origin = $request->getServer('HTTP_ORIGIN', $request->getServer('HTTP_REFERER', ''));
|
||||
$originValidator = new Origin(array_merge($project->getAttribute('platforms', []), $console->getAttribute('platforms', [])));
|
||||
|
||||
if(!$originValidator->isValid($origin)
|
||||
&& in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
|
||||
&& empty($request->getHeader('X-Appwrite-Key', ''))) {
|
||||
throw new Exception($originValidator->getDescription(), 403);
|
||||
}
|
||||
|
||||
/*
|
||||
* ACL Check
|
||||
*/
|
||||
|
|
@ -410,12 +410,6 @@ $utopia->get('/.well-known/acme-challenge')
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$name = APP_NAME;
|
||||
|
||||
if (array_key_exists($service, $services)) { /** @noinspection PhpIncludeInspection */
|
||||
|
|
|
|||
|
|
@ -1,60 +1,45 @@
|
|||
<?php
|
||||
|
||||
const APP_PLATFORM_WEB = 'web';
|
||||
const APP_PLATFORM_IOS = 'ios';
|
||||
const APP_PLATFORM_ANDROID = 'android';
|
||||
const APP_PLATFORM_UNITY = 'unity';
|
||||
const APP_PLATFORM_FLUTTER = 'flutter';
|
||||
|
||||
const APP_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
|
||||
return [
|
||||
APP_PLATFORM_WEB => [
|
||||
'key' => APP_PLATFORM_WEB,
|
||||
'name' => 'Web',
|
||||
'description' => 'Client libraries for integrating with '.APP_NAME.' to build web-based applications and websites. Read the [getting started for web](/docs/getting-started-for-web) tutorial to start building your first web application.',
|
||||
APP_PLATFORM_CLIENT => [
|
||||
'key' => APP_PLATFORM_CLIENT,
|
||||
'name' => 'Client',
|
||||
'description' => 'Client libraries for integrating with '.APP_NAME.' to build client-based applications and websites. Read the [getting started for web](/docs/getting-started-for-web) or [getting started for Flutter](/docs/getting-started-for-flutter) tutorials to start building your first application.',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
[
|
||||
'key' => 'javascript',
|
||||
'name' => 'JavaScript',
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '1.0.29',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-js',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
'prism' => 'javascript',
|
||||
'source' => realpath(__DIR__ . '/../sdks/web-javascript'),
|
||||
'source' => realpath(__DIR__ . '/../sdks/client-web'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-js.git',
|
||||
'gitRepoName' => 'sdk-for-js',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
[
|
||||
'key' => 'typescript',
|
||||
'name' => 'TypeScript',
|
||||
'url' => '',
|
||||
'enabled' => false,
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '0.2.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
'prism' => 'typescript',
|
||||
'source' => false,
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-typescript.git',
|
||||
'gitRepoName' => 'sdk-for-typescript',
|
||||
'prism' => 'dart',
|
||||
'source' => realpath(__DIR__ . '/../sdks/client-flutter'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-flutter.git',
|
||||
'gitRepoName' => 'sdk-for-flutter',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
APP_PLATFORM_IOS => [
|
||||
'key' => APP_PLATFORM_IOS,
|
||||
'name' => 'iOS',
|
||||
'description' => 'Client libraries for integrating with '.APP_NAME.' to build iOS applications. Read the [getting started for iOS](/docs/getting-started-for-ios) tutorial to start building your first iOS application.',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
|
|
@ -81,16 +66,6 @@ return [
|
|||
'gitRepoName' => 'sdk-for-objective-c',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
APP_PLATFORM_ANDROID => [
|
||||
'key' => APP_PLATFORM_ANDROID,
|
||||
'name' => 'Android',
|
||||
'description' => 'Client libraries for integrating with '.APP_NAME.' to build Android applications. Read the [getting started for Android](/docs/getting-started-for-android) tutorial to start building your first Android application.',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'kotlin',
|
||||
'name' => 'Kotlin',
|
||||
|
|
@ -104,62 +79,38 @@ return [
|
|||
'gitRepoName' => 'sdk-for-kotlin',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
[
|
||||
'key' => 'java',
|
||||
'name' => 'Java',
|
||||
'url' => '',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
'prism' => 'java',
|
||||
'source' => false,
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-java.git',
|
||||
'gitRepoName' => 'sdk-for-java',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
// [
|
||||
// 'key' => 'java',
|
||||
// 'name' => 'Java',
|
||||
// 'url' => '',
|
||||
// 'enabled' => false,
|
||||
// 'beta' => false,
|
||||
// 'family' => APP_PLATFORM_CLIENT,
|
||||
// 'prism' => 'java',
|
||||
// 'source' => false,
|
||||
// 'gitUrl' => 'git@github.com:appwrite/sdk-for-java.git',
|
||||
// 'gitRepoName' => 'sdk-for-java',
|
||||
// 'gitUserName' => 'appwrite',
|
||||
// ],
|
||||
],
|
||||
],
|
||||
|
||||
APP_PLATFORM_FLUTTER => [
|
||||
'key' => APP_PLATFORM_FLUTTER,
|
||||
'name' => 'Flutter',
|
||||
'description' => 'Client libraries for integrating with '.APP_NAME.' to build cross-platform Flutter applications. Read the [getting started for Flutter](/docs/getting-started-for-flutter) tutorial to start building your first Flutter application.',
|
||||
'enabled' => false,
|
||||
'beta' => true,
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '0.0.8',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
'prism' => 'dart',
|
||||
'source' => realpath(__DIR__ . '/../sdks/flutter-dart'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-dart.git',
|
||||
'gitRepoName' => 'sdk-for-dart',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
APP_PLATFORM_CONSOLE => [
|
||||
'key' => APP_PLATFORM_CONSOLE,
|
||||
'name' => 'Console',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
[
|
||||
'key' => 'javascript',
|
||||
'name' => 'JS',
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
'version' => '1.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-console',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'family' => APP_PLATFORM_CONSOLE,
|
||||
'prism' => 'console',
|
||||
'source' => realpath(__DIR__ . '/../sdks/console-javascript'),
|
||||
'source' => realpath(__DIR__ . '/../sdks/console-web'),
|
||||
'gitUrl' => null,
|
||||
'gitRepoName' => 'sdk-for-console',
|
||||
'gitUserName' => 'appwrite',
|
||||
|
|
@ -173,7 +124,7 @@ return [
|
|||
'description' => 'Libraries for integrating with '.APP_NAME.' to build server side integrations. Read the [getting started for server](/docs/getting-started-for-server) tutorial to start building your first server integration.',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'languages' => [
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
|
|
@ -235,7 +186,7 @@ return [
|
|||
'name' => 'Go',
|
||||
'version' => '0.0.6',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-go',
|
||||
'enabled' => true,
|
||||
'enabled' => false,
|
||||
'beta' => true,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
'prism' => 'go',
|
||||
|
|
@ -244,7 +195,34 @@ return [
|
|||
'gitRepoName' => 'sdk-for-go',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
[
|
||||
'key' => 'java',
|
||||
'name' => 'Java',
|
||||
'version' => '0.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-java',
|
||||
'enabled' => false,
|
||||
'beta' => true,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
'prism' => 'java',
|
||||
'source' => realpath(__DIR__ . '/../sdks/server-java'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-java.git',
|
||||
'gitRepoName' => 'sdk-for-java',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '0.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'enabled' => false,
|
||||
'beta' => true,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
'prism' => 'java',
|
||||
'source' => realpath(__DIR__ . '/../sdks/server-dart'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-dart.git',
|
||||
'gitRepoName' => 'sdk-for-dart',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -21,4 +21,5 @@ return [ // List of publicly visible scopes
|
|||
// 'webhooks.write',
|
||||
'locale.read',
|
||||
'avatars.read',
|
||||
'health.read',
|
||||
];;
|
||||
|
|
@ -43,8 +43,9 @@ return [
|
|||
],
|
||||
'v1/health' => [
|
||||
'name' => 'Health',
|
||||
'description' => '/docs/services/health.md',
|
||||
'controller' => 'controllers/api/health.php',
|
||||
'sdk' => false,
|
||||
'sdk' => true,
|
||||
'tests' => false,
|
||||
],
|
||||
'v1/projects' => [
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ use GeoIp2\Database\Reader;
|
|||
|
||||
include_once __DIR__ . '/../shared/api.php';
|
||||
|
||||
$oauthDefaultSuccess = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/success';
|
||||
$oauthDefaultFailure = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/failure';
|
||||
$oauthDefaultSuccess = $request->getServer('_APP_HOME').'/auth/oauth2/success';
|
||||
$oauthDefaultFailure = $request->getServer('_APP_HOME').'/auth/oauth2/failure';
|
||||
|
||||
$oauth2Keys = [];
|
||||
|
||||
|
|
@ -483,6 +483,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
if($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms
|
||||
$state['success'] = URLParser::parse($state['success']);
|
||||
$query = URLParser::parseQuery($state['success']['query']);
|
||||
$query['project'] = $project->getId();
|
||||
$query['domain'] = COOKIE_DOMAIN;
|
||||
$query['key'] = Auth::$cookieName;
|
||||
$query['secret'] = Auth::encodeSession($user->getId(), $secret);
|
||||
|
|
@ -721,7 +722,7 @@ $utopia->patch('/v1/account/password')
|
|||
->label('sdk.method', 'updatePassword')
|
||||
->label('sdk.description', '/docs/references/account/update-password.md')
|
||||
->param('password', '', function () { return new Password(); }, 'New user password.')
|
||||
->param('old-password', '', function () { return new Password(); }, 'Old user password.')
|
||||
->param('oldPassword', '', function () { return new Password(); }, 'Old user password.')
|
||||
->action(
|
||||
function ($password, $oldPassword) use ($response, $user, $projectDB, $audit, $oauth2Keys) {
|
||||
if (!Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
|
||||
|
|
@ -1119,11 +1120,11 @@ $utopia->put('/v1/account/recovery')
|
|||
->label('abuse-key', 'url:{url},userId:{param-userId}')
|
||||
->param('userId', '', function () { return new UID(); }, 'User account UID address.')
|
||||
->param('secret', '', function () { return new Text(256); }, 'Valid reset token.')
|
||||
->param('password-a', '', function () { return new Password(); }, 'New password.')
|
||||
->param('password-b', '', function () {return new Password(); }, 'New password again.')
|
||||
->param('password', '', function () { return new Password(); }, 'New password.')
|
||||
->param('passwordAgain', '', function () {return new Password(); }, 'New password again.')
|
||||
->action(
|
||||
function ($userId, $secret, $passwordA, $passwordB) use ($response, $projectDB, $audit) {
|
||||
if ($passwordA !== $passwordB) {
|
||||
function ($userId, $secret, $password, $passwordAgain) use ($response, $projectDB, $audit) {
|
||||
if ($password !== $passwordAgain) {
|
||||
throw new Exception('Passwords must match', 400);
|
||||
}
|
||||
|
||||
|
|
@ -1149,7 +1150,7 @@ $utopia->put('/v1/account/recovery')
|
|||
Authorization::setRole('user:'.$profile->getId());
|
||||
|
||||
$profile = $projectDB->updateDocument(array_merge($profile->getArrayCopy(), [
|
||||
'password' => Auth::passwordHash($passwordA),
|
||||
'password' => Auth::passwordHash($password),
|
||||
'password-update' => time(),
|
||||
'emailVerification' => true,
|
||||
]));
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ $utopia->get('/v1/avatars/credit-cards/:code')
|
|||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'avatars')
|
||||
->label('sdk.method', 'getCreditCard')
|
||||
->label('sdk.methodType', 'location')
|
||||
->label('sdk.description', '/docs/references/avatars/get-credit-card.md')
|
||||
->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('credit-cards', $code, $width, $height, $quality);
|
||||
});
|
||||
|
|
@ -127,6 +128,7 @@ $utopia->get('/v1/avatars/flags/:code')
|
|||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'avatars')
|
||||
->label('sdk.method', 'getFlag')
|
||||
->label('sdk.methodType', 'location')
|
||||
->label('sdk.description', '/docs/references/avatars/get-flag.md')
|
||||
->action(function ($code, $width, $height, $quality) use ($avatarCallback) { return $avatarCallback('flags', $code, $width, $height, $quality);
|
||||
});
|
||||
|
|
@ -140,6 +142,7 @@ $utopia->get('/v1/avatars/image')
|
|||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'avatars')
|
||||
->label('sdk.method', 'getImage')
|
||||
->label('sdk.methodType', 'location')
|
||||
->label('sdk.description', '/docs/references/avatars/get-image.md')
|
||||
->action(
|
||||
function ($url, $width, $height) use ($response) {
|
||||
|
|
@ -206,6 +209,7 @@ $utopia->get('/v1/avatars/favicon')
|
|||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'avatars')
|
||||
->label('sdk.method', 'getFavicon')
|
||||
->label('sdk.methodType', 'location')
|
||||
->label('sdk.description', '/docs/references/avatars/get-favicon.md')
|
||||
->action(
|
||||
function ($url) use ($response, $request) {
|
||||
|
|
@ -356,12 +360,13 @@ $utopia->get('/v1/avatars/qr')
|
|||
->desc('Get QR Code')
|
||||
->param('text', '', function () { return new Text(512); }, 'Plain text to be converted to QR code image.')
|
||||
->param('size', 400, function () { return new Range(0, 1000); }, 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true)
|
||||
->param('margin', 1, function () { return new Range(0, 10); }, 'Margin From Edge. Pass an integer between 0 to 10. Defaults to 1.', true)
|
||||
->param('margin', 1, function () { return new Range(0, 10); }, 'Margin from edge. Pass an integer between 0 to 10. Defaults to 1.', true)
|
||||
->param('download', 0, function () { return new Range(0, 1); }, 'Return resulting image with \'Content-Disposition: attachment \' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
|
||||
->label('scope', 'avatars.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'avatars')
|
||||
->label('sdk.method', 'getQR')
|
||||
->label('sdk.methodType', 'location')
|
||||
->label('sdk.description', '/docs/references/avatars/get-qr.md')
|
||||
->action(
|
||||
function ($text, $size, $margin, $download) use ($response) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ use Utopia\Validator\Range;
|
|||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Audit\Adapters\MySQL as AuditAdapter;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\UID;
|
||||
|
|
@ -18,6 +21,8 @@ use Appwrite\Database\Validator\Collection;
|
|||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Exception\Authorization as AuthorizationException;
|
||||
use Appwrite\Database\Exception\Structure as StructureException;
|
||||
use DeviceDetector\DeviceDetector;
|
||||
use GeoIp2\Database\Reader;
|
||||
|
||||
include_once __DIR__ . '/../shared/api.php';
|
||||
|
||||
|
|
@ -70,6 +75,10 @@ $utopia->post('/v1/database/collections')
|
|||
throw new Exception('Failed saving document to DB', 500);
|
||||
}
|
||||
|
||||
if (false === $data) {
|
||||
throw new Exception('Failed saving collection to DB', 500);
|
||||
}
|
||||
|
||||
$data = $data->getArrayCopy();
|
||||
|
||||
$webhook
|
||||
|
|
@ -160,6 +169,70 @@ $utopia->get('/v1/database/collections/:collectionId')
|
|||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/database/collections/:collectionId/logs')
|
||||
->desc('Get Collection Logs')
|
||||
->label('scope', 'collections.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'getCollectionLogs')
|
||||
->label('sdk.description', '/docs/references/database/get-collection-logs.md')
|
||||
->param('collectionId', '', function () { return new UID(); }, 'Collection unique ID.')
|
||||
->action(
|
||||
function ($collectionId) use ($response, $register, $projectDB, $project) {
|
||||
$collection = $projectDB->getDocument($collectionId);
|
||||
|
||||
if (empty($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
|
||||
throw new Exception('Collection not found', 404);
|
||||
}
|
||||
|
||||
$adapter = new AuditAdapter($register->get('db'));
|
||||
$adapter->setNamespace('app_'.$project->getId());
|
||||
|
||||
$audit = new Audit($adapter);
|
||||
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
$logs = $audit->getLogsByResource('database/collection/'.$collection->getId());
|
||||
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$output = [];
|
||||
|
||||
foreach ($logs as $i => &$log) {
|
||||
$log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN';
|
||||
|
||||
$dd = new DeviceDetector($log['userAgent']);
|
||||
|
||||
$dd->skipBotDetection(); // OPTIONAL: If called, bot detection will completely be skipped (bots will be detected as regular devices then)
|
||||
|
||||
$dd->parse();
|
||||
|
||||
$output[$i] = [
|
||||
'event' => $log['event'],
|
||||
'ip' => $log['ip'],
|
||||
'time' => strtotime($log['time']),
|
||||
'OS' => $dd->getOs(),
|
||||
'client' => $dd->getClient(),
|
||||
'device' => $dd->getDevice(),
|
||||
'brand' => $dd->getBrand(),
|
||||
'model' => $dd->getModel(),
|
||||
'geo' => [],
|
||||
];
|
||||
|
||||
try {
|
||||
$record = $reader->country($log['ip']);
|
||||
$output[$i]['geo']['isoCode'] = strtolower($record->country->isoCode);
|
||||
$output[$i]['geo']['country'] = $record->country->name;
|
||||
$output[$i]['geo']['country'] = (isset($countries[$record->country->isoCode])) ? $countries[$record->country->isoCode] : Locale::getText('locale.country.unknown');
|
||||
} catch (\Exception $e) {
|
||||
$output[$i]['geo']['isoCode'] = '--';
|
||||
$output[$i]['geo']['country'] = Locale::getText('locale.country.unknown');
|
||||
}
|
||||
}
|
||||
|
||||
$response->json($output);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->put('/v1/database/collections/:collectionId')
|
||||
->desc('Update Collection')
|
||||
->label('scope', 'collections.write')
|
||||
|
|
@ -193,16 +266,24 @@ $utopia->put('/v1/database/collections/:collectionId')
|
|||
], $rule);
|
||||
}
|
||||
|
||||
$collection = $projectDB->updateDocument(array_merge($collection->getArrayCopy(), [
|
||||
'name' => $name,
|
||||
'structure' => true,
|
||||
'dateUpdated' => time(),
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
],
|
||||
'rules' => $rules,
|
||||
]));
|
||||
try {
|
||||
$collection = $projectDB->updateDocument(array_merge($collection->getArrayCopy(), [
|
||||
'name' => $name,
|
||||
'structure' => true,
|
||||
'dateUpdated' => time(),
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
],
|
||||
'rules' => $parsedRules,
|
||||
]));
|
||||
} catch (AuthorizationException $exception) {
|
||||
throw new Exception('Unauthorized action', 401);
|
||||
} catch (StructureException $exception) {
|
||||
throw new Exception('Bad structure. '.$exception->getMessage(), 400);
|
||||
} catch (\Exception $exception) {
|
||||
throw new Exception('Failed saving document to DB', 500);
|
||||
}
|
||||
|
||||
if (false === $collection) {
|
||||
throw new Exception('Failed saving collection to DB', 500);
|
||||
|
|
@ -336,6 +417,18 @@ $utopia->post('/v1/database/collections/:collectionId/documents')
|
|||
$data = $parentDocument->getArrayCopy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default collection values
|
||||
*/
|
||||
foreach ($collection->getAttribute('rules') as $key => $rule) {
|
||||
$key = (isset($rule['key'])) ? $rule['key'] : '';
|
||||
$default = (isset($rule['default'])) ? $rule['default'] : null;
|
||||
|
||||
if(!isset($data[$key])) {
|
||||
$data[$key] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$data = $projectDB->createDocument($data);
|
||||
} catch (AuthorizationException $exception) {
|
||||
|
|
@ -379,9 +472,9 @@ $utopia->get('/v1/database/collections/:collectionId/documents')
|
|||
->param('filters', [], function () { return new ArrayList(new Text(128)); }, 'Array of filter strings. Each filter is constructed from a key name, comparison operator (=, !=, >, <, <=, >=) and a value. You can also use a dot (.) separator in attribute names to filter by child document attributes. Examples: \'name=John Doe\' or \'category.$id>=5bed2d152c362\'.', true)
|
||||
->param('offset', 0, function () { return new Range(0, 900000000); }, 'Offset value. Use this value to manage pagination.', true)
|
||||
->param('limit', 50, function () { return new Range(0, 1000); }, 'Maximum number of documents to return in response. Use this value to manage pagination.', true)
|
||||
->param('order-field', '$id', function () { return new Text(128); }, 'Document field that results will be sorted by.', true)
|
||||
->param('order-type', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true)
|
||||
->param('order-cast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true)
|
||||
->param('orderField', '$id', function () { return new Text(128); }, 'Document field that results will be sorted by.', true)
|
||||
->param('orderType', 'ASC', function () { return new WhiteList(array('DESC', 'ASC')); }, 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true)
|
||||
->param('orderCast', 'string', function () { return new WhiteList(array('int', 'string', 'date', 'time', 'datetime')); }, 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true)
|
||||
->param('search', '', function () { return new Text(256); }, 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children.', true)
|
||||
->param('first', 0, function () { return new Range(0, 1); }, 'Return only the first document. Pass 1 for true or 0 for false. The default value is 0.', true)
|
||||
->param('last', 0, function () { return new Range(0, 1); }, 'Return only the last document. Pass 1 for true or 0 for false. The default value is 0.', true)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use Appwrite\Storage\Storage;
|
|||
use Appwrite\ClamAV\Network;
|
||||
|
||||
$utopia->get('/v1/health')
|
||||
->desc('Check API HTTP Health')
|
||||
->desc('Get HTTP')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'get')
|
||||
->label('docs', false)
|
||||
->label('sdk.description', '/docs/references/health/get.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['status' => 'OK']);
|
||||
|
|
@ -21,12 +21,12 @@ $utopia->get('/v1/health')
|
|||
);
|
||||
|
||||
$utopia->get('/v1/health/db')
|
||||
->desc('Check DB Health')
|
||||
->desc('Get DB')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getDB')
|
||||
->label('docs', false)
|
||||
->label('sdk.description', '/docs/references/health/get-db.md')
|
||||
->action(
|
||||
function () use ($response, $register) {
|
||||
$register->get('db'); /* @var $db PDO */
|
||||
|
|
@ -36,12 +36,12 @@ $utopia->get('/v1/health/db')
|
|||
);
|
||||
|
||||
$utopia->get('/v1/health/cache')
|
||||
->desc('Check Cache Health')
|
||||
->desc('Get Cache')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getCache')
|
||||
->label('docs', false)
|
||||
->label('sdk.description', '/docs/references/health/get-cache.md')
|
||||
->action(
|
||||
function () use ($response, $register) {
|
||||
$register->get('cache'); /* @var $cache Predis\Client */
|
||||
|
|
@ -51,12 +51,12 @@ $utopia->get('/v1/health/cache')
|
|||
);
|
||||
|
||||
$utopia->get('/v1/health/time')
|
||||
->desc('Check Time Health')
|
||||
->desc('Get Time')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getTime')
|
||||
->label('docs', false)
|
||||
->label('sdk.description', '/docs/references/health/get-time.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
/*
|
||||
|
|
@ -97,26 +97,91 @@ $utopia->get('/v1/health/time')
|
|||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/webhooks')
|
||||
->desc('Check Webhooks Health')
|
||||
$utopia->get('/v1/health/queue/webhooks')
|
||||
->desc('Get Webhooks Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getWebhooks')
|
||||
->label('docs', false)
|
||||
->label('sdk.method', 'getQueueWebhooks')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-webhooks.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-webhooks')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/queue/tasks')
|
||||
->desc('Get Tasks Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueTasks')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-tasks.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-tasks')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/queue/logs')
|
||||
->desc('Get Logs Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueLogs')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-logs.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-audit')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/queue/usage')
|
||||
->desc('Get Usage Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueUsage')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-usage.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-usage')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/queue/certificates')
|
||||
->desc('Get Certificate Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueCertificates')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-certificates.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-usage')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/queue/functions')
|
||||
->desc('Get Functions Queue')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueFunctions')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-functions.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$response->json(['size' => Resque::size('v1-functions')]);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/storage/local')
|
||||
->desc('Check File System Health')
|
||||
->desc('Get Local Storage')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getStorageLocal')
|
||||
->label('docs', false)
|
||||
->label('sdk.description', '/docs/references/health/get-storage-local.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$device = new Local(APP_STORAGE_UPLOADS.'/');
|
||||
|
|
@ -124,22 +189,34 @@ $utopia->get('/v1/health/storage/local')
|
|||
if (!is_readable($device->getRoot().'/..')) {
|
||||
throw new Exception('Device is not readable');
|
||||
}
|
||||
|
||||
if (!is_writable($device->getRoot().'/../uploads')) {
|
||||
throw new Exception('Device uploads dir is not writable');
|
||||
}
|
||||
|
||||
if (!is_writable($device->getRoot().'/../cache')) {
|
||||
throw new Exception('Device cache dir is not writable');
|
||||
}
|
||||
|
||||
if (!is_writable($device->getRoot().'/..')) {
|
||||
throw new Exception('Device is not writable');
|
||||
if (!is_writable($device->getRoot().'/../config')) {
|
||||
throw new Exception('Device config dir is not writable');
|
||||
}
|
||||
|
||||
if (!is_writable($device->getRoot().'/../certificates')) {
|
||||
throw new Exception('Device certificates dir is not writable');
|
||||
}
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/storage/anti-virus')
|
||||
->desc('Check Anti virus Health')
|
||||
$utopia->get('/v1/health/anti-virus')
|
||||
->desc('Get Anti virus')
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getStorageAntiVirus')
|
||||
->label('docs', false)
|
||||
->label('sdk.method', 'getAntiVirus')
|
||||
->label('sdk.description', '/docs/references/health/get-storage-anti-virus.md')
|
||||
->action(
|
||||
function () use ($response) {
|
||||
$antiVirus = new Network('clamav', 3310);
|
||||
|
|
@ -151,12 +228,12 @@ $utopia->get('/v1/health/storage/anti-virus')
|
|||
}
|
||||
);
|
||||
|
||||
$utopia->get('/v1/health/stats')
|
||||
->desc('System Stats')
|
||||
$utopia->get('/v1/health/stats') // Currently only used internally
|
||||
->desc('Get System Stats')
|
||||
->label('scope', 'god')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getStats')
|
||||
// ->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
// ->label('sdk.namespace', 'health')
|
||||
// ->label('sdk.method', 'getStats')
|
||||
->label('docs', false)
|
||||
->action(
|
||||
function () use ($response, $register) {
|
||||
|
|
|
|||
|
|
@ -153,28 +153,55 @@ $utopia->get('/v1/projects/:projectId/usage')
|
|||
->label('sdk.namespace', 'projects')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->param('projectId', '', function () { return new UID(); }, 'Project unique ID.')
|
||||
->param('range', 'last30', function () { return new WhiteList(['daily', 'monthly', 'last30', 'last90']); }, 'Date range.', true)
|
||||
->action(
|
||||
function ($projectId) use ($response, $consoleDB, $projectDB, $register) {
|
||||
function ($projectId, $range) use ($response, $consoleDB, $projectDB, $register) {
|
||||
$project = $consoleDB->getDocument($projectId);
|
||||
|
||||
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS != $project->getCollection()) {
|
||||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$period = [
|
||||
'daily' => [
|
||||
'start' => DateTime::createFromFormat('U', strtotime('today')),
|
||||
'end' => DateTime::createFromFormat('U', strtotime('tomorrow')),
|
||||
'group' => '1m',
|
||||
],
|
||||
'monthly' => [
|
||||
'start' => DateTime::createFromFormat('U', strtotime('midnight first day of this month')),
|
||||
'end' => DateTime::createFromFormat('U', strtotime('midnight last day of this month')),
|
||||
'group' => '1d',
|
||||
],
|
||||
'last30' => [
|
||||
'start' => DateTime::createFromFormat('U', strtotime('-30 days')),
|
||||
'end' => DateTime::createFromFormat('U', strtotime('tomorrow')),
|
||||
'group' => '1d',
|
||||
],
|
||||
'last90' => [
|
||||
'start' => DateTime::createFromFormat('U', strtotime('-90 days')),
|
||||
'end' => DateTime::createFromFormat('U', strtotime('today')),
|
||||
'group' => '1d',
|
||||
],
|
||||
// 'yearly' => [
|
||||
// 'start' => DateTime::createFromFormat('U', strtotime('midnight first day of january')),
|
||||
// 'end' => DateTime::createFromFormat('U', strtotime('midnight last day of december')),
|
||||
// 'group' => '4w',
|
||||
// ],
|
||||
];
|
||||
|
||||
$client = $register->get('influxdb');
|
||||
|
||||
$requests = [];
|
||||
$network = [];
|
||||
|
||||
if ($client) {
|
||||
$start = DateTime::createFromFormat('U', strtotime('last day of last month'));
|
||||
$start = $start->format(DateTime::RFC3339);
|
||||
$end = DateTime::createFromFormat('U', strtotime('last day of this month'));
|
||||
$end = $end->format(DateTime::RFC3339);
|
||||
$start = $period[$range]['start']->format(DateTime::RFC3339);
|
||||
$end = $period[$range]['end']->format(DateTime::RFC3339);
|
||||
$database = $client->selectDB('telegraf');
|
||||
|
||||
// Requests
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_requests_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time(1d) FILL(null)');
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_requests_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
|
||||
$points = $result->getPoints();
|
||||
|
||||
foreach ($points as $point) {
|
||||
|
|
@ -185,7 +212,7 @@ $utopia->get('/v1/projects/:projectId/usage')
|
|||
}
|
||||
|
||||
// Network
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_network_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time(1d) FILL(null)');
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_network_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
|
||||
$points = $result->getPoints();
|
||||
|
||||
foreach ($points as $point) {
|
||||
|
|
@ -1030,7 +1057,7 @@ $utopia->post('/v1/projects/:projectId/platforms')
|
|||
->label('sdk.namespace', 'projects')
|
||||
->label('sdk.method', 'createPlatform')
|
||||
->param('projectId', null, function () { return new UID(); }, 'Project unique ID.')
|
||||
->param('type', null, function () { return new WhiteList(['web', 'ios', 'android', 'unity']); }, 'Platform type.')
|
||||
->param('type', null, function () { return new WhiteList(['web', 'flutter-ios', 'flutter-android', 'ios', 'android', 'unity']); }, 'Platform type.')
|
||||
->param('name', null, function () { return new Text(256); }, 'Platform name.')
|
||||
->param('key', '', function () { return new Text(256); }, 'Package name for android or bundle ID for iOS.', true)
|
||||
->param('store', '', function () { return new Text(256); }, 'App store or Google Play store ID.', true)
|
||||
|
|
|
|||
|
|
@ -302,7 +302,23 @@ $utopia->get('/v1/users/:userId/logs')
|
|||
|
||||
$countries = Locale::getText('countries');
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getId());
|
||||
$logs = $audit->getLogsByUserAndActions($user->getId(), [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'account.update.name',
|
||||
'account.update.email',
|
||||
'account.update.password',
|
||||
'account.update.prefs',
|
||||
'account.sessions.create',
|
||||
'account.sessions.delete',
|
||||
'account.recovery.create',
|
||||
'account.recovery.update',
|
||||
'account.verification.create',
|
||||
'account.verification.update',
|
||||
'teams.membership.create',
|
||||
'teams.membership.update',
|
||||
'teams.membership.delete',
|
||||
]);
|
||||
|
||||
$reader = new Reader(__DIR__.'/../../db/DBIP/dbip-country-lite-2020-01.mmdb');
|
||||
$output = [];
|
||||
|
|
@ -433,7 +449,7 @@ $utopia->patch('/v1/users/:userId/prefs')
|
|||
);
|
||||
|
||||
|
||||
$utopia->delete('/v1/users/:userId/sessions/:session')
|
||||
$utopia->delete('/v1/users/:userId/sessions/:sessionId')
|
||||
->desc('Delete User Session')
|
||||
->label('scope', 'users.write')
|
||||
->label('sdk.platform', [APP_PLATFORM_SERVER])
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ use Utopia\View;
|
|||
use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Validator\UID;
|
||||
use Appwrite\Storage\Storage;
|
||||
|
||||
$utopia->init(function () use ($layout, $utopia) {
|
||||
$utopia->init(function () use ($layout) {
|
||||
$layout
|
||||
->setParam('analytics', 'UA-26264668-5')
|
||||
;
|
||||
|
|
@ -178,12 +179,14 @@ $utopia->get('/console/database')
|
|||
});
|
||||
|
||||
$utopia->get('/console/database/collection')
|
||||
->desc('Platform console project settings')
|
||||
->desc('Platform console project database collection')
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'console')
|
||||
->param('id', '', function () { return new UID(); }, 'Collection unique ID.')
|
||||
->action(function ($id) use ($layout, $projectDB) {
|
||||
Authorization::disable();
|
||||
$collection = $projectDB->getDocument($id, false);
|
||||
Authorization::reset();
|
||||
|
||||
if (empty($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
|
||||
throw new Exception('Collection not found', 404);
|
||||
|
|
@ -192,11 +195,41 @@ $utopia->get('/console/database/collection')
|
|||
$page = new View(__DIR__.'/../../views/console/database/collection.phtml');
|
||||
|
||||
$page
|
||||
->setParam('collection', $collection->getArrayCopy())
|
||||
->setParam('collection', $collection)
|
||||
;
|
||||
|
||||
$layout
|
||||
->setParam('title', APP_NAME.' - Database')
|
||||
->setParam('title', APP_NAME.' - Database Collection')
|
||||
->setParam('body', $page);
|
||||
});
|
||||
|
||||
$utopia->get('/console/database/document')
|
||||
->desc('Platform console project database document')
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'console')
|
||||
->param('collection', '', function () { return new UID(); }, 'Collection unique ID.')
|
||||
->action(function ($collection) use ($layout, $projectDB) {
|
||||
Authorization::disable();
|
||||
$collection = $projectDB->getDocument($collection, false);
|
||||
Authorization::reset();
|
||||
|
||||
if (empty($collection->getId()) || Database::SYSTEM_COLLECTION_COLLECTIONS != $collection->getCollection()) {
|
||||
throw new Exception('Collection not found', 404);
|
||||
}
|
||||
|
||||
$page = new View(__DIR__.'/../../views/console/database/document.phtml');
|
||||
$searchFiles = new View(__DIR__.'/../../views/console/database/search/files.phtml');
|
||||
$searchDocuments = new View(__DIR__.'/../../views/console/database/search/documents.phtml');
|
||||
|
||||
$page
|
||||
->setParam('db', $projectDB)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('searchFiles', $searchFiles)
|
||||
->setParam('searchDocuments', $searchDocuments)
|
||||
;
|
||||
|
||||
$layout
|
||||
->setParam('title', APP_NAME.' - Database Document')
|
||||
->setParam('body', $page);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ global $utopia, $response, $request, $layout;
|
|||
|
||||
use Utopia\View;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Validator\Range;
|
||||
|
||||
$header = new View(__DIR__.'/../../views/home/comps/header.phtml');
|
||||
$footer = new View(__DIR__.'/../../views/home/comps/footer.phtml');
|
||||
|
|
@ -155,3 +157,401 @@ $utopia->get('/error/:code')
|
|||
->setParam('title', 'Error'.' - '.APP_NAME)
|
||||
->setParam('body', $page);
|
||||
});
|
||||
|
||||
$utopia->get('/open-api-2.json')
|
||||
->label('scope', 'public')
|
||||
->label('docs', false)
|
||||
->param('platform', APP_PLATFORM_CLIENT, function () {return new WhiteList([APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER, APP_PLATFORM_CONSOLE]);}, 'Choose target platform.', true)
|
||||
->param('extensions', 0, function () {return new Range(0, 1);}, 'Show extra data.', true)
|
||||
->param('tests', 0, function () {return new Range(0, 1);}, 'Include only test services.', true)
|
||||
->action(
|
||||
function ($platform, $extensions, $tests) use ($response, $request, $utopia, $services) {
|
||||
function fromCamelCase($input)
|
||||
{
|
||||
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
|
||||
$ret = $matches[0];
|
||||
foreach ($ret as &$match) {
|
||||
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
|
||||
}
|
||||
|
||||
return implode('_', $ret);
|
||||
}
|
||||
|
||||
function fromCamelCaseToDash($input)
|
||||
{
|
||||
return str_replace([' ', '_'], '-', strtolower(preg_replace('/([a-zA-Z])(?=[A-Z])/', '$1-', $input)));
|
||||
}
|
||||
|
||||
foreach ($services as $service) { /* @noinspection PhpIncludeInspection */
|
||||
if($tests && !isset($service['tests'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if($tests && !$service['tests']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$tests && !$service['sdk']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once realpath(__DIR__.'/../../'.$service['controller']);
|
||||
}
|
||||
|
||||
$security = [
|
||||
APP_PLATFORM_CLIENT => ['Project' => []],
|
||||
APP_PLATFORM_SERVER => ['Project' => [], 'Key' => []],
|
||||
APP_PLATFORM_CONSOLE => ['Project' => [], 'Key' => []],
|
||||
];
|
||||
|
||||
$platforms = [
|
||||
'client' => APP_PLATFORM_CLIENT,
|
||||
'server' => APP_PLATFORM_SERVER,
|
||||
'all' => APP_PLATFORM_CONSOLE,
|
||||
];
|
||||
|
||||
$keys = [
|
||||
APP_PLATFORM_CLIENT => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_SERVER => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
APP_PLATFORM_CONSOLE => [
|
||||
'Project' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Project',
|
||||
'description' => 'Your project ID',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Key' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Key',
|
||||
'description' => 'Your secret API key',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Locale' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Locale',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
'Mode' => [
|
||||
'type' => 'apiKey',
|
||||
'name' => 'X-Appwrite-Mode',
|
||||
'description' => '',
|
||||
'in' => 'header',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/*
|
||||
* Specifications (v3.0.0):
|
||||
* https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
|
||||
*/
|
||||
$output = [
|
||||
'swagger' => '2.0',
|
||||
'info' => [
|
||||
'version' => APP_VERSION_STABLE,
|
||||
'title' => APP_NAME,
|
||||
'description' => 'Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)',
|
||||
'termsOfService' => 'https://appwrite.io/policy/terms',
|
||||
'contact' => [
|
||||
'name' => 'Appwrite Team',
|
||||
'url' => 'https://appwrite.io/support',
|
||||
'email' => $request->getServer('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM),
|
||||
],
|
||||
'license' => [
|
||||
'name' => 'BSD-3-Clause',
|
||||
'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE',
|
||||
],
|
||||
],
|
||||
'host' => parse_url($request->getServer('_APP_HOME', Config::getParam('domain')), PHP_URL_HOST),
|
||||
'basePath' => '/v1',
|
||||
'schemes' => ['https'],
|
||||
'consumes' => ['application/json', 'multipart/form-data'],
|
||||
'produces' => ['application/json'],
|
||||
'securityDefinitions' => $keys[$platform],
|
||||
'paths' => [],
|
||||
'definitions' => [
|
||||
// 'Pet' => [
|
||||
// 'required' => ['id', 'name'],
|
||||
// 'properties' => [
|
||||
// 'id' => [
|
||||
// 'type' => 'integer',
|
||||
// 'format' => 'int64',
|
||||
// ],
|
||||
// 'name' => [
|
||||
// 'type' => 'string',
|
||||
// ],
|
||||
// 'tag' => [
|
||||
// 'type' => 'string',
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
// 'Pets' => array(
|
||||
// 'type' => 'array',
|
||||
// 'items' => array(
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ),
|
||||
// ),
|
||||
'Error' => array(
|
||||
'required' => array(
|
||||
0 => 'code',
|
||||
1 => 'message',
|
||||
),
|
||||
'properties' => array(
|
||||
'code' => array(
|
||||
'type' => 'integer',
|
||||
'format' => 'int32',
|
||||
),
|
||||
'message' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
'externalDocs' => [
|
||||
'description' => 'Full API docs, specs and tutorials',
|
||||
'url' => Config::getParam('protocol').'://'.Config::getParam('domain').'/docs',
|
||||
],
|
||||
];
|
||||
|
||||
if ($extensions) {
|
||||
if(isset($output['securityDefinitions']['Project'])) {
|
||||
$output['securityDefinitions']['Project']['extensions'] = ['demo' => '5df5acd0d48c2'];
|
||||
}
|
||||
|
||||
if(isset($output['securityDefinitions']['Key'])) {
|
||||
$output['securityDefinitions']['Key']['extensions'] = ['demo' => '919c2d18fb5d4...a2ae413da83346ad2'];
|
||||
}
|
||||
|
||||
if(isset($output['securityDefinitions']['Locale'])) {
|
||||
$output['securityDefinitions']['Locale']['extensions'] = ['demo' => 'en'];
|
||||
}
|
||||
|
||||
if(isset($output['securityDefinitions']['Mode'])) {
|
||||
$output['securityDefinitions']['Mode']['extensions'] = ['demo' => ''];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($utopia->getRoutes() as $key => $method) {
|
||||
foreach ($method as $route) { /* @var $route \Utopia\Route */
|
||||
if (!$route->getLabel('docs', true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($route->getLabel('sdk.namespace', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if($platform !== APP_PLATFORM_CONSOLE && !in_array($platforms[$platform], $route->getLabel('sdk.platform', []))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = str_replace('/v1', '', $route->getURL());
|
||||
$scope = $route->getLabel('scope', '');
|
||||
$hide = $route->getLabel('sdk.hide', false);
|
||||
$consumes = ['application/json'];
|
||||
|
||||
if ($hide) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$desc = (!empty($route->getLabel('sdk.description', ''))) ? realpath('../'.$route->getLabel('sdk.description', '')) : null;
|
||||
|
||||
$temp = [
|
||||
'summary' => $route->getDesc(),
|
||||
'operationId' => $route->getLabel('sdk.method', uniqid()),
|
||||
'consumes' => [],
|
||||
'tags' => [$route->getLabel('sdk.namespace', 'default')],
|
||||
'description' => ($desc) ? file_get_contents($desc) : '',
|
||||
|
||||
// 'responses' => [
|
||||
// 200 => [
|
||||
// 'description' => 'An paged array of pets',
|
||||
// 'schema' => [
|
||||
// '$ref' => '#/definitions/Pet',
|
||||
// ],
|
||||
// ],
|
||||
// ],
|
||||
];
|
||||
|
||||
if ($extensions) {
|
||||
$platformList = $route->getLabel('sdk.platform', []);
|
||||
|
||||
$temp['extensions'] = [
|
||||
'weight' => $route->getOrder(),
|
||||
'cookies' => $route->getLabel('sdk.cookies', false),
|
||||
'type' => $route->getLabel('sdk.methodType', ''),
|
||||
'demo' => 'docs/examples/'.fromCamelCaseToDash($route->getLabel('sdk.namespace', 'default')).'/'.fromCamelCaseToDash($temp['operationId']).'.md',
|
||||
'edit' => 'https://github.com/appwrite/appwrite/edit/master' . $route->getLabel('sdk.description', ''),
|
||||
'rate-limit' => $route->getLabel('abuse-limit', 0),
|
||||
'rate-time' => $route->getLabel('abuse-time', 3600),
|
||||
'scope' => $route->getLabel('scope', ''),
|
||||
'platforms' => $platformList,
|
||||
];
|
||||
}
|
||||
|
||||
if ((!empty($scope))) { // && 'public' != $scope
|
||||
$temp['security'][] = $route->getLabel('sdk.security', $security[$platform]);
|
||||
}
|
||||
|
||||
$requestBody = [
|
||||
'content' => [
|
||||
'application/x-www-form-urlencoded' => [
|
||||
'schema' => [
|
||||
'type' => 'object',
|
||||
'properties' => [],
|
||||
],
|
||||
'required' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($route->getParams() as $name => $param) {
|
||||
$validator = (is_callable($param['validator'])) ? $param['validator']() : $param['validator']; /* @var $validator \Utopia\Validator */
|
||||
|
||||
$node = [
|
||||
'name' => $name,
|
||||
'description' => $param['description'],
|
||||
'required' => !$param['optional'],
|
||||
];
|
||||
|
||||
switch ((!empty($validator)) ? get_class($validator) : '') {
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Appwrite\Database\Validator\UID':
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = '['.strtoupper(fromCamelCase($node['name'])).']';
|
||||
break;
|
||||
case 'Utopia\Validator\Email':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'email';
|
||||
$node['x-example'] = 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\URL':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\JSON':
|
||||
case 'Utopia\Validator\Mock':
|
||||
case 'Utopia\Validator\Assoc':
|
||||
$node['type'] = 'object';
|
||||
$node['type'] = 'object';
|
||||
$node['x-example'] = '{}';
|
||||
//$node['format'] = 'json';
|
||||
break;
|
||||
case 'Appwrite\Storage\Validators\File':
|
||||
$consumes = ['multipart/form-data'];
|
||||
$node['type'] = 'file';
|
||||
break;
|
||||
case 'Utopia\Validator\ArrayList':
|
||||
$node['type'] = 'array';
|
||||
$node['collectionFormat'] = 'multi';
|
||||
$node['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'format';
|
||||
$node['x-example'] = 'password';
|
||||
break;
|
||||
case 'Utopia\Validator\Range': /* @var $validator \Utopia\Validator\Range */
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
$node['x-example'] = $validator->getMin();
|
||||
break;
|
||||
case 'Utopia\Validator\Numeric':
|
||||
$node['type'] = 'integer';
|
||||
$node['format'] = 'int32';
|
||||
break;
|
||||
case 'Utopia\Validator\Length':
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
$node['type'] = 'string';
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList': /* @var $validator \Utopia\Validator\WhiteList */
|
||||
$node['type'] = 'string';
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
break;
|
||||
default:
|
||||
$node['type'] = 'string';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($param['optional'] && !is_null($param['default'])) { // Param has default value
|
||||
$node['default'] = $param['default'];
|
||||
}
|
||||
|
||||
if (false !== strpos($url, ':'.$name)) { // Param is in URL path
|
||||
$node['in'] = 'path';
|
||||
$temp['parameters'][] = $node;
|
||||
} elseif ($key == 'GET') { // Param is in query
|
||||
$node['in'] = 'query';
|
||||
$temp['parameters'][] = $node;
|
||||
} else { // Param is in payload
|
||||
$node['in'] = 'formData';
|
||||
$temp['parameters'][] = $node;
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['schema']['properties'][] = $node;
|
||||
|
||||
if (!$param['optional']) {
|
||||
$requestBody['content']['application/x-www-form-urlencoded']['required'][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$url = str_replace(':'.$name, '{'.$name.'}', $url);
|
||||
}
|
||||
|
||||
$temp['consumes'] = $consumes;
|
||||
|
||||
$output['paths'][$url][strtolower($route->getMethod())] = $temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*foreach ($consoleDB->getMocks() as $mock) {
|
||||
var_dump($mock['name']);
|
||||
}*/
|
||||
|
||||
ksort($output['paths']);
|
||||
|
||||
$response
|
||||
->json($output);
|
||||
}
|
||||
);
|
||||
|
|
@ -32,8 +32,8 @@ const APP_EMAIL_SECURITY = 'security@localhost.test'; // Default security email
|
|||
const APP_USERAGENT = APP_NAME.'-Server v%s. Please report abuse at %s';
|
||||
const APP_MODE_ADMIN = 'admin';
|
||||
const APP_PAGING_LIMIT = 15;
|
||||
const APP_CACHE_BUSTER = 56;
|
||||
const APP_VERSION_STABLE = '0.5.3';
|
||||
const APP_CACHE_BUSTER = 125;
|
||||
const APP_VERSION_STABLE = '0.6.0';
|
||||
const APP_STORAGE_UPLOADS = '/storage/uploads';
|
||||
const APP_STORAGE_CACHE = '/storage/cache';
|
||||
const APP_STORAGE_CERTIFICATES = '/storage/certificates';
|
||||
|
|
@ -45,6 +45,7 @@ const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite';
|
|||
const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io';
|
||||
const APP_SOCIAL_GITHUB = 'https://github.com/appwrite';
|
||||
const APP_SOCIAL_DISCORD = 'https://discord.gg/GSeTUeA';
|
||||
const APP_SOCIAL_DEV = 'https://dev.to/appwrite';
|
||||
|
||||
$register = new Registry();
|
||||
$request = new Request();
|
||||
|
|
|
|||
42
app/sdks/client-flutter/CHANGELOG.md
Normal file
42
app/sdks/client-flutter/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
## 0.2.1
|
||||
|
||||
- Fixed callback scheme
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Updated flutter_web_auth plugin to version 0.2.4
|
||||
- Added per project unique callback for OAuth2 redirects to aviod conflicts between multiple Appwrite projects
|
||||
|
||||
## 0.1.1
|
||||
|
||||
- Updated flutter_web_auth version
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- Added examples file
|
||||
- Some minor style fixes
|
||||
|
||||
## 0.0.14
|
||||
|
||||
- Using MultipartFile for file uploads
|
||||
|
||||
## 0.0.13
|
||||
|
||||
- Fix for file upload method
|
||||
|
||||
## 0.0.12
|
||||
|
||||
- Added file upload support for storage service
|
||||
|
||||
## 0.0.11
|
||||
|
||||
- Added integration with web auth plugin to support Appwrite OAuth API
|
||||
|
||||
## 0.0.9
|
||||
|
||||
- Updated deafult params
|
||||
|
||||
## 0.0.8
|
||||
|
||||
- Fixed compilation error in Client class
|
||||
- Shorter description for package
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
# Appwrite SDK for Dart
|
||||
# Appwrite Flutter SDK
|
||||
|
||||

|
||||

|
||||
[](https://pub.dartlang.org/packages/appwrite)
|
||||

|
||||

|
||||
|
||||
**This SDK is compatible with Appwrite server version 0.5.3. For older versions, please check previous releases.**
|
||||
**This SDK is compatible with Appwrite server version 0.6.0. For older versions, please check previous releases.**
|
||||
|
||||
Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
|
||||
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way.
|
||||
Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.
|
||||
For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
|
||||
|
||||
|
||||
|
||||
|
|
@ -17,7 +20,7 @@ Add this to your package's `pubspec.yaml` file:
|
|||
|
||||
```yml
|
||||
dependencies:
|
||||
appwrite: ^0.0.8
|
||||
appwrite: ^0.2.1
|
||||
```
|
||||
|
||||
You can install packages from the command line:
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.createOAuth2Session(
|
||||
provider: 'bitbucket',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.createRecovery(
|
||||
email: 'email@example.com',
|
||||
url: 'https://example.com',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.createSession(
|
||||
email: 'email@example.com',
|
||||
password: 'password',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.createVerification(
|
||||
url: 'https://example.com',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
21
app/sdks/client-flutter/docs/examples/account/create.md
Normal file
21
app/sdks/client-flutter/docs/examples/account/create.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.create(
|
||||
email: 'email@example.com',
|
||||
password: 'password',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.deleteSession(
|
||||
sessionId: '[SESSION_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.deleteSessions();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
18
app/sdks/client-flutter/docs/examples/account/delete.md
Normal file
18
app/sdks/client-flutter/docs/examples/account/delete.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.delete();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
18
app/sdks/client-flutter/docs/examples/account/get-logs.md
Normal file
18
app/sdks/client-flutter/docs/examples/account/get-logs.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.getLogs();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
18
app/sdks/client-flutter/docs/examples/account/get-prefs.md
Normal file
18
app/sdks/client-flutter/docs/examples/account/get-prefs.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.getPrefs();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.getSessions();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
18
app/sdks/client-flutter/docs/examples/account/get.md
Normal file
18
app/sdks/client-flutter/docs/examples/account/get.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.get();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updateEmail(
|
||||
email: 'email@example.com',
|
||||
password: 'password',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/account/update-name.md
Normal file
20
app/sdks/client-flutter/docs/examples/account/update-name.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updateName(
|
||||
name: '[NAME]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updatePassword(
|
||||
password: 'password',
|
||||
oldPassword: 'password',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updatePrefs(
|
||||
prefs: {},
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updateRecovery(
|
||||
userId: '[USER_ID]',
|
||||
secret: '[SECRET]',
|
||||
password: 'password',
|
||||
passwordAgain: 'password',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Account account = Account(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = account.updateVerification(
|
||||
userId: '[USER_ID]',
|
||||
secret: '[SECRET]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/avatars/get-browser.md
Normal file
20
app/sdks/client-flutter/docs/examples/avatars/get-browser.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = avatars.getBrowser(
|
||||
code: 'aa',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = avatars.getCreditCard(
|
||||
code: 'amex',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
15
app/sdks/client-flutter/docs/examples/avatars/get-favicon.md
Normal file
15
app/sdks/client-flutter/docs/examples/avatars/get-favicon.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = avatars.getFavicon(
|
||||
url: 'https://example.com',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
15
app/sdks/client-flutter/docs/examples/avatars/get-flag.md
Normal file
15
app/sdks/client-flutter/docs/examples/avatars/get-flag.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = avatars.getFlag(
|
||||
code: 'af',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
15
app/sdks/client-flutter/docs/examples/avatars/get-image.md
Normal file
15
app/sdks/client-flutter/docs/examples/avatars/get-image.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = avatars.getImage(
|
||||
url: 'https://example.com',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
15
app/sdks/client-flutter/docs/examples/avatars/get-q-r.md
Normal file
15
app/sdks/client-flutter/docs/examples/avatars/get-q-r.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Avatars avatars = Avatars(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = avatars.getQR(
|
||||
text: '[TEXT]',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Database database = Database(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = database.createDocument(
|
||||
collectionId: '[COLLECTION_ID]',
|
||||
data: {},
|
||||
read: [],
|
||||
write: [],
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Database database = Database(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = database.deleteDocument(
|
||||
collectionId: '[COLLECTION_ID]',
|
||||
documentId: '[DOCUMENT_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Database database = Database(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = database.getDocument(
|
||||
collectionId: '[COLLECTION_ID]',
|
||||
documentId: '[DOCUMENT_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Database database = Database(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = database.listDocuments(
|
||||
collectionId: '[COLLECTION_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Database database = Database(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = database.updateDocument(
|
||||
collectionId: '[COLLECTION_ID]',
|
||||
documentId: '[DOCUMENT_ID]',
|
||||
data: {},
|
||||
read: [],
|
||||
write: [],
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.getContinents();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.getCountriesEU();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.getCountriesPhones();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.getCountries();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.getCurrencies();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
18
app/sdks/client-flutter/docs/examples/locale/get.md
Normal file
18
app/sdks/client-flutter/docs/examples/locale/get.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Locale locale = Locale(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = locale.get();
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
23
app/sdks/client-flutter/docs/examples/storage/create-file.md
Normal file
23
app/sdks/client-flutter/docs/examples/storage/create-file.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import 'dart:io';
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = storage.createFile(
|
||||
file: await MultipartFile.fromFile('./path-to-files/image.jpg', 'image.jpg'),
|
||||
read: [],
|
||||
write: [],
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/storage/delete-file.md
Normal file
20
app/sdks/client-flutter/docs/examples/storage/delete-file.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = storage.deleteFile(
|
||||
fileId: '[FILE_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = storage.getFileDownload(
|
||||
fileId: '[FILE_ID]',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = storage.getFilePreview(
|
||||
fileId: '[FILE_ID]',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
String result = storage.getFileView(
|
||||
fileId: '[FILE_ID]',
|
||||
);
|
||||
|
||||
print(result); // Resource URL string
|
||||
20
app/sdks/client-flutter/docs/examples/storage/get-file.md
Normal file
20
app/sdks/client-flutter/docs/examples/storage/get-file.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = storage.getFile(
|
||||
fileId: '[FILE_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
19
app/sdks/client-flutter/docs/examples/storage/list-files.md
Normal file
19
app/sdks/client-flutter/docs/examples/storage/list-files.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = storage.listFiles(
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
22
app/sdks/client-flutter/docs/examples/storage/update-file.md
Normal file
22
app/sdks/client-flutter/docs/examples/storage/update-file.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Storage storage = Storage(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = storage.updateFile(
|
||||
fileId: '[FILE_ID]',
|
||||
read: [],
|
||||
write: [],
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.createMembership(
|
||||
teamId: '[TEAM_ID]',
|
||||
email: 'email@example.com',
|
||||
roles: [],
|
||||
url: 'https://example.com',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/teams/create.md
Normal file
20
app/sdks/client-flutter/docs/examples/teams/create.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.create(
|
||||
name: '[NAME]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.deleteMembership(
|
||||
teamId: '[TEAM_ID]',
|
||||
inviteId: '[INVITE_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/teams/delete.md
Normal file
20
app/sdks/client-flutter/docs/examples/teams/delete.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.delete(
|
||||
teamId: '[TEAM_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.getMemberships(
|
||||
teamId: '[TEAM_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
20
app/sdks/client-flutter/docs/examples/teams/get.md
Normal file
20
app/sdks/client-flutter/docs/examples/teams/get.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.get(
|
||||
teamId: '[TEAM_ID]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
19
app/sdks/client-flutter/docs/examples/teams/list.md
Normal file
19
app/sdks/client-flutter/docs/examples/teams/list.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.list(
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.updateMembershipStatus(
|
||||
teamId: '[TEAM_ID]',
|
||||
inviteId: '[INVITE_ID]',
|
||||
userId: '[USER_ID]',
|
||||
secret: '[SECRET]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
21
app/sdks/client-flutter/docs/examples/teams/update.md
Normal file
21
app/sdks/client-flutter/docs/examples/teams/update.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
// Init SDK
|
||||
Client client = Client();
|
||||
Teams teams = Teams(client);
|
||||
|
||||
client
|
||||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
Future result = teams.update(
|
||||
teamId: '[TEAM_ID]',
|
||||
name: '[NAME]',
|
||||
);
|
||||
|
||||
result
|
||||
.then((response) {
|
||||
print(response);
|
||||
}).catchError((error) {
|
||||
print(error);
|
||||
});
|
||||
55
app/sdks/client-flutter/example/README.md
Normal file
55
app/sdks/client-flutter/example/README.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Examples
|
||||
|
||||
Init your Appwrite client:
|
||||
|
||||
```dart
|
||||
Client client = Client();
|
||||
|
||||
client
|
||||
.setEndpoint('https://localhost/v1') // Your Appwrite Endpoint
|
||||
.setProject('5e8cf4f46b5e8') // Your project ID
|
||||
.setSelfSigned() // Remove in production
|
||||
;
|
||||
|
||||
```
|
||||
|
||||
Create a new user and session:
|
||||
|
||||
```dart
|
||||
Account account = Account(client);
|
||||
|
||||
Response user = await account.create(email: 'me@appwrite.io', password: 'password', name: 'My Name');
|
||||
|
||||
Response session = await account.createSession(email: 'me@appwrite.io', password: 'password');
|
||||
|
||||
```
|
||||
|
||||
Fetch user profile:
|
||||
|
||||
```dart
|
||||
Account account = Account(client);
|
||||
|
||||
Response profile = await account.get();
|
||||
```
|
||||
|
||||
Upload File:
|
||||
|
||||
```dart
|
||||
Storage storage = Storage(client);
|
||||
|
||||
MultipartFile file = MultipartFile.fromFile('./path-to-file/image.jpg', filename: 'image.jpg');
|
||||
|
||||
storage.createFile(
|
||||
file: file,
|
||||
read: ['*'],
|
||||
write: []
|
||||
)
|
||||
.then((response) {
|
||||
print(response); // File uploaded!
|
||||
})
|
||||
.catchError((error) {
|
||||
print(error.response);
|
||||
});
|
||||
```
|
||||
|
||||
All examples and API features are available at the [official Appwrite docs](https://appwrite.io/docs)
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
export 'package:dio/dio.dart' show Response;
|
||||
|
||||
export 'client.dart';
|
||||
export 'enums.dart';
|
||||
export 'services/account.dart';
|
||||
export 'services/avatars.dart';
|
||||
export 'services/database.dart';
|
||||
export 'services/locale.dart';
|
||||
export 'services/storage.dart';
|
||||
export 'services/teams.dart';
|
||||
export 'client.dart';
|
||||
export 'enums.dart';
|
||||
export 'package:dio/dio.dart' show Response;
|
||||
120
app/sdks/client-flutter/lib/client.dart
Normal file
120
app/sdks/client-flutter/lib/client.dart
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio/adapter.dart';
|
||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
|
||||
import 'enums.dart';
|
||||
|
||||
class Client {
|
||||
String endPoint;
|
||||
String type = 'unknown';
|
||||
Map<String, String> headers;
|
||||
Map<String, String> config;
|
||||
bool selfSigned;
|
||||
bool init = false;
|
||||
Dio http;
|
||||
PersistCookieJar cookieJar;
|
||||
|
||||
Client({this.endPoint = 'https://appwrite.io/v1', this.selfSigned = false, Dio http}) : this.http = http ?? Dio() {
|
||||
|
||||
type = (Platform.isIOS) ? 'ios' : type;
|
||||
type = (Platform.isMacOS) ? 'macos' : type;
|
||||
type = (Platform.isAndroid) ? 'android' : type;
|
||||
type = (Platform.isLinux) ? 'linux' : type;
|
||||
type = (Platform.isWindows) ? 'windows' : type;
|
||||
type = (Platform.isFuchsia) ? 'fuchsia' : type;
|
||||
|
||||
this.headers = {
|
||||
'content-type': 'application/json',
|
||||
'x-sdk-version': 'appwrite:dart:0.2.1',
|
||||
};
|
||||
|
||||
this.config = {};
|
||||
|
||||
assert(endPoint.startsWith(RegExp("http://|https://")), "endPoint $endPoint must start with 'http'");
|
||||
}
|
||||
|
||||
Future<Directory> _getCookiePath() async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final path = directory.path;
|
||||
final Directory dir = new Directory('$path/cookies');
|
||||
await dir.create();
|
||||
return dir;
|
||||
}
|
||||
|
||||
/// Your project ID
|
||||
Client setProject(value) {
|
||||
config['project'] = value;
|
||||
addHeader('X-Appwrite-Project', value);
|
||||
return this;
|
||||
}
|
||||
|
||||
Client setLocale(value) {
|
||||
config['locale'] = value;
|
||||
addHeader('X-Appwrite-Locale', value);
|
||||
return this;
|
||||
}
|
||||
|
||||
Client setSelfSigned({bool status = true}) {
|
||||
selfSigned = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
Client setEndpoint(String endPoint) {
|
||||
this.endPoint = endPoint;
|
||||
this.http.options.baseUrl = this.endPoint;
|
||||
return this;
|
||||
}
|
||||
|
||||
Client addHeader(String key, String value) {
|
||||
headers[key] = value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Future<Response> call(HttpMethod method, {String path = '', Map<String, String> headers = const {}, Map<String, dynamic> params = const {}}) async {
|
||||
if(selfSigned) {
|
||||
// Allow self signed requests
|
||||
(http.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient client) {
|
||||
client.badCertificateCallback = (X509Certificate cert, String host, int port) => true;
|
||||
return client;
|
||||
};
|
||||
}
|
||||
|
||||
if(!init) {
|
||||
final Directory cookieDir = await _getCookiePath();
|
||||
|
||||
cookieJar = new PersistCookieJar(dir:cookieDir.path);
|
||||
|
||||
this.http.options.baseUrl = this.endPoint;
|
||||
this.http.options.validateStatus = (status) => status < 400;
|
||||
this.http.interceptors.add(CookieManager(cookieJar));
|
||||
|
||||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||
|
||||
addHeader('Origin', 'appwrite-' + type + '://' + packageInfo.packageName);
|
||||
|
||||
init = true;
|
||||
}
|
||||
|
||||
// Origin is hardcoded for testing
|
||||
Options options = Options(
|
||||
headers: {...this.headers, ...headers},
|
||||
method: method.name(),
|
||||
);
|
||||
|
||||
if(headers['content-type'] == 'multipart/form-data') {
|
||||
return http.request(path, data: FormData.fromMap(params), options: options);
|
||||
}
|
||||
|
||||
if (method == HttpMethod.get) {
|
||||
return http.get(path, queryParameters: params, options: options);
|
||||
} else {
|
||||
return http.request(path, data: params, options: options);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
app/sdks/client-flutter/lib/enums.dart
Normal file
15
app/sdks/client-flutter/lib/enums.dart
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
enum HttpMethod { get, post, put, delete, patch }
|
||||
|
||||
extension HttpMethodString on HttpMethod {
|
||||
String name() {
|
||||
return this.toString().split('.').last.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
enum OrderType { asc, desc }
|
||||
|
||||
extension OrderTypeString on OrderType {
|
||||
String name() {
|
||||
return this.toString().split('.').last.toUpperCase();
|
||||
}
|
||||
}
|
||||
7
app/sdks/client-flutter/lib/service.dart
Normal file
7
app/sdks/client-flutter/lib/service.dart
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import 'client.dart';
|
||||
|
||||
class Service {
|
||||
final Client client;
|
||||
|
||||
const Service(this.client);
|
||||
}
|
||||
|
|
@ -1,31 +1,44 @@
|
|||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:flutter_web_auth/flutter_web_auth.dart';
|
||||
|
||||
import "../client.dart";
|
||||
import '../enums.dart';
|
||||
import "../service.dart";
|
||||
|
||||
class Account extends Service {
|
||||
|
||||
Account(Client client): super(client);
|
||||
|
||||
/// Get Account
|
||||
///
|
||||
/// Get currently logged in user data as JSON object.
|
||||
///
|
||||
Future<Response> get() {
|
||||
final String path = '/account';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Account
|
||||
///
|
||||
/// Use this endpoint to allow a new user to register a new account in your
|
||||
/// project. After the user registration completes successfully, you can use
|
||||
/// the [/account/verfication](/docs/account#createVerification) route to start
|
||||
/// verifying the user email address. To allow your new user to login to his
|
||||
/// new account, you need to create a new [account
|
||||
/// session](/docs/account#createSession).
|
||||
Future<Response> create({@required String email, @required String password, String name = null}) {
|
||||
///
|
||||
Future<Response> create({@required String email, @required String password, String name = ''}) {
|
||||
final String path = '/account';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -34,25 +47,41 @@ class Account extends Service {
|
|||
'name': name,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete Account
|
||||
///
|
||||
/// Delete a currently logged in user account. Behind the scene, the user
|
||||
/// record is not deleted but permanently blocked from any access. This is done
|
||||
/// to avoid deleted accounts being overtaken by new users with the same email
|
||||
/// address. Any user-related resources like documents or storage files should
|
||||
/// be deleted separately.
|
||||
///
|
||||
Future<Response> delete() {
|
||||
final String path = '/account';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Account Email
|
||||
///
|
||||
/// Update currently logged in user account email address. After changing user
|
||||
/// address, user confirmation status is being reset and a new confirmation
|
||||
/// mail is sent. For security measures, user password is required to complete
|
||||
/// this request.
|
||||
///
|
||||
Future<Response> updateEmail({@required String email, @required String password}) {
|
||||
final String path = '/account/email';
|
||||
|
||||
|
|
@ -61,19 +90,35 @@ class Account extends Service {
|
|||
'password': password,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get 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.
|
||||
///
|
||||
Future<Response> getLogs() {
|
||||
final String path = '/account/logs';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Account Name
|
||||
///
|
||||
/// Update currently logged in user account name.
|
||||
///
|
||||
Future<Response> updateName({@required String name}) {
|
||||
final String path = '/account/name';
|
||||
|
||||
|
|
@ -81,31 +126,55 @@ class Account extends Service {
|
|||
'name': name,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Account Password
|
||||
///
|
||||
/// Update currently logged in user password. For validation, user is required
|
||||
/// to pass the password twice.
|
||||
///
|
||||
Future<Response> updatePassword({@required String password, @required String oldPassword}) {
|
||||
final String path = '/account/password';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'password': password,
|
||||
'old-password': oldPassword,
|
||||
'oldPassword': oldPassword,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Account Preferences
|
||||
///
|
||||
/// Get currently logged in user preferences as a key-value object.
|
||||
///
|
||||
Future<Response> getPrefs() {
|
||||
final String path = '/account/prefs';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Account Preferences
|
||||
///
|
||||
/// Update currently logged in user account preferences. You can pass only the
|
||||
/// specific settings you wish to update.
|
||||
///
|
||||
Future<Response> updatePrefs({@required dynamic prefs}) {
|
||||
final String path = '/account/prefs';
|
||||
|
||||
|
|
@ -113,14 +182,22 @@ class Account extends Service {
|
|||
'prefs': prefs,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Password Recovery
|
||||
///
|
||||
/// Sends the user an email with a temporary secret key for password reset.
|
||||
/// When the user clicks the confirmation link he is redirected back to your
|
||||
/// app password reset URL with the secret key and email address values
|
||||
/// attached to the URL query string. Use the query string params to submit a
|
||||
/// request to the [PUT /account/recovery](/docs/account#updateRecovery)
|
||||
/// endpoint to complete the process.
|
||||
///
|
||||
Future<Response> createRecovery({@required String email, @required String url}) {
|
||||
final String path = '/account/recovery';
|
||||
|
||||
|
|
@ -129,8 +206,15 @@ class Account extends Service {
|
|||
'url': url,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Complete Password Recovery
|
||||
///
|
||||
/// Use this endpoint to complete the user account password reset. Both the
|
||||
/// **userId** and **secret** arguments will be passed as query parameters to
|
||||
/// the redirect URL you have provided when sending your request to the [POST
|
||||
|
|
@ -140,30 +224,47 @@ class Account extends Service {
|
|||
/// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
|
||||
/// the only valid redirect URLs are the ones from domains you have set when
|
||||
/// adding your platforms in the console interface.
|
||||
Future<Response> updateRecovery({@required String userId, @required String secret, @required String passwordA, @required String passwordB}) {
|
||||
///
|
||||
Future<Response> updateRecovery({@required String userId, @required String secret, @required String password, @required String passwordAgain}) {
|
||||
final String path = '/account/recovery';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'userId': userId,
|
||||
'secret': secret,
|
||||
'password-a': passwordA,
|
||||
'password-b': passwordB,
|
||||
'password': password,
|
||||
'passwordAgain': passwordAgain,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.put, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.put, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Account Sessions
|
||||
///
|
||||
/// Get currently logged in user list of active sessions across different
|
||||
/// devices.
|
||||
///
|
||||
Future<Response> getSessions() {
|
||||
final String path = '/account/sessions';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Account Session
|
||||
///
|
||||
/// Allow the user to login into his account by providing a valid email and
|
||||
/// password combination. This route will create a new session for the user.
|
||||
///
|
||||
Future<Response> createSession({@required String email, @required String password}) {
|
||||
final String path = '/account/sessions';
|
||||
|
||||
|
|
@ -172,43 +273,86 @@ class Account extends Service {
|
|||
'password': password,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete All Account Sessions
|
||||
///
|
||||
/// Delete all sessions from the user account and remove any sessions cookies
|
||||
/// from the end client.
|
||||
///
|
||||
Future<Response> deleteSessions() {
|
||||
final String path = '/account/sessions';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Account Session with OAuth2
|
||||
///
|
||||
/// Allow the user to login to his account using the OAuth2 provider of his
|
||||
/// choice. Each OAuth2 provider should be enabled from the Appwrite console
|
||||
/// first. Use the success and failure arguments to provide a redirect URL's
|
||||
/// back to your app when login is completed.
|
||||
Future<Response> createOAuth2Session({@required String provider, @required String success, @required String failure}) {
|
||||
///
|
||||
Future createOAuth2Session({@required String provider, String success = 'https://appwrite.io/auth/oauth2/success', String failure = 'https://appwrite.io/auth/oauth2/failure'}) {
|
||||
final String path = '/account/sessions/oauth2/{provider}'.replaceAll(RegExp('{provider}'), provider);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'success': success,
|
||||
'failure': failure,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return FlutterWebAuth.authenticate(
|
||||
url: url.toString(),
|
||||
callbackUrlScheme: "appwrite-callback-" + client.config['project']
|
||||
).then((value) {
|
||||
Uri url = Uri.parse(value);
|
||||
List<Cookie> cookies = [new Cookie(url.queryParameters['key'], url.queryParameters['secret'])];
|
||||
client.cookieJar.saveFromResponse(Uri.parse(client.endPoint), cookies);
|
||||
});
|
||||
}
|
||||
|
||||
/// Delete Account Session
|
||||
///
|
||||
/// Use this endpoint to log out the currently logged in user from all his
|
||||
/// account sessions across all his different devices. When using the option id
|
||||
/// argument, only the session unique ID provider will be deleted.
|
||||
///
|
||||
Future<Response> deleteSession({@required String sessionId}) {
|
||||
final String path = '/account/sessions/{sessionId}'.replaceAll(RegExp('{sessionId}'), sessionId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Email Verification
|
||||
///
|
||||
/// Use this endpoint to send a verification message to your user email address
|
||||
/// to confirm they are the valid owners of that address. Both the **userId**
|
||||
/// and **secret** arguments will be passed as query parameters to the URL you
|
||||
|
|
@ -222,6 +366,7 @@ class Account extends Service {
|
|||
/// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
|
||||
/// the only valid redirect URLs are the ones from domains you have set when
|
||||
/// adding your platforms in the console interface.
|
||||
///
|
||||
Future<Response> createVerification({@required String url}) {
|
||||
final String path = '/account/verification';
|
||||
|
||||
|
|
@ -229,12 +374,20 @@ class Account extends Service {
|
|||
'url': url,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Complete Email Verification
|
||||
///
|
||||
/// Use this endpoint to complete the user email verification process. Use both
|
||||
/// the **userId** and **secret** parameters that were attached to your app URL
|
||||
/// to verify the user email ownership. If confirmed this route will return a
|
||||
/// 200 status code.
|
||||
///
|
||||
Future<Response> updateVerification({@required String userId, @required String secret}) {
|
||||
final String path = '/account/verification';
|
||||
|
||||
|
|
@ -243,6 +396,10 @@ class Account extends Service {
|
|||
'secret': secret,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.put, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.put, path: path, params: params, headers: headers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
|
@ -7,13 +8,15 @@ import '../enums.dart';
|
|||
import "../service.dart";
|
||||
|
||||
class Avatars extends Service {
|
||||
|
||||
Avatars(Client client): super(client);
|
||||
|
||||
/// Get Browser Icon
|
||||
///
|
||||
/// You can use this endpoint to show different browser icons to your users.
|
||||
/// The code argument receives the browser code as it appears in your user
|
||||
/// /account/sessions endpoint. Use width, height and quality arguments to
|
||||
/// change the output settings.
|
||||
///
|
||||
Future<Response> getBrowser({@required String code, int width = 100, int height = 100, int quality = 100}) {
|
||||
final String path = '/avatars/browsers/{code}'.replaceAll(RegExp('{code}'), code);
|
||||
|
||||
|
|
@ -23,66 +26,126 @@ class Avatars extends Service {
|
|||
'quality': quality,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Credit Card Icon
|
||||
///
|
||||
/// Need to display your users with your billing method or their payment
|
||||
/// methods? The credit card endpoint will return you the icon of the credit
|
||||
/// card provider you need. Use width, height and quality arguments to change
|
||||
/// the output settings.
|
||||
Future<Response> getCreditCard({@required String code, int width = 100, int height = 100, int quality = 100}) {
|
||||
///
|
||||
String getCreditCard({@required String code, int width = 100, int height = 100, int quality = 100}) {
|
||||
final String path = '/avatars/credit-cards/{code}'.replaceAll(RegExp('{code}'), code);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'width': width,
|
||||
'height': height,
|
||||
'quality': quality,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get Favicon
|
||||
///
|
||||
/// Use this endpoint to fetch the favorite icon (AKA favicon) of a any remote
|
||||
/// website URL.
|
||||
Future<Response> getFavicon({@required String url}) {
|
||||
///
|
||||
String getFavicon({@required String url}) {
|
||||
final String path = '/avatars/favicon';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'url': url,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get Country Flag
|
||||
///
|
||||
/// You can use this endpoint to show different country flags icons to your
|
||||
/// users. The code argument receives the 2 letter country code. Use width,
|
||||
/// height and quality arguments to change the output settings.
|
||||
Future<Response> getFlag({@required String code, int width = 100, int height = 100, int quality = 100}) {
|
||||
///
|
||||
String getFlag({@required String code, int width = 100, int height = 100, int quality = 100}) {
|
||||
final String path = '/avatars/flags/{code}'.replaceAll(RegExp('{code}'), code);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'width': width,
|
||||
'height': height,
|
||||
'quality': quality,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get Image from URL
|
||||
///
|
||||
/// Use this endpoint to fetch a remote image URL and crop it to any image size
|
||||
/// you want. This endpoint is very useful if you need to crop and display
|
||||
/// remote images in your app or in case you want to make sure a 3rd party
|
||||
/// image is properly served using a TLS protocol.
|
||||
Future<Response> getImage({@required String url, int width = 400, int height = 400}) {
|
||||
///
|
||||
String getImage({@required String url, int width = 400, int height = 400}) {
|
||||
final String path = '/avatars/image';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'url': url,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get QR Code
|
||||
///
|
||||
/// Converts a given plain text to a QR code image. You can use the query
|
||||
/// parameters to change the size and style of the resulting image.
|
||||
Future<Response> getQR({@required String text, int size = 400, int margin = 1, int download = null}) {
|
||||
///
|
||||
String getQR({@required String text, int size = 400, int margin = 1, int download = 0}) {
|
||||
final String path = '/avatars/qr';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -90,8 +153,17 @@ class Avatars extends Service {
|
|||
'size': size,
|
||||
'margin': margin,
|
||||
'download': download,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
|
@ -7,32 +8,42 @@ import '../enums.dart';
|
|||
import "../service.dart";
|
||||
|
||||
class Database extends Service {
|
||||
|
||||
Database(Client client): super(client);
|
||||
|
||||
/// List Documents
|
||||
///
|
||||
/// Get a list of all the user documents. You can use the query params to
|
||||
/// filter your results. On admin mode, this endpoint will return a list of all
|
||||
/// of the project documents. [Learn more about different API
|
||||
/// modes](/docs/admin).
|
||||
Future<Response> listDocuments({@required String collectionId, List filters = const [], int offset = null, int limit = 50, String orderField = '\$id', String orderType = 'ASC', String orderCast = 'string', String search = null, int first = null, int last = null}) {
|
||||
///
|
||||
Future<Response> listDocuments({@required String collectionId, List filters = const [], int offset = 0, int limit = 50, String orderField = '\$id', OrderType orderType = OrderType.asc, String orderCast = 'string', String search = '', int first = 0, int last = 0}) {
|
||||
final String path = '/database/collections/{collectionId}/documents'.replaceAll(RegExp('{collectionId}'), collectionId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'filters': filters,
|
||||
'offset': offset,
|
||||
'limit': limit,
|
||||
'order-field': orderField,
|
||||
'order-type': orderType,
|
||||
'order-cast': orderCast,
|
||||
'orderField': orderField,
|
||||
'orderType': orderType.name(),
|
||||
'orderCast': orderCast,
|
||||
'search': search,
|
||||
'first': first,
|
||||
'last': last,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Document
|
||||
///
|
||||
/// Create a new Document.
|
||||
Future<Response> createDocument({@required String collectionId, @required dynamic data, @required List read, @required List write, String parentDocument = null, String parentProperty = null, String parentPropertyType = 'assign'}) {
|
||||
///
|
||||
Future<Response> createDocument({@required String collectionId, @required dynamic data, @required List read, @required List write, String parentDocument = '', String parentProperty = '', String parentPropertyType = 'assign'}) {
|
||||
final String path = '/database/collections/{collectionId}/documents'.replaceAll(RegExp('{collectionId}'), collectionId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -44,18 +55,32 @@ class Database extends Service {
|
|||
'parentPropertyType': parentPropertyType,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Document
|
||||
///
|
||||
/// Get document by its unique ID. This endpoint response returns a JSON object
|
||||
/// with the document data.
|
||||
///
|
||||
Future<Response> getDocument({@required String collectionId, @required String documentId}) {
|
||||
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll(RegExp('{collectionId}'), collectionId).replaceAll(RegExp('{documentId}'), documentId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Document
|
||||
Future<Response> updateDocument({@required String collectionId, @required String documentId, @required dynamic data, @required List read, @required List write}) {
|
||||
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll(RegExp('{collectionId}'), collectionId).replaceAll(RegExp('{documentId}'), documentId);
|
||||
|
||||
|
|
@ -65,17 +90,29 @@ class Database extends Service {
|
|||
'write': write,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete Document
|
||||
///
|
||||
/// Delete document by its unique ID. This endpoint deletes only the parent
|
||||
/// documents, his attributes and relations to other documents. Child documents
|
||||
/// **will not** be deleted.
|
||||
///
|
||||
Future<Response> deleteDocument({@required String collectionId, @required String documentId}) {
|
||||
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll(RegExp('{collectionId}'), collectionId).replaceAll(RegExp('{documentId}'), documentId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
|
@ -7,72 +8,118 @@ import '../enums.dart';
|
|||
import "../service.dart";
|
||||
|
||||
class Locale extends Service {
|
||||
|
||||
Locale(Client client): super(client);
|
||||
|
||||
/// Get User Locale
|
||||
///
|
||||
/// Get the current user location based on IP. Returns an object with user
|
||||
/// country code, country name, continent name, continent code, ip address and
|
||||
/// suggested currency. You can use the locale header to get the data in a
|
||||
/// supported language.
|
||||
///
|
||||
/// ([IP Geolocation by DB-IP](https://db-ip.com))
|
||||
///
|
||||
Future<Response> get() {
|
||||
final String path = '/locale';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// List Continents
|
||||
///
|
||||
/// List of all continents. You can use the locale header to get the data in a
|
||||
/// supported language.
|
||||
///
|
||||
Future<Response> getContinents() {
|
||||
final String path = '/locale/continents';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// List Countries
|
||||
///
|
||||
/// List of all countries. You can use the locale header to get the data in a
|
||||
/// supported language.
|
||||
///
|
||||
Future<Response> getCountries() {
|
||||
final String path = '/locale/countries';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// List EU Countries
|
||||
///
|
||||
/// List of all countries that are currently members of the EU. You can use the
|
||||
/// locale header to get the data in a supported language.
|
||||
///
|
||||
Future<Response> getCountriesEU() {
|
||||
final String path = '/locale/countries/eu';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// List Countries Phone Codes
|
||||
///
|
||||
/// List of all countries phone codes. You can use the locale header to get the
|
||||
/// data in a supported language.
|
||||
///
|
||||
Future<Response> getCountriesPhones() {
|
||||
final String path = '/locale/countries/phones';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// List Currencies
|
||||
///
|
||||
/// List of all currencies, including currency symol, name, plural, and decimal
|
||||
/// digits for all major and minor currencies. You can use the locale header to
|
||||
/// get the data in a supported language.
|
||||
///
|
||||
Future<Response> getCurrencies() {
|
||||
final String path = '/locale/currencies';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
|
@ -7,13 +8,15 @@ import '../enums.dart';
|
|||
import "../service.dart";
|
||||
|
||||
class Storage extends Service {
|
||||
|
||||
Storage(Client client): super(client);
|
||||
|
||||
/// List Files
|
||||
///
|
||||
/// Get a list of all the user files. You can use the query params to filter
|
||||
/// your results. On admin mode, this endpoint will return a list of all of the
|
||||
/// project files. [Learn more about different API modes](/docs/admin).
|
||||
Future<Response> listFiles({String search = null, int limit = 25, int offset = null, OrderType orderType = OrderType.asc}) {
|
||||
///
|
||||
Future<Response> listFiles({String search = '', int limit = 25, int offset = 0, OrderType orderType = OrderType.asc}) {
|
||||
final String path = '/storage/files';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -23,12 +26,20 @@ class Storage extends Service {
|
|||
'orderType': orderType.name(),
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create File
|
||||
///
|
||||
/// Create a new file. The user who creates the file will automatically be
|
||||
/// assigned to read and write access unless he has passed custom values for
|
||||
/// read and write arguments.
|
||||
Future<Response> createFile({@required file, @required List read, @required List write}) {
|
||||
///
|
||||
Future<Response> createFile({@required MultipartFile file, @required List read, @required List write}) {
|
||||
final String path = '/storage/files';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -37,20 +48,36 @@ class Storage extends Service {
|
|||
'write': write,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'multipart/form-data',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get File
|
||||
///
|
||||
/// Get file by its unique ID. This endpoint response returns a JSON object
|
||||
/// with the file metadata.
|
||||
///
|
||||
Future<Response> getFile({@required String fileId}) {
|
||||
final String path = '/storage/files/{fileId}'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update File
|
||||
///
|
||||
/// Update file by its unique ID. Only users with write permissions have access
|
||||
/// to update this resource.
|
||||
///
|
||||
Future<Response> updateFile({@required String fileId, @required List read, @required List write}) {
|
||||
final String path = '/storage/files/{fileId}'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
|
|
@ -59,34 +86,63 @@ class Storage extends Service {
|
|||
'write': write,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.put, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.put, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete File
|
||||
///
|
||||
/// Delete a file by its unique ID. Only users with write permissions have
|
||||
/// access to delete this resource.
|
||||
///
|
||||
Future<Response> deleteFile({@required String fileId}) {
|
||||
final String path = '/storage/files/{fileId}'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get File for Download
|
||||
///
|
||||
/// Get file content by its unique ID. The endpoint response return with a
|
||||
/// 'Content-Disposition: attachment' header that tells the browser to start
|
||||
/// downloading the file to user downloads directory.
|
||||
Future<Response> getFileDownload({@required String fileId}) {
|
||||
///
|
||||
String getFileDownload({@required String fileId}) {
|
||||
final String path = '/storage/files/{fileId}/download'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get File Preview
|
||||
///
|
||||
/// Get a file preview image. Currently, this method supports preview for image
|
||||
/// files (jpg, png, and gif), other supported formats, like pdf, docs, slides,
|
||||
/// and spreadsheets, will return the file icon image. You can also pass query
|
||||
/// string arguments for cutting and resizing your preview image.
|
||||
Future<Response> getFilePreview({@required String fileId, int width = null, int height = null, int quality = 100, String background = null, String output = null}) {
|
||||
///
|
||||
String getFilePreview({@required String fileId, int width = 0, int height = 0, int quality = 100, String background = '', String output = ''}) {
|
||||
final String path = '/storage/files/{fileId}/preview'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -95,19 +151,41 @@ class Storage extends Service {
|
|||
'quality': quality,
|
||||
'background': background,
|
||||
'output': output,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/// Get File for View
|
||||
///
|
||||
/// Get file content by its unique ID. This endpoint is similar to the download
|
||||
/// method but returns with no 'Content-Disposition: attachment' header.
|
||||
Future<Response> getFileView({@required String fileId, String as = null}) {
|
||||
///
|
||||
String getFileView({@required String fileId, String as = ''}) {
|
||||
final String path = '/storage/files/{fileId}/view'.replaceAll(RegExp('{fileId}'), fileId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
'as': as,
|
||||
'project': client.config['project'],
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
Uri endpoint = Uri.parse(client.endPoint);
|
||||
Uri url = new Uri(scheme: endpoint.scheme,
|
||||
host: endpoint.host,
|
||||
port: endpoint.port,
|
||||
path: endpoint.path + path,
|
||||
queryParameters:params,
|
||||
);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
|
@ -7,13 +8,15 @@ import '../enums.dart';
|
|||
import "../service.dart";
|
||||
|
||||
class Teams extends Service {
|
||||
|
||||
Teams(Client client): super(client);
|
||||
|
||||
/// List Teams
|
||||
///
|
||||
/// Get a list of all the current user teams. You can use the query params to
|
||||
/// filter your results. On admin mode, this endpoint will return a list of all
|
||||
/// of the project teams. [Learn more about different API modes](/docs/admin).
|
||||
Future<Response> list({String search = null, int limit = 25, int offset = null, OrderType orderType = OrderType.asc}) {
|
||||
///
|
||||
Future<Response> list({String search = '', int limit = 25, int offset = 0, OrderType orderType = OrderType.asc}) {
|
||||
final String path = '/teams';
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -23,12 +26,20 @@ class Teams extends Service {
|
|||
'orderType': orderType.name(),
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Team
|
||||
///
|
||||
/// Create a new team. The user who creates the team will automatically be
|
||||
/// assigned as the owner of the team. The team owner can invite new members,
|
||||
/// who will be able add new owners and update or delete the team from your
|
||||
/// project.
|
||||
///
|
||||
Future<Response> create({@required String name, List roles = const ["owner"]}) {
|
||||
final String path = '/teams';
|
||||
|
||||
|
|
@ -37,20 +48,36 @@ class Teams extends Service {
|
|||
'roles': roles,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Team
|
||||
///
|
||||
/// Get team by its unique ID. All team members have read access for this
|
||||
/// resource.
|
||||
///
|
||||
Future<Response> get({@required String teamId}) {
|
||||
final String path = '/teams/{teamId}'.replaceAll(RegExp('{teamId}'), teamId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Team
|
||||
///
|
||||
/// Update team by its unique ID. Only team owners have write access for this
|
||||
/// resource.
|
||||
///
|
||||
Future<Response> update({@required String teamId, @required String name}) {
|
||||
final String path = '/teams/{teamId}'.replaceAll(RegExp('{teamId}'), teamId);
|
||||
|
||||
|
|
@ -58,28 +85,51 @@ class Teams extends Service {
|
|||
'name': name,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.put, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.put, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete Team
|
||||
///
|
||||
/// Delete team by its unique ID. Only team owners have write access for this
|
||||
/// resource.
|
||||
///
|
||||
Future<Response> delete({@required String teamId}) {
|
||||
final String path = '/teams/{teamId}'.replaceAll(RegExp('{teamId}'), teamId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Get Team Memberships
|
||||
///
|
||||
/// Get team members by the team unique ID. All team members have read access
|
||||
/// for this list of resources.
|
||||
///
|
||||
Future<Response> getMemberships({@required String teamId}) {
|
||||
final String path = '/teams/{teamId}/memberships'.replaceAll(RegExp('{teamId}'), teamId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.get, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.get, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Create Team Membership
|
||||
///
|
||||
/// Use this endpoint to invite a new member to join your team. An email with a
|
||||
/// link to join the team will be sent to the new member email address if the
|
||||
/// member doesn't exist in the project it will be created automatically.
|
||||
|
|
@ -93,7 +143,8 @@ class Teams extends Service {
|
|||
/// Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
|
||||
/// the only valid redirect URL's are the once from domains you have set when
|
||||
/// added your platforms in the console interface.
|
||||
Future<Response> createMembership({@required String teamId, @required String email, @required List roles, @required String url, String name = null}) {
|
||||
///
|
||||
Future<Response> createMembership({@required String teamId, @required String email, @required List roles, @required String url, String name = ''}) {
|
||||
final String path = '/teams/{teamId}/memberships'.replaceAll(RegExp('{teamId}'), teamId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
|
|
@ -103,22 +154,38 @@ class Teams extends Service {
|
|||
'url': url,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.post, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.post, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Delete Team Membership
|
||||
///
|
||||
/// This endpoint allows a user to leave a team or for a team owner to delete
|
||||
/// the membership of any other team member. You can also use this endpoint to
|
||||
/// delete a user membership even if he didn't accept it.
|
||||
///
|
||||
Future<Response> deleteMembership({@required String teamId, @required String inviteId}) {
|
||||
final String path = '/teams/{teamId}/memberships/{inviteId}'.replaceAll(RegExp('{teamId}'), teamId).replaceAll(RegExp('{inviteId}'), inviteId);
|
||||
|
||||
final Map<String, dynamic> params = {
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.delete, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.delete, path: path, params: params, headers: headers);
|
||||
}
|
||||
|
||||
/// Update Team Membership Status
|
||||
///
|
||||
/// Use this endpoint to allow a user to accept an invitation to join a team
|
||||
/// after he is being redirected back to your app from the invitation email he
|
||||
/// was sent.
|
||||
///
|
||||
Future<Response> updateMembershipStatus({@required String teamId, @required String inviteId, @required String userId, @required String secret}) {
|
||||
final String path = '/teams/{teamId}/memberships/{inviteId}/status'.replaceAll(RegExp('{teamId}'), teamId).replaceAll(RegExp('{inviteId}'), inviteId);
|
||||
|
||||
|
|
@ -127,6 +194,10 @@ class Teams extends Service {
|
|||
'secret': secret,
|
||||
};
|
||||
|
||||
return this.client.call(HttpMethod.patch, path: path, params: params);
|
||||
final Map<String, String> headers = {
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
|
||||
return client.call(HttpMethod.patch, path: path, params: params, headers: headers);
|
||||
}
|
||||
}
|
||||
38
app/sdks/client-flutter/pubspec.yaml
Normal file
38
app/sdks/client-flutter/pubspec.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
name: appwrite
|
||||
version: 0.2.1
|
||||
description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API
|
||||
homepage: https://appwrite.io
|
||||
repository: https://github.com/appwrite/sdk-for-flutter
|
||||
issue_tracker: https://github.com/appwrite/sdk-generator/issues
|
||||
documentation: https://appwrite.io/support
|
||||
environment:
|
||||
sdk: '>=2.6.0 <3.0.0'
|
||||
dependencies:
|
||||
meta: ^1.1.8
|
||||
path_provider: ^1.6.5
|
||||
package_info: ^0.4.0+16
|
||||
dio: ^3.0.0
|
||||
cookie_jar: ^1.0.0
|
||||
dio_cookie_manager: ^1.0.0
|
||||
flutter_web_auth: ^0.2.4
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
|
||||
# The following line ensures that the Material Icons font is
|
||||
# included with your application, so that you can use the icons in
|
||||
# the material Icons class.
|
||||
uses-material-design: true
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
# Appwrite SDK for JavaScript
|
||||
# Appwrite Web SDK
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
|
||||
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way.
|
||||
Use the Web SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.
|
||||
For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
|
||||
|
||||

|
||||
|
||||
|
|
@ -31,21 +33,6 @@ To install with a CDN (content delivery network) add the following scripts to th
|
|||
<script src="https://cdn.jsdelivr.net/npm/appwrite@1.0.29"></script>
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
Initialise the Appwrite SDK in your code, and setup your API credentials:
|
||||
|
||||
```js
|
||||
|
||||
// Init your JS SDK
|
||||
var appwrite = new Appwrite();
|
||||
|
||||
appwrite
|
||||
.setEndpoint('http://localhost/v1') // Set only when using self-hosted solution
|
||||
.setProject('455x34dfkj') // Your Appwrite Project UID
|
||||
;
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Contribution
|
||||
|
|
@ -4,7 +4,7 @@ sdk
|
|||
.setProject('5df5acd0d48c2') // Your project ID
|
||||
;
|
||||
|
||||
let promise = sdk.avatars.getImage('https://example.com');
|
||||
let promise = sdk.account.createOAuth2Session('bitbucket');
|
||||
|
||||
promise.then(function (response) {
|
||||
console.log(response); // Success
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue