1
0
Fork 0
mirror of synced 2024-07-03 05:31:38 +12:00

Merge pull request #399 from appwrite/team-features

Team features
This commit is contained in:
Eldad A. Fux 2020-06-11 11:24:48 +03:00 committed by GitHub
commit 50d934bac2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 878 additions and 281 deletions

View file

@ -6,10 +6,14 @@
- Added option to force HTTPS connection to the Appwrite server (_APP_OPTIONS_FORCE_HTTPS) - Added option to force HTTPS connection to the Appwrite server (_APP_OPTIONS_FORCE_HTTPS)
- Added Google Fonts to Appwrite for offline availability - Added Google Fonts to Appwrite for offline availability
- Added a new route in the Avatars API to get user initials avatar - Added a new route in the Avatars API to get user initials avatar
- Added option to delete team from the console
- Added option to view team members from the console
- Added option to join a user to any team from the console
## Bug Fixes ## Bug Fixes
- Fixed output of /v1/health/queue/certificates returning wrong data - Fixed output of /v1/health/queue/certificates returning wrong data
- Fixed bug where team members count was wrong in some cases
- Fixed network calculation for uploaded files - Fixed network calculation for uploaded files
- Fixed a UI bug preventing float values in numeric fields - Fixed a UI bug preventing float values in numeric fields

View file

@ -215,7 +215,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
->param('roles', [], function () { return new ArrayList(new Text(128)); }, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions).') ->param('roles', [], function () { return new ArrayList(new Text(128)); }, 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions).')
->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add our own built-in confirm page ->param('url', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.') // TODO add our own built-in confirm page
->action( ->action(
function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB) { function ($teamId, $email, $name, $roles, $url) use ($response, $register, $project, $user, $audit, $projectDB, $mode) {
$name = (empty($name)) ? $email : $name; $name = (empty($name)) ? $email : $name;
$team = $projectDB->getDocument($teamId); $team = $projectDB->getDocument($teamId);
@ -285,7 +285,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
} }
} }
if (!$isOwner) { if (!$isOwner && (APP_MODE_ADMIN !== $mode)) {
throw new Exception('User is not allowed to send invitations for this team', 401); throw new Exception('User is not allowed to send invitations for this team', 401);
} }
@ -302,11 +302,18 @@ $utopia->post('/v1/teams/:teamId/memberships')
'roles' => $roles, 'roles' => $roles,
'invited' => time(), 'invited' => time(),
'joined' => 0, 'joined' => 0,
'confirm' => false, 'confirm' => (APP_MODE_ADMIN === $mode),
'secret' => Auth::hash($secret), 'secret' => Auth::hash($secret),
]); ]);
$membership = $projectDB->createDocument($membership->getArrayCopy()); if(APP_MODE_ADMIN === $mode) { // Allow admin to create membership
Authorization::disable();
$membership = $projectDB->createDocument($membership->getArrayCopy());
Authorization::reset();
}
else {
$membership = $projectDB->createDocument($membership->getArrayCopy());
}
if (false === $membership) { if (false === $membership) {
throw new Exception('Failed saving membership to DB', 500); throw new Exception('Failed saving membership to DB', 500);
@ -334,7 +341,9 @@ $utopia->post('/v1/teams/:teamId/memberships')
$mail->AltBody = strip_tags($body->render()); $mail->AltBody = strip_tags($body->render());
try { try {
$mail->send(); if(APP_MODE_ADMIN !== $mode) { // No need in comfirmation when in admin mode
$mail->send();
}
} catch (\Exception $error) { } catch (\Exception $error) {
throw new Exception('Error sending mail: ' . $error->getMessage(), 500); throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
} }
@ -371,8 +380,12 @@ $utopia->get('/v1/teams/:teamId/memberships')
->label('sdk.method', 'getMemberships') ->label('sdk.method', 'getMemberships')
->label('sdk.description', '/docs/references/teams/get-team-members.md') ->label('sdk.description', '/docs/references/teams/get-team-members.md')
->param('teamId', '', function () { return new UID(); }, 'Team unique ID.') ->param('teamId', '', function () { return new UID(); }, 'Team unique ID.')
->param('search', '', function () { return new Text(256); }, 'Search term to filter your list results.', true)
->param('limit', 25, function () { return new Range(0, 100); }, 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, function () { return new Range(0, 2000); }, 'Results offset. The default value is 0. Use this param to manage pagination.', true)
->param('orderType', 'ASC', function () { return new WhiteList(['ASC', 'DESC']); }, 'Order result by ASC or DESC order.', true)
->action( ->action(
function ($teamId) use ($response, $projectDB) { function ($teamId, $search, $limit, $offset, $orderType) use ($response, $projectDB) {
$team = $projectDB->getDocument($teamId); $team = $projectDB->getDocument($teamId);
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) { if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
@ -380,8 +393,12 @@ $utopia->get('/v1/teams/:teamId/memberships')
} }
$memberships = $projectDB->getCollection([ $memberships = $projectDB->getCollection([
'limit' => 50, 'limit' => $limit,
'offset' => 0, 'offset' => $offset,
'orderField' => 'joined',
'orderType' => $orderType,
'orderCast' => 'int',
'search' => $search,
'filters' => [ 'filters' => [
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS, '$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
'teamId='.$teamId, 'teamId='.$teamId,
@ -408,15 +425,8 @@ $utopia->get('/v1/teams/:teamId/memberships')
])); ]));
} }
usort($users, function ($a, $b) { $response->json(['sum' => $projectDB->getSum(), 'memberships' => $users]);
if ($a['joined'] === 0 || $b['joined'] === 0) {
return $b['joined'] - $a['joined'];
}
return $a['joined'] - $b['joined'];
});
$response->json($users);
} }
); );
@ -583,9 +593,11 @@ $utopia->delete('/v1/teams/:teamId/memberships/:inviteId')
throw new Exception('Failed to remove membership from DB', 500); throw new Exception('Failed to remove membership from DB', 500);
} }
$team = $projectDB->updateDocument(array_merge($team->getArrayCopy(), [ if ($membership->getAttribute('confirm')) { // Count only confirmed members
'sum' => $team->getAttribute('sum', 0) - 1, $team = $projectDB->updateDocument(array_merge($team->getArrayCopy(), [
])); 'sum' => $team->getAttribute('sum', 0) - 1,
]));
}
if (false === $team) { if (false === $team) {
throw new Exception('Failed saving team to DB', 500); throw new Exception('Failed saving team to DB', 500);

View file

@ -277,14 +277,26 @@ $utopia->get('/console/users')
->setParam('body', $page); ->setParam('body', $page);
}); });
$utopia->get('/console/users/view') $utopia->get('/console/users/user')
->desc('Platform console project user') ->desc('Platform console project user')
->label('permission', 'public') ->label('permission', 'public')
->label('scope', 'console') ->label('scope', 'console')
->action(function () use ($layout) { ->action(function () use ($layout) {
$page = new View(__DIR__.'/../../views/console/users/view.phtml'); $page = new View(__DIR__.'/../../views/console/users/user.phtml');
$layout $layout
->setParam('title', APP_NAME.' - View User') ->setParam('title', APP_NAME.' - User')
->setParam('body', $page);
});
$utopia->get('/console/users/teams/team')
->desc('Platform console project team')
->label('permission', 'public')
->label('scope', 'console')
->action(function () use ($layout) {
$page = new View(__DIR__.'/../../views/console/users/team.phtml');
$layout
->setParam('title', APP_NAME.' - Team')
->setParam('body', $page); ->setParam('body', $page);
}); });

View file

@ -1,7 +1,7 @@
# Appwrite Web SDK # Appwrite Web SDK
![License](https://img.shields.io/github/license/appwrite/sdk-for-js.svg?v=1) ![License](https://img.shields.io/github/license/appwrite/sdk-for-js.svg?v=1)
![Version](https://img.shields.io/badge/api%20version-0.6.1-blue.svg?v=1) ![Version](https://img.shields.io/badge/api%20version-0.6.2-blue.svg?v=1)
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. 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. Use the Web SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.

View file

@ -5,7 +5,7 @@ sdk
.setProject('5df5acd0d48c2') // Your project ID .setProject('5df5acd0d48c2') // Your project ID
; ;
let promise = sdk.account.createOAuth2Session('bitbucket'); let promise = sdk.account.createOAuth2Session('amazon');
promise.then(function (response) { promise.then(function (response) {
console.log(response); // Success console.log(response); // Success

View file

@ -276,10 +276,10 @@
* *
* Use this endpoint to allow a new user to register a new account in your * 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 * project. After the user registration completes successfully, you can use
* the [/account/verfication](/docs/account#createVerification) route to start * the [/account/verfication](/docs/client/account#createVerification) route
* verifying the user email address. To allow your new user to login to his * to start verifying the user email address. To allow your new user to login
* new account, you need to create a new [account * to his new account, you need to create a new [account
* session](/docs/account#createSession). * session](/docs/client/account#createSession).
* *
* @param {string} email * @param {string} email
* @param {string} password * @param {string} password
@ -522,7 +522,7 @@
* When the user clicks the confirmation link he is redirected back to your * 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 * 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 * attached to the URL query string. Use the query string params to submit a
* request to the [PUT /account/recovery](/docs/account#updateRecovery) * request to the [PUT /account/recovery](/docs/client/account#updateRecovery)
* endpoint to complete the process. * endpoint to complete the process.
* *
* @param {string} email * @param {string} email
@ -563,7 +563,7 @@
* Use this endpoint to complete the user account password reset. Both the * Use this endpoint to complete the user account password reset. Both the
* **userId** and **secret** arguments will be passed as query parameters to * **userId** and **secret** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the [POST * the redirect URL you have provided when sending your request to the [POST
* /account/recovery](/docs/account#createRecovery) endpoint. * /account/recovery](/docs/client/account#createRecovery) endpoint.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -772,7 +772,7 @@
* should redirect the user back for your app and allow you to complete the * should redirect the user back for your app and allow you to complete the
* verification process by verifying both the **userId** and **secret** * verification process by verifying both the **userId** and **secret**
* parameters. Learn more about how to [complete the verification * parameters. Learn more about how to [complete the verification
* process](/docs/account#updateAccountVerification). * process](/docs/client/account#updateAccountVerification).
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -1168,7 +1168,10 @@
/** /**
* Create Document * Create Document
* *
* Create a new Document. * Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database?sdk=nodejs#createCollection) API or
* directly from your database console.
* *
* @param {string} collectionId * @param {string} collectionId
* @param {object} data * @param {object} data
@ -1942,10 +1945,14 @@
* for this list of resources. * for this list of resources.
* *
* @param {string} teamId * @param {string} teamId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} orderType
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getMemberships: function(teamId) { getMemberships: function(teamId, search = '', limit = 25, offset = 0, orderType = 'ASC') {
if(teamId === undefined) { if(teamId === undefined) {
throw new Error('Missing required parameter: "teamId"'); throw new Error('Missing required parameter: "teamId"');
} }
@ -1954,6 +1961,22 @@
let payload = {}; let payload = {};
if(search) {
payload['search'] = search;
}
if(limit) {
payload['limit'] = limit;
}
if(offset) {
payload['offset'] = offset;
}
if(orderType) {
payload['orderType'] = orderType;
}
return http return http
.get(path, { .get(path, {
'content-type': 'application/json', 'content-type': 'application/json',
@ -1969,8 +1992,8 @@
* *
* Use the 'URL' parameter to redirect the user from the invitation email back * Use the 'URL' parameter to redirect the user from the invitation email back
* to your app. When the user is redirected, use the [Update Team Membership * to your app. When the user is redirected, use the [Update Team Membership
* Status](/docs/teams#updateMembershipStatus) endpoint to allow the user to * Status](/docs/client/teams#updateMembershipStatus) endpoint to allow the
* accept the invitation to the team. * user to accept the invitation to the team.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)

View file

@ -148,8 +148,12 @@ let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payloa
if(name===undefined){throw new Error('Missing required parameter: "name"')} if(name===undefined){throw new Error('Missing required parameter: "name"')}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload.name=name} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload.name=name}
return http.put(path,{'content-type':'application/json',},payload)},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} return http.put(path,{'content-type':'application/json',},payload)},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload)},getMemberships:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload)},getMemberships:function(teamId,search='',limit=25,offset=0,orderType='ASC'){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.get(path,{'content-type':'application/json',},payload)},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(search){payload.search=search}
if(limit){payload.limit=limit}
if(offset){payload.offset=offset}
if(orderType){payload.orderType=orderType}
return http.get(path,{'content-type':'application/json',},payload)},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
if(email===undefined){throw new Error('Missing required parameter: "email"')} if(email===undefined){throw new Error('Missing required parameter: "email"')}
if(roles===undefined){throw new Error('Missing required parameter: "roles"')} if(roles===undefined){throw new Error('Missing required parameter: "roles"')}
if(url===undefined){throw new Error('Missing required parameter: "url"')} if(url===undefined){throw new Error('Missing required parameter: "url"')}

View file

@ -64,10 +64,10 @@ declare namespace Appwrite {
* *
* Use this endpoint to allow a new user to register a new account in your * 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 * project. After the user registration completes successfully, you can use
* the [/account/verfication](/docs/account#createVerification) route to start * the [/account/verfication](/docs/client/account#createVerification) route
* verifying the user email address. To allow your new user to login to his * to start verifying the user email address. To allow your new user to login
* new account, you need to create a new [account * to his new account, you need to create a new [account
* session](/docs/account#createSession). * session](/docs/client/account#createSession).
* *
* @param {string} email * @param {string} email
* @param {string} password * @param {string} password
@ -170,7 +170,7 @@ declare namespace Appwrite {
* When the user clicks the confirmation link he is redirected back to your * 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 * 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 * attached to the URL query string. Use the query string params to submit a
* request to the [PUT /account/recovery](/docs/account#updateRecovery) * request to the [PUT /account/recovery](/docs/client/account#updateRecovery)
* endpoint to complete the process. * endpoint to complete the process.
* *
* @param {string} email * @param {string} email
@ -186,7 +186,7 @@ declare namespace Appwrite {
* Use this endpoint to complete the user account password reset. Both the * Use this endpoint to complete the user account password reset. Both the
* **userId** and **secret** arguments will be passed as query parameters to * **userId** and **secret** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the [POST * the redirect URL you have provided when sending your request to the [POST
* /account/recovery](/docs/account#createRecovery) endpoint. * /account/recovery](/docs/client/account#createRecovery) endpoint.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -276,7 +276,7 @@ declare namespace Appwrite {
* should redirect the user back for your app and allow you to complete the * should redirect the user back for your app and allow you to complete the
* verification process by verifying both the **userId** and **secret** * verification process by verifying both the **userId** and **secret**
* parameters. Learn more about how to [complete the verification * parameters. Learn more about how to [complete the verification
* process](/docs/account#updateAccountVerification). * process](/docs/client/account#updateAccountVerification).
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -431,7 +431,10 @@ declare namespace Appwrite {
/** /**
* Create Document * Create Document
* *
* Create a new Document. * Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database?sdk=nodejs#createCollection) API or
* directly from your database console.
* *
* @param {string} collectionId * @param {string} collectionId
* @param {object} data * @param {object} data
@ -758,10 +761,14 @@ declare namespace Appwrite {
* for this list of resources. * for this list of resources.
* *
* @param {string} teamId * @param {string} teamId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} orderType
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getMemberships(teamId: string): Promise<object>; getMemberships(teamId: string, search: string, limit: number, offset: number, orderType: string): Promise<object>;
/** /**
* Create Team Membership * Create Team Membership
@ -772,8 +779,8 @@ declare namespace Appwrite {
* *
* Use the 'URL' parameter to redirect the user from the invitation email back * Use the 'URL' parameter to redirect the user from the invitation email back
* to your app. When the user is redirected, use the [Update Team Membership * to your app. When the user is redirected, use the [Update Team Membership
* Status](/docs/teams#updateMembershipStatus) endpoint to allow the user to * Status](/docs/client/teams#updateMembershipStatus) endpoint to allow the
* accept the invitation to the team. * user to accept the invitation to the team.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)

View file

@ -1,7 +1,7 @@
# Appwrite Console SDK # Appwrite Console SDK
![License](https://img.shields.io/github/license/appwrite/sdk-for-console.svg?v=1) ![License](https://img.shields.io/github/license/appwrite/sdk-for-console.svg?v=1)
![Version](https://img.shields.io/badge/api%20version-0.6.1-blue.svg?v=1) ![Version](https://img.shields.io/badge/api%20version-0.6.2-blue.svg?v=1)
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. 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 Console SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. Use the Console SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools.

View file

@ -6,7 +6,7 @@ sdk
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
; ;
let promise = sdk.account.createOAuth2Session('bitbucket'); let promise = sdk.account.createOAuth2Session('amazon');
promise.then(function (response) { promise.then(function (response) {
console.log(response); // Success console.log(response); // Success

View file

@ -6,7 +6,7 @@ sdk
.setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key .setKey('919c2d18fb5d4...a2ae413da83346ad2') // Your secret API key
; ;
let promise = sdk.projects.updateOAuth2('[PROJECT_ID]', 'bitbucket'); let promise = sdk.projects.updateOAuth2('[PROJECT_ID]', 'amazon');
promise.then(function (response) { promise.then(function (response) {
console.log(response); // Success console.log(response); // Success

View file

@ -312,10 +312,10 @@
* *
* Use this endpoint to allow a new user to register a new account in your * 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 * project. After the user registration completes successfully, you can use
* the [/account/verfication](/docs/account#createVerification) route to start * the [/account/verfication](/docs/client/account#createVerification) route
* verifying the user email address. To allow your new user to login to his * to start verifying the user email address. To allow your new user to login
* new account, you need to create a new [account * to his new account, you need to create a new [account
* session](/docs/account#createSession). * session](/docs/client/account#createSession).
* *
* @param {string} email * @param {string} email
* @param {string} password * @param {string} password
@ -558,7 +558,7 @@
* When the user clicks the confirmation link he is redirected back to your * 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 * 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 * attached to the URL query string. Use the query string params to submit a
* request to the [PUT /account/recovery](/docs/account#updateRecovery) * request to the [PUT /account/recovery](/docs/client/account#updateRecovery)
* endpoint to complete the process. * endpoint to complete the process.
* *
* @param {string} email * @param {string} email
@ -599,7 +599,7 @@
* Use this endpoint to complete the user account password reset. Both the * Use this endpoint to complete the user account password reset. Both the
* **userId** and **secret** arguments will be passed as query parameters to * **userId** and **secret** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the [POST * the redirect URL you have provided when sending your request to the [POST
* /account/recovery](/docs/account#createRecovery) endpoint. * /account/recovery](/docs/client/account#createRecovery) endpoint.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -810,7 +810,7 @@
* should redirect the user back for your app and allow you to complete the * should redirect the user back for your app and allow you to complete the
* verification process by verifying both the **userId** and **secret** * verification process by verifying both the **userId** and **secret**
* parameters. Learn more about how to [complete the verification * parameters. Learn more about how to [complete the verification
* process](/docs/account#updateAccountVerification). * process](/docs/client/account#updateAccountVerification).
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -1421,7 +1421,10 @@
/** /**
* Create Document * Create Document
* *
* Create a new Document. * Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database?sdk=nodejs#createCollection) API or
* directly from your database console.
* *
* @param {string} collectionId * @param {string} collectionId
* @param {object} data * @param {object} data
@ -3753,10 +3756,14 @@
* for this list of resources. * for this list of resources.
* *
* @param {string} teamId * @param {string} teamId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} orderType
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getMemberships: function(teamId) { getMemberships: function(teamId, search = '', limit = 25, offset = 0, orderType = 'ASC') {
if(teamId === undefined) { if(teamId === undefined) {
throw new Error('Missing required parameter: "teamId"'); throw new Error('Missing required parameter: "teamId"');
} }
@ -3765,6 +3772,22 @@
let payload = {}; let payload = {};
if(search) {
payload['search'] = search;
}
if(limit) {
payload['limit'] = limit;
}
if(offset) {
payload['offset'] = offset;
}
if(orderType) {
payload['orderType'] = orderType;
}
return http return http
.get(path, { .get(path, {
'content-type': 'application/json', 'content-type': 'application/json',
@ -3780,8 +3803,8 @@
* *
* Use the 'URL' parameter to redirect the user from the invitation email back * Use the 'URL' parameter to redirect the user from the invitation email back
* to your app. When the user is redirected, use the [Update Team Membership * to your app. When the user is redirected, use the [Update Team Membership
* Status](/docs/teams#updateMembershipStatus) endpoint to allow the user to * Status](/docs/client/teams#updateMembershipStatus) endpoint to allow the
* accept the invitation to the team. * user to accept the invitation to the team.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)

View file

@ -319,8 +319,12 @@ let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payloa
if(name===undefined){throw new Error('Missing required parameter: "name"')} if(name===undefined){throw new Error('Missing required parameter: "name"')}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload.name=name} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload.name=name}
return http.put(path,{'content-type':'application/json',},payload)},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} return http.put(path,{'content-type':'application/json',},payload)},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload)},getMemberships:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload)},getMemberships:function(teamId,search='',limit=25,offset=0,orderType='ASC'){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.get(path,{'content-type':'application/json',},payload)},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')} let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(search){payload.search=search}
if(limit){payload.limit=limit}
if(offset){payload.offset=offset}
if(orderType){payload.orderType=orderType}
return http.get(path,{'content-type':'application/json',},payload)},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"')}
if(email===undefined){throw new Error('Missing required parameter: "email"')} if(email===undefined){throw new Error('Missing required parameter: "email"')}
if(roles===undefined){throw new Error('Missing required parameter: "roles"')} if(roles===undefined){throw new Error('Missing required parameter: "roles"')}
if(url===undefined){throw new Error('Missing required parameter: "url"')} if(url===undefined){throw new Error('Missing required parameter: "url"')}

View file

@ -85,10 +85,10 @@ declare namespace Appwrite {
* *
* Use this endpoint to allow a new user to register a new account in your * 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 * project. After the user registration completes successfully, you can use
* the [/account/verfication](/docs/account#createVerification) route to start * the [/account/verfication](/docs/client/account#createVerification) route
* verifying the user email address. To allow your new user to login to his * to start verifying the user email address. To allow your new user to login
* new account, you need to create a new [account * to his new account, you need to create a new [account
* session](/docs/account#createSession). * session](/docs/client/account#createSession).
* *
* @param {string} email * @param {string} email
* @param {string} password * @param {string} password
@ -191,7 +191,7 @@ declare namespace Appwrite {
* When the user clicks the confirmation link he is redirected back to your * 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 * 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 * attached to the URL query string. Use the query string params to submit a
* request to the [PUT /account/recovery](/docs/account#updateRecovery) * request to the [PUT /account/recovery](/docs/client/account#updateRecovery)
* endpoint to complete the process. * endpoint to complete the process.
* *
* @param {string} email * @param {string} email
@ -207,7 +207,7 @@ declare namespace Appwrite {
* Use this endpoint to complete the user account password reset. Both the * Use this endpoint to complete the user account password reset. Both the
* **userId** and **secret** arguments will be passed as query parameters to * **userId** and **secret** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the [POST * the redirect URL you have provided when sending your request to the [POST
* /account/recovery](/docs/account#createRecovery) endpoint. * /account/recovery](/docs/client/account#createRecovery) endpoint.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -297,7 +297,7 @@ declare namespace Appwrite {
* should redirect the user back for your app and allow you to complete the * should redirect the user back for your app and allow you to complete the
* verification process by verifying both the **userId** and **secret** * verification process by verifying both the **userId** and **secret**
* parameters. Learn more about how to [complete the verification * parameters. Learn more about how to [complete the verification
* process](/docs/account#updateAccountVerification). * process](/docs/client/account#updateAccountVerification).
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -522,7 +522,10 @@ declare namespace Appwrite {
/** /**
* Create Document * Create Document
* *
* Create a new Document. * Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database?sdk=nodejs#createCollection) API or
* directly from your database console.
* *
* @param {string} collectionId * @param {string} collectionId
* @param {object} data * @param {object} data
@ -1402,10 +1405,14 @@ declare namespace Appwrite {
* for this list of resources. * for this list of resources.
* *
* @param {string} teamId * @param {string} teamId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} orderType
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getMemberships(teamId: string): Promise<object>; getMemberships(teamId: string, search: string, limit: number, offset: number, orderType: string): Promise<object>;
/** /**
* Create Team Membership * Create Team Membership
@ -1416,8 +1423,8 @@ declare namespace Appwrite {
* *
* Use the 'URL' parameter to redirect the user from the invitation email back * Use the 'URL' parameter to redirect the user from the invitation email back
* to your app. When the user is redirected, use the [Update Team Membership * to your app. When the user is redirected, use the [Update Team Membership
* Status](/docs/teams#updateMembershipStatus) endpoint to allow the user to * Status](/docs/client/teams#updateMembershipStatus) endpoint to allow the
* accept the invitation to the team. * user to accept the invitation to the team.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)

View file

@ -24,13 +24,13 @@
<div class="col span-3 text-align-center margin-bottom"> <div class="col span-3 text-align-center margin-bottom">
<img src="" data-ls-attrs="src={{account|gravatar}}" data-size="200" height="150" alt="User Avatar" class="avatar huge huge margin-bottom-small" /> <img src="" data-ls-attrs="src={{account|gravatar}}" data-size="200" height="150" alt="User Avatar" class="avatar huge huge margin-bottom-small" />
<br /> <!-- <br /> -->
<a href="https://en.gravatar.com/gravatars/new/" rel="noopener" class="button margin-bottom-small link-animation-disabled" target="_blank"><i class="icon-upload"></i> Upload</a> <!-- <a href="https://en.gravatar.com/gravatars/new/" rel="noopener" class="button margin-bottom-small link-animation-disabled" target="_blank"><i class="icon-upload"></i> Upload</a> -->
<br /> <!-- <br /> -->
<small class="text-size-small">(via <a href="https://gravatar.com/" target="_blank" rel="noopener">gravatar.com <i class="icon-link-ext"></i></a>)</small> <!-- <small class="text-size-small">(via <a href="https://gravatar.com/" target="_blank" rel="noopener">gravatar.com <i class="icon-link-ext"></i></a>)</small> -->
</div> </div>
<div class="col span-9"> <div class="col span-9">
@ -57,7 +57,7 @@
<input name="name" id="name" type="text" autocomplete="off" data-ls-bind="{{account.name}}" required class="margin-bottom-no"> <input name="name" id="name" type="text" autocomplete="off" data-ls-bind="{{account.name}}" required class="margin-bottom-no">
</div> </div>
<div class="col span-4"> <div class="col span-4">
<button type="submit" class="fill reverse margin-bottom-no">Update Name</button> <button type="submit" class="fill margin-bottom-no">Update Name</button>
</div> </div>
</div> </div>
</form> </form>
@ -85,7 +85,7 @@
<input name="email" type="email" class="margin-bottom-no" autocomplete="off" placeholder="me@example.com" data-ls-bind="{{account.email}}" required> <input name="email" type="email" class="margin-bottom-no" autocomplete="off" placeholder="me@example.com" data-ls-bind="{{account.email}}" required>
</div> </div>
<div class="col span-4"> <div class="col span-4">
<div data-ui-modal class="modal box close width-small height-small" data-button-text="Update Email" data-button-class="fill reverse"> <div data-ui-modal class="modal box close width-small height-small" data-button-text="Update Email" data-button-class="fill">
<h3>Confirm Password</h3> <h3>Confirm Password</h3>
<hr /> <hr />
@ -103,7 +103,7 @@
<hr /> <hr />
<div data-ui-modal class="modal box close width-small" data-button-text="Update Password" data-button-class="reverse"> <div data-ui-modal class="modal box close width-small" data-button-text="Update Password" data-button-class="">
<h1>Update Password</h1> <h1>Update Password</h1>
<form name="update-password" <form name="update-password"

View file

@ -385,7 +385,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
data-success-param-trigger-events="teams.getMemberships"> data-success-param-trigger-events="teams.getMemberships">
<div class="box margin-bottom"> <div class="box margin-bottom">
<ul data-ls-loop="members" data-ls-as="member" class="list"> <ul data-ls-loop="members.memberships" data-ls-as="member" class="list">
<li class="clear"> <li class="clear">
<form class="pull-end" <form class="pull-end"
data-analytics-event="submit" data-analytics-event="submit"
@ -432,10 +432,10 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
data-scope="console" data-scope="console"
data-event="teams.deleteMembership.resend" data-event="teams.deleteMembership.resend"
data-success="alert,trigger" data-success="alert,trigger"
data-success-param-alert-text="Invitation Sent Successfully" data-success-param-alert-text="Invitation sent successfully"
data-success-param-trigger-events="teams.createMembership.resent" data-success-param-trigger-events="teams.createMembership.resent"
data-failure="alert" data-failure="alert"
data-failure-param-alert-text="Failed to Send inivitation" data-failure-param-alert-text="Failed to send inivitation"
data-failure-param-alert-classname="error"> data-failure-param-alert-classname="error">
<input name="teamId" type="hidden" data-ls-bind="{{member.teamId}}"> <input name="teamId" type="hidden" data-ls-bind="{{member.teamId}}">
@ -470,10 +470,10 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
data-event="submit" data-event="submit"
data-loading="Sending invitation, please wait..." data-loading="Sending invitation, please wait..."
data-success="alert,trigger,reset" data-success="alert,trigger,reset"
data-success-param-alert-text="Invitation Sent Successfully" data-success-param-alert-text="Invitation sent successfully"
data-success-param-trigger-events="teams.createMembership" data-success-param-trigger-events="teams.createMembership"
data-failure="alert" data-failure="alert"
data-failure-param-alert-text="Failed to Send Invite" data-failure-param-alert-text="Failed to send invite"
data-failure-param-alert-classname="error"> data-failure-param-alert-classname="error">
<input name="teamId" id="team-teamId" type="hidden" data-ls-bind="{{console-project.teamId}}"> <input name="teamId" id="team-teamId" type="hidden" data-ls-bind="{{console-project.teamId}}">

View file

@ -107,7 +107,7 @@ $providers = $this->getParam('providers', []);
<img src="" data-ls-attrs="src={{user|gravatar}}" data-size="45" alt="User Avatar" class="avatar pull-start" loading="lazy" width="30" height="30" /> <img src="" data-ls-attrs="src={{user|gravatar}}" data-size="45" alt="User Avatar" class="avatar pull-start" loading="lazy" width="30" height="30" />
</td> </td>
<td data-title="Name: "> <td data-title="Name: ">
<a data-ls-attrs="href=/console/users/view?id={{user.$id}}&project={{router.params.project}}"> <a data-ls-attrs="href=/console/users/user?id={{user.$id}}&project={{router.params.project}}">
<span data-ls-bind="{{user.name}}"></span> <span data-ls-bind="{{user.name}}"></span>
<span data-ls-if="{{user.name}} === ''">-----</span> <span data-ls-if="{{user.name}} === ''">-----</span>
</a> </a>
@ -253,36 +253,7 @@ $providers = $this->getParam('providers', []);
<img src="" data-ls-attrs="src={{team.name|gravatar}}" data-size="45" alt="Collection Avatar" class="avatar margin-end pull-start" loading="lazy" width="30" height="30" /> <img src="" data-ls-attrs="src={{team.name|gravatar}}" data-size="45" alt="Collection Avatar" class="avatar margin-end pull-start" loading="lazy" width="30" height="30" />
</td> </td>
<td data-title="Name: "> <td data-title="Name: ">
<div data-ui-modal class="box modal close" data-button-text="{{team.name}}" data-button-class="link"> <a data-ls-attrs="href=/console/users/teams/team?id={{team.$id}}&project={{router.params.project}}" data-ls-bind="{{team.name}}"></a>
<h1>Update Team</h1>
<form
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Update Team"
data-service="teams.update"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger"
data-success-param-alert-text="Updated team successfully"
data-success-param-trigger-events="teams.update"
data-failure="alert"
data-failure-param-alert-text="Failed to update team"
data-failure-param-alert-classname="error">
<label for="name">ID</label>
<div class="input-copy">
<input data-ls-attrs="id=team-id-{{team.$id}}" name="teamId" data-forms-copy type="text" disabled data-ls-bind="{{team.$id}}" />
</div>
<label for="name">Name</label>
<input data-ls-attrs="id=team-name-{{team.$id}}" name="name" type="text" autocomplete="off" data-ls-bind="{{team.name}}">
<hr />
<button>Update</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</form>
</div>
</td> </td>
<td data-title="Members: "><span data-ls-bind="{{team.sum}} members"></span></td> <td data-title="Members: "><span data-ls-bind="{{team.sum}} members"></span></td>
<td data-title="Date Created: "><small data-ls-bind="{{team.dateCreated|date-text}}"></small></td> <td data-title="Date Created: "><small data-ls-bind="{{team.dateCreated|date-text}}"></small></td>

View file

@ -0,0 +1,230 @@
<div
data-service="teams.get"
data-name="team"
data-event="load,teams.update,teams.deleteMembership,teams.createMembership"
data-param-team-id="{{router.params.id}}"
data-success="trigger"
data-success-param-trigger-events="teams.get">
<div class="cover">
<h1 class="zone xl margin-bottom-large">
<a data-ls-attrs="href=/console/users/teams?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Teams</a>
<br />
<span data-ls-bind="{{team.name}}">&nbsp;</span>
<span data-ls-if="{{team.name}} === ''">Unknown</span>
</h1>
</div>
<div data-ui-modal class="modal width-large box close" data-button-hide="on" data-open-event="open-json">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h2>JSON View</h2>
<div class="margin-bottom">
<input type="hidden" data-ls-bind="{{team}}" data-forms-code />
</div>
<button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
<div class="zone xl">
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
<li data-state="/console/users/teams/team?id={{router.params.id}}&project={{router.params.project}}">
<h2>General</h2>
<div class="row responsive margin-top-negative">
<div class="col span-8 margin-bottom-large">
<label>&nbsp;</label>
<div class="box margin-bottom-large">
<form
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Update Team"
data-service="teams.update"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger"
data-success-param-alert-text="Updated team successfully"
data-success-param-trigger-events="teams.update"
data-failure="alert"
data-failure-param-alert-text="Failed to update team"
data-failure-param-alert-classname="error">
<input data-ls-attrs="id=team-id-{{team.$id}}" name="teamId" type="hidden" disabled data-ls-bind="{{team.$id}}" />
<label for="name">Name</label>
<input data-ls-attrs="id=team-name-{{team.$id}}" name="name" type="text" autocomplete="off" data-ls-bind="{{team.name}}">
<hr />
<button>Update</button>
</form>
</div>
<h3 class="margin-bottom">Members</h3>
<div
data-service="teams.getMemberships"
data-event="load,teams.create,teams.update,teams.delete,teams.deleteMembership,teams.createMembership"
data-param-team-id="{{router.params.id}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-offset="{{router.params.offset}}"
data-param-order-type="DESC"
data-scope="sdk"
data-name="project-members">
<div data-ls-if="0 == {{project-members.sum}}" class="box margin-bottom">
<h3 class="margin-bottom-small text-bold">No Memberships Found</h3>
<p class="margin-bottom-no">Add your first team member to get started</p>
</div>
<div data-ls-if="0 != {{project-members.sum}}">
<div class="margin-bottom-small margin-end-small text-align-end text-size-small margin-top-negative"><span data-ls-bind="{{project-members.sum}}"></span> memberships found</div>
<div class="box margin-bottom">
<ul data-ls-loop="project-members.memberships" data-ls-as="member" class="list">
<li class="clear">
<form class="pull-end"
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Delete Team Membership"
data-service="teams.deleteMembership"
data-event="submit"
data-success="alert,trigger"
data-success-param-alert-text="Member Removed Successfully"
data-success-param-trigger-events="teams.deleteMembership"
data-failure="alert"
data-failure-param-alert-text="Failed to Remove Member"
data-failure-param-alert-classname="error">
<input name="teamId" data-ls-attrs="id={{member.$id}}" type="hidden" data-ls-bind="{{router.params.id}}">
<input name="inviteId" data-ls-attrs="id=leave-inviteId-{{member.$id}}" type="hidden" data-ls-bind="{{member.$id}}">
<button class="danger">Remove</button>
</form>
<img src="" data-ls-attrs="src={{member|gravatar}}" data-size="200" alt="User Avatar" class="avatar pull-start margin-end" loading="lazy" width="60" height="60" />
<div class="margin-bottom-tiny">
<a data-ls-attrs="href=/console/users/user?id={{member.userId}}&project={{router.params.project}}"><span data-ls-bind="{{member.name}}"></span></a> &nbsp;&nbsp;
<span data-ls-if="1 == {{member.roles.length}}" class="text-fade tooltip" data-ls-bind="({{member.roles.length}} role)" data-ls-attrs="data-tooltip={{member.roles|arraySentence}}"></span>
<span data-ls-if="2 <= {{member.roles.length}}" class="text-fade tooltip" data-ls-bind="({{member.roles.length}} roles)" data-ls-attrs="data-tooltip={{member.roles|arraySentence}}"></span>
</div>
<small class="text-size-small text-fade" data-ls-bind="{{member.email}}"></small> &nbsp;&nbsp;<span data-ls-if="false === {{member.confirm}}" class="text-danger text-size-small">Pending Approval</span>
</li>
</ul>
</div>
</div>
<div data-ui-modal class="box modal close" data-button-text="Add Member" data-button-class="pull-start">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1>Add Member</h1>
<form name="teams.createTeamMembership"
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Team Membership"
data-service="teams.createMembership"
data-event="submit"
data-loading="Sending invitation, please wait..."
data-success="alert,trigger,reset"
data-success-param-alert-text="Invitation sent successfully"
data-success-param-trigger-events="teams.createMembership"
data-failure="alert"
data-failure-param-alert-text="Failed to send invite"
data-failure-param-alert-classname="error">
<input name="teamId" id="team-teamId" type="hidden" data-ls-bind="{{team.$id}}">
<input name="url" type="hidden" data-ls-bind="{{env.PROTOCOL}}://{{env.DOMAIN}}" />
<label for="email">Email</label>
<input name="email" id="email" type="email" autocomplete="email" required>
<label for="team-name">Name <small>(optional)</small></label>
<input name="name" id="team-name" type="text" autocomplete="name">
<label for="roles">Roles</label>
<input type="hidden" id="team-roles" name="roles" data-forms-tags data-cast-to="json" data-ls-bind="<?php echo $this->escape(json_encode(['owner'])); ?>" placeholder="Add any role you like" />
<hr />
<div class="clear">
<button>Add Member</button>
&nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
</form>
</div>
<div class="clear text-align-center paging pull-end">
<form
data-service="teams.getMemberships"
data-event="submit"
data-param-team-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-type="DESC"
data-scope="sdk"
data-name="project-members"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{project-members.sum}}" class="margin-end round small" aria-label="Back"><i class="icon-left-open"></i></button>
</form>
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{project-members.sum|pageTotal}}"></span>
<form
data-service="teams.getMemberships"
data-event="submit"
data-param-team-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-type="DESC"
data-scope="sdk"
data-name="project-members"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-members.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
</div>
</div>
<div class="col span-4 sticky-top">
<label>Team ID</label>
<div class="input-copy margin-bottom">
<input id="uid" type="text" autocomplete="off" placeholder="" data-ls-bind="{{team.$id}}" disabled data-forms-copy>
</div>
<ul class="margin-bottom-large text-fade text-size-small">
<li class="margin-bottom-small"><i class="icon-angle-circled-right margin-start-tiny margin-end-tiny"></i> <button data-ls-ui-trigger="open-json" class="link text-size-small">View as JSON</button></li>
<li class="margin-bottom-small"><i class="icon-angle-circled-right margin-start-tiny margin-end-tiny"></i> Created: <span data-ls-bind="{{team.dateCreated|date-text}}"></span></li>
</ul>
<form name="teams.delete" class="margin-bottom"
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Delete Team"
data-service="teams.delete"
data-event="submit"
data-confirm="Are you sure you want to delete this team?"
data-param-team-id="{{router.params.id}}"
data-success="alert,trigger,redirect"
data-success-param-alert-text="Team deleted successfully"
data-success-param-trigger-events="users.update"
data-success-param-redirect-url="/console/users/teams?project={{router.params.project}}"
data-failure="alert"
data-failure-param-alert-text="Failed to delete team"
data-failure-param-alert-classname="error">
<button type="submit" class="danger fill">Delete Team</button>
</form>
</div>
</div>
</li>
</ul>
</div>
</div>

View file

@ -30,7 +30,7 @@
<div class="zone xl"> <div class="zone xl">
<ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}"> <ul class="phases clear" data-ui-phases data-selected="{{router.params.tab}}">
<li data-state="/console/users/view?id={{router.params.id}}&project={{router.params.project}}"> <li data-state="/console/users/user?id={{router.params.id}}&project={{router.params.project}}">
<h2>General</h2> <h2>General</h2>
<div data-ls-if="{{user.status}} === <?php echo \Appwrite\Auth\Auth::USER_STATUS_BLOCKED; ?>" style="display: none" class="box padding-small danger margin-bottom-xxl text-align-center"> <div data-ls-if="{{user.status}} === <?php echo \Appwrite\Auth\Auth::USER_STATUS_BLOCKED; ?>" style="display: none" class="box padding-small danger margin-bottom-xxl text-align-center">
@ -113,10 +113,10 @@
data-event="submit" data-event="submit"
data-param-user-id="{{router.params.id}}" data-param-user-id="{{router.params.id}}"
data-success="alert,trigger" data-success="alert,trigger"
data-success-param-alert-text="Blocked User Successfully" data-success-param-alert-text="Blocked user successfully"
data-success-param-trigger-events="users.update" data-success-param-trigger-events="users.update"
data-failure="alert" data-failure="alert"
data-failure-param-alert-text="Failed to Block User" data-failure-param-alert-text="Failed to block user"
data-failure-param-alert-classname="error"> data-failure-param-alert-classname="error">
<button name="status" type="submit" class="danger fill" value="<?php echo \Appwrite\Auth\Auth::USER_STATUS_BLOCKED; ?>">Block Account</button> <button name="status" type="submit" class="danger fill" value="<?php echo \Appwrite\Auth\Auth::USER_STATUS_BLOCKED; ?>">Block Account</button>
@ -132,10 +132,10 @@
data-event="submit" data-event="submit"
data-param-user-id="{{router.params.id}}" data-param-user-id="{{router.params.id}}"
data-success="alert,trigger" data-success="alert,trigger"
data-success-param-alert-text="Activated User Successfully" data-success-param-alert-text="Activated user successfully"
data-success-param-trigger-events="users.update" data-success-param-trigger-events="users.update"
data-failure="alert" data-failure="alert"
data-failure-param-alert-text="Failed to Activate User" data-failure-param-alert-text="Failed to activate user"
data-failure-param-alert-classname="error"> data-failure-param-alert-classname="error">
<button name="status" type="submit" class="fill" value="<?php echo \Appwrite\Auth\Auth::USER_STATUS_ACTIVATED; ?>">Activate Account</button> <button name="status" type="submit" class="fill" value="<?php echo \Appwrite\Auth\Auth::USER_STATUS_ACTIVATED; ?>">Activate Account</button>
@ -144,7 +144,7 @@
</div> </div>
</div> </div>
</li> </li>
<li data-state="/console/users/view/devices?id={{router.params.id}}&project={{router.params.project}}"> <li data-state="/console/users/user/devices?id={{router.params.id}}&project={{router.params.project}}">
<h2>Devices</h2> <h2>Devices</h2>
<div <div
@ -210,7 +210,7 @@
</div> </div>
</li> </li>
<li data-state="/console/users/view/audit?id={{router.params.id}}&project={{router.params.project}}"> <li data-state="/console/users/user/audit?id={{router.params.id}}&project={{router.params.project}}">
<h2>Activity</h2> <h2>Activity</h2>
<div <div

View file

@ -12,7 +12,7 @@
data-param-secret="{{router.params.secret}}" data-param-secret="{{router.params.secret}}"
data-success="redirect,alert,trigger" data-success="redirect,alert,trigger"
data-success-param-redirect-url="/console?project={{router.params.project}}" data-success-param-redirect-url="/console?project={{router.params.project}}"
data-success-param-alert-text="Joined Team Successfully" data-success-param-alert-text="Joined team successfully"
data-success-param-trigger-events="teams.updateMembershipStatus" data-success-param-trigger-events="teams.updateMembershipStatus"
data-failure="redirect,alert" data-failure="redirect,alert"
data-success-param-redirect-url="/console" data-success-param-redirect-url="/console"

View file

@ -18,8 +18,7 @@ request.setRequestHeader(key,headers[key]);}}
request.onload=function(){if(4===request.readyState&&399>=request.status){let data=request.response;let contentType=this.getResponseHeader('content-type')||'';contentType=contentType.substring(0,contentType.indexOf(';'));switch(contentType){case'application/json':data=JSON.parse(data);break;} request.onload=function(){if(4===request.readyState&&399>=request.status){let data=request.response;let contentType=this.getResponseHeader('content-type')||'';contentType=contentType.substring(0,contentType.indexOf(';'));switch(contentType){case'application/json':data=JSON.parse(data);break;}
let cookieFallback=this.getResponseHeader('X-Fallback-Cookies')||'';if(window.localStorage&&cookieFallback){window.console.warn('Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.');window.localStorage.setItem('cookieFallback',cookieFallback);} let cookieFallback=this.getResponseHeader('X-Fallback-Cookies')||'';if(window.localStorage&&cookieFallback){window.console.warn('Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.');window.localStorage.setItem('cookieFallback',cookieFallback);}
resolve(data);}else{reject(new Error(request.statusText));}};if(progress){request.addEventListener('progress',progress);request.upload.addEventListener('progress',progress,false);} resolve(data);}else{reject(new Error(request.statusText));}};if(progress){request.addEventListener('progress',progress);request.upload.addEventListener('progress',progress,false);}
request.onerror=function(){reject(new Error("Network Error"));};request.send(params);})};return{'get':function(path,headers={},params={}){return call('GET',path+((Object.keys(params).length>0)?'?'+buildQuery(params):''),headers,{});},'post':function(path,headers={},params={},progress=null){return call('POST',path,headers,params,progress);},'put':function(path,headers={},params={},progress=null){return call('PUT',path,headers,params,progress);},'patch':function(path,headers={},params={},progress=null){return call('PATCH',path,headers,params,progress);},'delete':function(path,headers={},params={},progress=null){return call('DELETE',path,headers,params,progress);},'addGlobalParam':addGlobalParam,'addGlobalHeader':addGlobalHeader}}(window.document);let iframe=function(method,url,params){let form=document.createElement('form');form.setAttribute('method',method);form.setAttribute('action',config.endpoint+url);for(let key in params){if(params.hasOwnProperty(key)){let hiddenField=document.createElement("input");hiddenField.setAttribute("type","hidden");hiddenField.setAttribute("name",key);hiddenField.setAttribute("value",params[key]);form.appendChild(hiddenField);}} request.onerror=function(){reject(new Error("Network Error"));};request.send(params);})};return{'get':function(path,headers={},params={}){return call('GET',path+((Object.keys(params).length>0)?'?'+buildQuery(params):''),headers,{});},'post':function(path,headers={},params={},progress=null){return call('POST',path,headers,params,progress);},'put':function(path,headers={},params={},progress=null){return call('PUT',path,headers,params,progress);},'patch':function(path,headers={},params={},progress=null){return call('PATCH',path,headers,params,progress);},'delete':function(path,headers={},params={},progress=null){return call('DELETE',path,headers,params,progress);},'addGlobalParam':addGlobalParam,'addGlobalHeader':addGlobalHeader}}(window.document);let account={get:function(){let path='/account';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(email,password,name=''){if(email===undefined){throw new Error('Missing required parameter: "email"');}
document.body.appendChild(form);return form.submit();};let account={get:function(){let path='/account';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(email,password,name=''){if(email===undefined){throw new Error('Missing required parameter: "email"');}
if(password===undefined){throw new Error('Missing required parameter: "password"');} if(password===undefined){throw new Error('Missing required parameter: "password"');}
let path='/account';let payload={};if(email){payload['email']=email;} let path='/account';let payload={};if(email){payload['email']=email;}
if(password){payload['password']=password;} if(password){payload['password']=password;}
@ -52,12 +51,10 @@ return http.put(path,{'content-type':'application/json',},payload);},getSessions
if(password===undefined){throw new Error('Missing required parameter: "password"');} if(password===undefined){throw new Error('Missing required parameter: "password"');}
let path='/account/sessions';let payload={};if(email){payload['email']=email;} let path='/account/sessions';let payload={};if(email){payload['email']=email;}
if(password){payload['password']=password;} if(password){payload['password']=password;}
return http.post(path,{'content-type':'application/json',},payload);},deleteSessions:function(){let path='/account/sessions';let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createOAuth2Session:function(provider,success,failure){if(provider===undefined){throw new Error('Missing required parameter: "provider"');} return http.post(path,{'content-type':'application/json',},payload);},deleteSessions:function(){let path='/account/sessions';let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createOAuth2Session:function(provider,success='https://appwrite.io/auth/oauth2/success',failure='https://appwrite.io/auth/oauth2/failure'){if(provider===undefined){throw new Error('Missing required parameter: "provider"');}
if(success===undefined){throw new Error('Missing required parameter: "success"');}
if(failure===undefined){throw new Error('Missing required parameter: "failure"');}
let path='/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}','g'),provider);let payload={};if(success){payload['success']=success;} let path='/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}','g'),provider);let payload={};if(success){payload['success']=success;}
if(failure){payload['failure']=failure;} if(failure){payload['failure']=failure;}
payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},deleteSession:function(sessionId){if(sessionId===undefined){throw new Error('Missing required parameter: "sessionId"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');window.location=config.endpoint+path+((query)?'?'+query:'');},deleteSession:function(sessionId){if(sessionId===undefined){throw new Error('Missing required parameter: "sessionId"');}
let path='/account/sessions/{sessionId}'.replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createVerification:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');} let path='/account/sessions/{sessionId}'.replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createVerification:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/account/verification';let payload={};if(url){payload['url']=url;} let path='/account/verification';let payload={};if(url){payload['url']=url;}
return http.post(path,{'content-type':'application/json',},payload);},updateVerification:function(userId,secret){if(userId===undefined){throw new Error('Missing required parameter: "userId"');} return http.post(path,{'content-type':'application/json',},payload);},updateVerification:function(userId,secret){if(userId===undefined){throw new Error('Missing required parameter: "userId"');}
@ -68,26 +65,26 @@ return http.put(path,{'content-type':'application/json',},payload);}};let avatar
let path='/avatars/browsers/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/browsers/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getCreditCard:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getCreditCard:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');}
let path='/avatars/credit-cards/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/credit-cards/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getFavicon:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getFavicon:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/avatars/favicon';let payload={};if(url){payload['url']=url;} let path='/avatars/favicon';let payload={};if(url){payload['url']=url;}
return http.get(path,{'content-type':'application/json',},payload);},getFlag:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getFlag:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');}
let path='/avatars/flags/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/flags/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getImage:function(url,width=400,height=400){if(url===undefined){throw new Error('Missing required parameter: "url"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getImage:function(url,width=400,height=400){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/avatars/image';let payload={};if(url){payload['url']=url;} let path='/avatars/image';let payload={};if(url){payload['url']=url;}
if(width){payload['width']=width;} if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
return http.get(path,{'content-type':'application/json',},payload);},getQR:function(text,size=400,margin=1,download=0){if(text===undefined){throw new Error('Missing required parameter: "text"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getQR:function(text,size=400,margin=1,download=0){if(text===undefined){throw new Error('Missing required parameter: "text"');}
let path='/avatars/qr';let payload={};if(text){payload['text']=text;} let path='/avatars/qr';let payload={};if(text){payload['text']=text;}
if(size){payload['size']=size;} if(size){payload['size']=size;}
if(margin){payload['margin']=margin;} if(margin){payload['margin']=margin;}
if(download){payload['download']=download;} if(download){payload['download']=download;}
return http.get(path,{'content-type':'application/json',},payload);}};let database={listCollections:function(search='',limit=25,offset=0,orderType='ASC'){let path='/database/collections';let payload={};if(search){payload['search']=search;} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');}};let database={listCollections:function(search='',limit=25,offset=0,orderType='ASC'){let path='/database/collections';let payload={};if(search){payload['search']=search;}
if(limit){payload['limit']=limit;} if(limit){payload['limit']=limit;}
if(offset){payload['offset']=offset;} if(offset){payload['offset']=offset;}
if(orderType){payload['orderType']=orderType;} if(orderType){payload['orderType']=orderType;}
@ -141,7 +138,8 @@ if(read){payload['read']=read;}
if(write){payload['write']=write;} if(write){payload['write']=write;}
return http.patch(path,{'content-type':'application/json',},payload);},deleteDocument:function(collectionId,documentId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');} return http.patch(path,{'content-type':'application/json',},payload);},deleteDocument:function(collectionId,documentId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');}
if(documentId===undefined){throw new Error('Missing required parameter: "documentId"');} if(documentId===undefined){throw new Error('Missing required parameter: "documentId"');}
let path='/database/collections/{collectionId}/documents/{documentId}'.replace(new RegExp('{collectionId}','g'),collectionId).replace(new RegExp('{documentId}','g'),documentId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);}};let locale={get:function(){let path='/locale';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getContinents:function(){let path='/locale/continents';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountries:function(){let path='/locale/countries';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesEU:function(){let path='/locale/countries/eu';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesPhones:function(){let path='/locale/countries/phones';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCurrencies:function(){let path='/locale/currencies';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let projects={list:function(){let path='/projects';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(name,teamId,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId=''){if(name===undefined){throw new Error('Missing required parameter: "name"');} let path='/database/collections/{collectionId}/documents/{documentId}'.replace(new RegExp('{collectionId}','g'),collectionId).replace(new RegExp('{documentId}','g'),documentId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getCollectionLogs:function(collectionId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/logs'.replace(new RegExp('{collectionId}','g'),collectionId);let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let health={get:function(){let path='/health';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getAntiVirus:function(){let path='/health/anti-virus';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCache:function(){let path='/health/cache';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getDB:function(){let path='/health/db';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueCertificates:function(){let path='/health/queue/certificates';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueFunctions:function(){let path='/health/queue/functions';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueLogs:function(){let path='/health/queue/logs';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueTasks:function(){let path='/health/queue/tasks';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueUsage:function(){let path='/health/queue/usage';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueWebhooks:function(){let path='/health/queue/webhooks';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getStorageLocal:function(){let path='/health/storage/local';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getTime:function(){let path='/health/time';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let locale={get:function(){let path='/locale';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getContinents:function(){let path='/locale/continents';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountries:function(){let path='/locale/countries';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesEU:function(){let path='/locale/countries/eu';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesPhones:function(){let path='/locale/countries/phones';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCurrencies:function(){let path='/locale/currencies';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let projects={list:function(){let path='/projects';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(name,teamId,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId=''){if(name===undefined){throw new Error('Missing required parameter: "name"');}
if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/projects';let payload={};if(name){payload['name']=name;} let path='/projects';let payload={};if(name){payload['name']=name;}
if(teamId){payload['teamId']=teamId;} if(teamId){payload['teamId']=teamId;}
@ -259,7 +257,7 @@ if(httpUser){payload['httpUser']=httpUser;}
if(httpPass){payload['httpPass']=httpPass;} if(httpPass){payload['httpPass']=httpPass;}
return http.put(path,{'content-type':'application/json',},payload);},deleteTask:function(projectId,taskId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} return http.put(path,{'content-type':'application/json',},payload);},deleteTask:function(projectId,taskId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
if(taskId===undefined){throw new Error('Missing required parameter: "taskId"');} if(taskId===undefined){throw new Error('Missing required parameter: "taskId"');}
let path='/projects/{projectId}/tasks/{taskId}'.replace(new RegExp('{projectId}','g'),projectId).replace(new RegExp('{taskId}','g'),taskId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getUsage:function(projectId,range='monthly'){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} let path='/projects/{projectId}/tasks/{taskId}'.replace(new RegExp('{projectId}','g'),projectId).replace(new RegExp('{taskId}','g'),taskId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getUsage:function(projectId,range='last30'){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
let path='/projects/{projectId}/usage'.replace(new RegExp('{projectId}','g'),projectId);let payload={};if(range){payload['range']=range;} let path='/projects/{projectId}/usage'.replace(new RegExp('{projectId}','g'),projectId);let payload={};if(range){payload['range']=range;}
return http.get(path,{'content-type':'application/json',},payload);},listWebhooks:function(projectId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} return http.get(path,{'content-type':'application/json',},payload);},listWebhooks:function(projectId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
let path='/projects/{projectId}/webhooks'.replace(new RegExp('{projectId}','g'),projectId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createWebhook:function(projectId,name,events,url,security,httpUser='',httpPass=''){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} let path='/projects/{projectId}/webhooks'.replace(new RegExp('{projectId}','g'),projectId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createWebhook:function(projectId,name,events,url,security,httpUser='',httpPass=''){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
@ -327,8 +325,12 @@ let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payloa
if(name===undefined){throw new Error('Missing required parameter: "name"');} if(name===undefined){throw new Error('Missing required parameter: "name"');}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload['name']=name;} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload['name']=name;}
return http.put(path,{'content-type':'application/json',},payload);},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} return http.put(path,{'content-type':'application/json',},payload);},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getMemberships:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getMemberships:function(teamId,search='',limit=25,offset=0,orderType='ASC'){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(search){payload['search']=search;}
if(limit){payload['limit']=limit;}
if(offset){payload['offset']=offset;}
if(orderType){payload['orderType']=orderType;}
return http.get(path,{'content-type':'application/json',},payload);},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
if(email===undefined){throw new Error('Missing required parameter: "email"');} if(email===undefined){throw new Error('Missing required parameter: "email"');}
if(roles===undefined){throw new Error('Missing required parameter: "roles"');} if(roles===undefined){throw new Error('Missing required parameter: "roles"');}
if(url===undefined){throw new Error('Missing required parameter: "url"');} if(url===undefined){throw new Error('Missing required parameter: "url"');}
@ -366,7 +368,7 @@ if(sessionId===undefined){throw new Error('Missing required parameter: "sessionI
let path='/users/{userId}/sessions/{sessionId}'.replace(new RegExp('{userId}','g'),userId).replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},updateStatus:function(userId,status){if(userId===undefined){throw new Error('Missing required parameter: "userId"');} let path='/users/{userId}/sessions/{sessionId}'.replace(new RegExp('{userId}','g'),userId).replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},updateStatus:function(userId,status){if(userId===undefined){throw new Error('Missing required parameter: "userId"');}
if(status===undefined){throw new Error('Missing required parameter: "status"');} if(status===undefined){throw new Error('Missing required parameter: "status"');}
let path='/users/{userId}/status'.replace(new RegExp('{userId}','g'),userId);let payload={};if(status){payload['status']=status;} let path='/users/{userId}/status'.replace(new RegExp('{userId}','g'),userId);let payload={};if(status){payload['status']=status;}
return http.patch(path,{'content-type':'application/json',},payload);}};return{setEndpoint:setEndpoint,setProject:setProject,setKey:setKey,setLocale:setLocale,setMode:setMode,account:account,avatars:avatars,database:database,locale:locale,projects:projects,storage:storage,teams:teams,users:users};};if(typeof module!=="undefined"){module.exports=window.Appwrite;}})((typeof window!=="undefined")?window:{});(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart=f()}})(function(){var define,module,exports;return(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){var colorNames=require(5);module.exports={getRgba:getRgba,getHsla:getHsla,getRgb:getRgb,getHsl:getHsl,getHwb:getHwb,getAlpha:getAlpha,hexString:hexString,rgbString:rgbString,rgbaString:rgbaString,percentString:percentString,percentaString:percentaString,hslString:hslString,hslaString:hslaString,hwbString:hwbString,keyword:keyword} return http.patch(path,{'content-type':'application/json',},payload);}};return{setEndpoint:setEndpoint,setProject:setProject,setKey:setKey,setLocale:setLocale,setMode:setMode,account:account,avatars:avatars,database:database,health:health,locale:locale,projects:projects,storage:storage,teams:teams,users:users};};if(typeof module!=="undefined"){module.exports=window.Appwrite;}})((typeof window!=="undefined")?window:{});(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart=f()}})(function(){var define,module,exports;return(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){var colorNames=require(5);module.exports={getRgba:getRgba,getHsla:getHsla,getRgb:getRgb,getHsl:getHsl,getHwb:getHwb,getAlpha:getAlpha,hexString:hexString,rgbString:rgbString,rgbaString:rgbaString,percentString:percentString,percentaString:percentaString,hslString:hslString,hslaString:hslaString,hwbString:hwbString,keyword:keyword}
function getRgba(string){if(!string){return;} function getRgba(string){if(!string){return;}
var abbr=/^#([a-fA-F0-9]{3})$/i,hex=/^#([a-fA-F0-9]{6})$/i,rgba=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,per=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,keyword=/(\w+)/;var rgb=[0,0,0],a=1,match=string.match(abbr);if(match){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match[i]+match[i],16);}} var abbr=/^#([a-fA-F0-9]{3})$/i,hex=/^#([a-fA-F0-9]{6})$/i,rgba=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,per=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,keyword=/(\w+)/;var rgb=[0,0,0],a=1,match=string.match(abbr);if(match){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match[i]+match[i],16);}}
else if(match=string.match(hex)){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match.slice(i*2,i*2+2),16);}} else if(match=string.match(hex)){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match.slice(i*2,i*2+2),16);}}
@ -2532,7 +2534,7 @@ return slf.renderToken(tokens,idx,opts);}
md.renderer.rules.strong_open=renderEm;md.renderer.rules.strong_close=renderEm;return md;},true);})(window);(function(window){"use strict";window.ls.container.set('rtl',function(){var rtlStock="^ا^ب^ت^ث^ج^ح^خ^د^ذ^ر^ز^س^ش^ص^ض^ط^ظ^ع^غ^ف^ق^ك^ل^م^ن^ه^و^ي^א^ב^ג^ד^ה^ו^ז^ח^ט^י^כ^ך^ל^מ^ם^נ^ן^ס^ע^פ^ף^צ^ץ^ק^ר^ש^ת^";var special=["\n"," "," ","״",'"',"_","'","!","@","#","$","^","&","%","*","(",")","+","=","-","[","]","\\","/","{","}","|",":","<",">","?",",",".","0","1","2","3","4","5","6","7","8","9"];var isRTL=function(value){for(var i=0;i<value.length;i++){if(/\s/g.test(value[i])){continue;} md.renderer.rules.strong_open=renderEm;md.renderer.rules.strong_close=renderEm;return md;},true);})(window);(function(window){"use strict";window.ls.container.set('rtl',function(){var rtlStock="^ا^ب^ت^ث^ج^ح^خ^د^ذ^ر^ز^س^ش^ص^ض^ط^ظ^ع^غ^ف^ق^ك^ل^م^ن^ه^و^ي^א^ב^ג^ד^ה^ו^ז^ח^ט^י^כ^ך^ל^מ^ם^נ^ן^ס^ע^פ^ף^צ^ץ^ק^ר^ש^ת^";var special=["\n"," "," ","״",'"',"_","'","!","@","#","$","^","&","%","*","(",")","+","=","-","[","]","\\","/","{","}","|",":","<",">","?",",",".","0","1","2","3","4","5","6","7","8","9"];var isRTL=function(value){for(var i=0;i<value.length;i++){if(/\s/g.test(value[i])){continue;}
if(-1===special.indexOf(value[i])){var firstChar=value[i];break;}} if(-1===special.indexOf(value[i])){var firstChar=value[i];break;}}
if(-1<rtlStock.indexOf("^"+firstChar+"^")){return true;} if(-1<rtlStock.indexOf("^"+firstChar+"^")){return true;}
return false;};return{isRTL:isRTL,};},true);})(window);(function(window){"use strict";window.ls.container.set('sdk',function(window,router){var sdk=new window.Appwrite();sdk.setEndpoint(APP_ENV.API).setProject(router.params.project||'').setLocale(APP_ENV.LOCALE).setMode('admin');return sdk;},false);})(window);(function(window){"use strict";window.ls.container.set('search',function(window){return{params:{},path:'',pointer:'',selected:'',};},true,true);})(window);(function(window){"use strict";window.ls.container.set('timezone',function(){return{convert:function(unixTime){var timezoneMinutes=new Date().getTimezoneOffset();timezoneMinutes=(timezoneMinutes===0)?0:-timezoneMinutes;return parseInt(unixTime)+(timezoneMinutes*60);}};},true);})(window);window.ls.router.add("/auth/signin",{template:"/auth/signin?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/signup",{template:"/auth/signup?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery",{template:"/auth/recovery?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery/reset",{template:"/auth/recovery/reset?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/confirm",{template:"/auth/confirm?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/join",{template:"/auth/join?version="+APP_ENV.VERSION,scope:"home"}).add("/console",{template:"/console?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account/:tab",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/home",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/home/:tab",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/platforms/:platform",{template:function(window){return window.location.pathname+"?version="+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/notifications",{template:"/console/notifications?version="+APP_ENV.VERSION,scope:"console"}).add("/console/settings",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/settings/:tab",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks/:tab",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys/:tab",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks/:tab",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database",{template:"/console/database?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database/collection",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/collection/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/storage",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/storage/:tab",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/view",{template:"/console/users/view?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/view/:tab",{template:"/console/users/view?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/:tab",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true});window.ls.filter.add("gravatar",function($value,element){if(!$value){return"";} return false;};return{isRTL:isRTL,};},true);})(window);(function(window){"use strict";window.ls.container.set('sdk',function(window,router){var sdk=new window.Appwrite();sdk.setEndpoint(APP_ENV.API).setProject(router.params.project||'').setLocale(APP_ENV.LOCALE).setMode('admin');return sdk;},false);})(window);(function(window){"use strict";window.ls.container.set('search',function(window){return{params:{},path:'',pointer:'',selected:'',};},true,true);})(window);(function(window){"use strict";window.ls.container.set('timezone',function(){return{convert:function(unixTime){var timezoneMinutes=new Date().getTimezoneOffset();timezoneMinutes=(timezoneMinutes===0)?0:-timezoneMinutes;return parseInt(unixTime)+(timezoneMinutes*60);}};},true);})(window);window.ls.router.add("/auth/signin",{template:"/auth/signin?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/signup",{template:"/auth/signup?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery",{template:"/auth/recovery?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery/reset",{template:"/auth/recovery/reset?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/confirm",{template:"/auth/confirm?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/join",{template:"/auth/join?version="+APP_ENV.VERSION,scope:"home"}).add("/console",{template:"/console?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account/:tab",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/home",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/home/:tab",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/platforms/:platform",{template:function(window){return window.location.pathname+"?version="+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/notifications",{template:"/console/notifications?version="+APP_ENV.VERSION,scope:"console"}).add("/console/settings",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/settings/:tab",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks/:tab",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys/:tab",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks/:tab",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database",{template:"/console/database?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database/collection",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/collection/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/storage",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/storage/:tab",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/user",{template:"/console/users/user?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/user/:tab",{template:"/console/users/user?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/teams/team",{template:"/console/users/teams/team?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/teams/team/:tab",{template:"/console/users/teams/team?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/:tab",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true});window.ls.filter.add("gravatar",function($value,element){if(!$value){return"";}
let MD5=function(s){function L(k,d){return(k<<d)|(k>>>(32-d));} let MD5=function(s){function L(k,d){return(k<<d)|(k>>>(32-d));}
function K(G,k){let I,d,F,H,x;F=G&2147483648;H=k&2147483648;I=G&1073741824;d=k&1073741824;x=(G&1073741823)+(k&1073741823);if(I&d){return x^2147483648^F^H;} function K(G,k){let I,d,F,H,x;F=G&2147483648;H=k&2147483648;I=G&1073741824;d=k&1073741824;x=(G&1073741823)+(k&1073741823);if(I&d){return x^2147483648^F^H;}
if(I|d){if(x&1073741824){return x^3221225472^F^H;}else{return x^1073741824^F^H;}}else{return x^F^H;}} if(I|d){if(x&1073741824){return x^3221225472^F^H;}else{return x^1073741824^F^H;}}else{return x^F^H;}}
@ -2567,7 +2569,8 @@ $value=abbreviate($value,0,false,false);return $value==="0"?"N/A":$value;}).add(
return result.length;}).add("documentAction",function(container){let collection=container.get('project-collection');let document=container.get('project-document');if(collection&&document&&!document.$id){return'database.createDocument';} return result.length;}).add("documentAction",function(container){let collection=container.get('project-collection');let document=container.get('project-document');if(collection&&document&&!document.$id){return'database.createDocument';}
return'database.updateDocument';}).add("documentSuccess",function(container){let document=container.get('project-document');if(document&&!document.$id){return',redirect';} return'database.updateDocument';}).add("documentSuccess",function(container){let document=container.get('project-document');if(document&&!document.$id){return',redirect';}
return'';}).add("firstElement",function($value){if($value&&$value[0]){return $value[0];} return'';}).add("firstElement",function($value){if($value&&$value[0]){return $value[0];}
return $value;}).add("platformsLimit",function($value){return $value;}).add("limit",function($value){let postfix=($value.length>=50)?'...':'';return $value.substring(0,50)+postfix;;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);} return $value;}).add("platformsLimit",function($value){return $value;}).add("limit",function($value){let postfix=($value.length>=50)?'...':'';return $value.substring(0,50)+postfix;;}).add("arraySentence",function($value){if(!Array.isArray($value)){return'';}
return $value.join(", ").replace(/,\s([^,]+)$/,' and $1');});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";} let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);} return annotate(number,maxPlaces,forcePlaces,abbr);}
function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;} function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;}

View file

@ -18,8 +18,7 @@ request.setRequestHeader(key,headers[key]);}}
request.onload=function(){if(4===request.readyState&&399>=request.status){let data=request.response;let contentType=this.getResponseHeader('content-type')||'';contentType=contentType.substring(0,contentType.indexOf(';'));switch(contentType){case'application/json':data=JSON.parse(data);break;} request.onload=function(){if(4===request.readyState&&399>=request.status){let data=request.response;let contentType=this.getResponseHeader('content-type')||'';contentType=contentType.substring(0,contentType.indexOf(';'));switch(contentType){case'application/json':data=JSON.parse(data);break;}
let cookieFallback=this.getResponseHeader('X-Fallback-Cookies')||'';if(window.localStorage&&cookieFallback){window.console.warn('Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.');window.localStorage.setItem('cookieFallback',cookieFallback);} let cookieFallback=this.getResponseHeader('X-Fallback-Cookies')||'';if(window.localStorage&&cookieFallback){window.console.warn('Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.');window.localStorage.setItem('cookieFallback',cookieFallback);}
resolve(data);}else{reject(new Error(request.statusText));}};if(progress){request.addEventListener('progress',progress);request.upload.addEventListener('progress',progress,false);} resolve(data);}else{reject(new Error(request.statusText));}};if(progress){request.addEventListener('progress',progress);request.upload.addEventListener('progress',progress,false);}
request.onerror=function(){reject(new Error("Network Error"));};request.send(params);})};return{'get':function(path,headers={},params={}){return call('GET',path+((Object.keys(params).length>0)?'?'+buildQuery(params):''),headers,{});},'post':function(path,headers={},params={},progress=null){return call('POST',path,headers,params,progress);},'put':function(path,headers={},params={},progress=null){return call('PUT',path,headers,params,progress);},'patch':function(path,headers={},params={},progress=null){return call('PATCH',path,headers,params,progress);},'delete':function(path,headers={},params={},progress=null){return call('DELETE',path,headers,params,progress);},'addGlobalParam':addGlobalParam,'addGlobalHeader':addGlobalHeader}}(window.document);let iframe=function(method,url,params){let form=document.createElement('form');form.setAttribute('method',method);form.setAttribute('action',config.endpoint+url);for(let key in params){if(params.hasOwnProperty(key)){let hiddenField=document.createElement("input");hiddenField.setAttribute("type","hidden");hiddenField.setAttribute("name",key);hiddenField.setAttribute("value",params[key]);form.appendChild(hiddenField);}} request.onerror=function(){reject(new Error("Network Error"));};request.send(params);})};return{'get':function(path,headers={},params={}){return call('GET',path+((Object.keys(params).length>0)?'?'+buildQuery(params):''),headers,{});},'post':function(path,headers={},params={},progress=null){return call('POST',path,headers,params,progress);},'put':function(path,headers={},params={},progress=null){return call('PUT',path,headers,params,progress);},'patch':function(path,headers={},params={},progress=null){return call('PATCH',path,headers,params,progress);},'delete':function(path,headers={},params={},progress=null){return call('DELETE',path,headers,params,progress);},'addGlobalParam':addGlobalParam,'addGlobalHeader':addGlobalHeader}}(window.document);let account={get:function(){let path='/account';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(email,password,name=''){if(email===undefined){throw new Error('Missing required parameter: "email"');}
document.body.appendChild(form);return form.submit();};let account={get:function(){let path='/account';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(email,password,name=''){if(email===undefined){throw new Error('Missing required parameter: "email"');}
if(password===undefined){throw new Error('Missing required parameter: "password"');} if(password===undefined){throw new Error('Missing required parameter: "password"');}
let path='/account';let payload={};if(email){payload['email']=email;} let path='/account';let payload={};if(email){payload['email']=email;}
if(password){payload['password']=password;} if(password){payload['password']=password;}
@ -52,12 +51,10 @@ return http.put(path,{'content-type':'application/json',},payload);},getSessions
if(password===undefined){throw new Error('Missing required parameter: "password"');} if(password===undefined){throw new Error('Missing required parameter: "password"');}
let path='/account/sessions';let payload={};if(email){payload['email']=email;} let path='/account/sessions';let payload={};if(email){payload['email']=email;}
if(password){payload['password']=password;} if(password){payload['password']=password;}
return http.post(path,{'content-type':'application/json',},payload);},deleteSessions:function(){let path='/account/sessions';let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createOAuth2Session:function(provider,success,failure){if(provider===undefined){throw new Error('Missing required parameter: "provider"');} return http.post(path,{'content-type':'application/json',},payload);},deleteSessions:function(){let path='/account/sessions';let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createOAuth2Session:function(provider,success='https://appwrite.io/auth/oauth2/success',failure='https://appwrite.io/auth/oauth2/failure'){if(provider===undefined){throw new Error('Missing required parameter: "provider"');}
if(success===undefined){throw new Error('Missing required parameter: "success"');}
if(failure===undefined){throw new Error('Missing required parameter: "failure"');}
let path='/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}','g'),provider);let payload={};if(success){payload['success']=success;} let path='/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}','g'),provider);let payload={};if(success){payload['success']=success;}
if(failure){payload['failure']=failure;} if(failure){payload['failure']=failure;}
payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},deleteSession:function(sessionId){if(sessionId===undefined){throw new Error('Missing required parameter: "sessionId"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');window.location=config.endpoint+path+((query)?'?'+query:'');},deleteSession:function(sessionId){if(sessionId===undefined){throw new Error('Missing required parameter: "sessionId"');}
let path='/account/sessions/{sessionId}'.replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createVerification:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');} let path='/account/sessions/{sessionId}'.replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},createVerification:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/account/verification';let payload={};if(url){payload['url']=url;} let path='/account/verification';let payload={};if(url){payload['url']=url;}
return http.post(path,{'content-type':'application/json',},payload);},updateVerification:function(userId,secret){if(userId===undefined){throw new Error('Missing required parameter: "userId"');} return http.post(path,{'content-type':'application/json',},payload);},updateVerification:function(userId,secret){if(userId===undefined){throw new Error('Missing required parameter: "userId"');}
@ -68,26 +65,26 @@ return http.put(path,{'content-type':'application/json',},payload);}};let avatar
let path='/avatars/browsers/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/browsers/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getCreditCard:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getCreditCard:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');}
let path='/avatars/credit-cards/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/credit-cards/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getFavicon:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getFavicon:function(url){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/avatars/favicon';let payload={};if(url){payload['url']=url;} let path='/avatars/favicon';let payload={};if(url){payload['url']=url;}
return http.get(path,{'content-type':'application/json',},payload);},getFlag:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getFlag:function(code,width=100,height=100,quality=100){if(code===undefined){throw new Error('Missing required parameter: "code"');}
let path='/avatars/flags/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;} let path='/avatars/flags/{code}'.replace(new RegExp('{code}','g'),code);let payload={};if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
if(quality){payload['quality']=quality;} if(quality){payload['quality']=quality;}
return http.get(path,{'content-type':'application/json',},payload);},getImage:function(url,width=400,height=400){if(url===undefined){throw new Error('Missing required parameter: "url"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getImage:function(url,width=400,height=400){if(url===undefined){throw new Error('Missing required parameter: "url"');}
let path='/avatars/image';let payload={};if(url){payload['url']=url;} let path='/avatars/image';let payload={};if(url){payload['url']=url;}
if(width){payload['width']=width;} if(width){payload['width']=width;}
if(height){payload['height']=height;} if(height){payload['height']=height;}
return http.get(path,{'content-type':'application/json',},payload);},getQR:function(text,size=400,margin=1,download=0){if(text===undefined){throw new Error('Missing required parameter: "text"');} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');},getQR:function(text,size=400,margin=1,download=0){if(text===undefined){throw new Error('Missing required parameter: "text"');}
let path='/avatars/qr';let payload={};if(text){payload['text']=text;} let path='/avatars/qr';let payload={};if(text){payload['text']=text;}
if(size){payload['size']=size;} if(size){payload['size']=size;}
if(margin){payload['margin']=margin;} if(margin){payload['margin']=margin;}
if(download){payload['download']=download;} if(download){payload['download']=download;}
return http.get(path,{'content-type':'application/json',},payload);}};let database={listCollections:function(search='',limit=25,offset=0,orderType='ASC'){let path='/database/collections';let payload={};if(search){payload['search']=search;} payload['project']=config.project;payload['key']=config.key;let query=Object.keys(payload).map(key=>key+'='+encodeURIComponent(payload[key])).join('&');return config.endpoint+path+((query)?'?'+query:'');}};let database={listCollections:function(search='',limit=25,offset=0,orderType='ASC'){let path='/database/collections';let payload={};if(search){payload['search']=search;}
if(limit){payload['limit']=limit;} if(limit){payload['limit']=limit;}
if(offset){payload['offset']=offset;} if(offset){payload['offset']=offset;}
if(orderType){payload['orderType']=orderType;} if(orderType){payload['orderType']=orderType;}
@ -141,7 +138,8 @@ if(read){payload['read']=read;}
if(write){payload['write']=write;} if(write){payload['write']=write;}
return http.patch(path,{'content-type':'application/json',},payload);},deleteDocument:function(collectionId,documentId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');} return http.patch(path,{'content-type':'application/json',},payload);},deleteDocument:function(collectionId,documentId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');}
if(documentId===undefined){throw new Error('Missing required parameter: "documentId"');} if(documentId===undefined){throw new Error('Missing required parameter: "documentId"');}
let path='/database/collections/{collectionId}/documents/{documentId}'.replace(new RegExp('{collectionId}','g'),collectionId).replace(new RegExp('{documentId}','g'),documentId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);}};let locale={get:function(){let path='/locale';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getContinents:function(){let path='/locale/continents';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountries:function(){let path='/locale/countries';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesEU:function(){let path='/locale/countries/eu';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesPhones:function(){let path='/locale/countries/phones';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCurrencies:function(){let path='/locale/currencies';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let projects={list:function(){let path='/projects';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(name,teamId,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId=''){if(name===undefined){throw new Error('Missing required parameter: "name"');} let path='/database/collections/{collectionId}/documents/{documentId}'.replace(new RegExp('{collectionId}','g'),collectionId).replace(new RegExp('{documentId}','g'),documentId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getCollectionLogs:function(collectionId){if(collectionId===undefined){throw new Error('Missing required parameter: "collectionId"');}
let path='/database/collections/{collectionId}/logs'.replace(new RegExp('{collectionId}','g'),collectionId);let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let health={get:function(){let path='/health';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getAntiVirus:function(){let path='/health/anti-virus';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCache:function(){let path='/health/cache';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getDB:function(){let path='/health/db';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueCertificates:function(){let path='/health/queue/certificates';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueFunctions:function(){let path='/health/queue/functions';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueLogs:function(){let path='/health/queue/logs';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueTasks:function(){let path='/health/queue/tasks';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueUsage:function(){let path='/health/queue/usage';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getQueueWebhooks:function(){let path='/health/queue/webhooks';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getStorageLocal:function(){let path='/health/storage/local';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getTime:function(){let path='/health/time';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let locale={get:function(){let path='/locale';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getContinents:function(){let path='/locale/continents';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountries:function(){let path='/locale/countries';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesEU:function(){let path='/locale/countries/eu';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCountriesPhones:function(){let path='/locale/countries/phones';let payload={};return http.get(path,{'content-type':'application/json',},payload);},getCurrencies:function(){let path='/locale/currencies';let payload={};return http.get(path,{'content-type':'application/json',},payload);}};let projects={list:function(){let path='/projects';let payload={};return http.get(path,{'content-type':'application/json',},payload);},create:function(name,teamId,description='',logo='',url='',legalName='',legalCountry='',legalState='',legalCity='',legalAddress='',legalTaxId=''){if(name===undefined){throw new Error('Missing required parameter: "name"');}
if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/projects';let payload={};if(name){payload['name']=name;} let path='/projects';let payload={};if(name){payload['name']=name;}
if(teamId){payload['teamId']=teamId;} if(teamId){payload['teamId']=teamId;}
@ -259,7 +257,7 @@ if(httpUser){payload['httpUser']=httpUser;}
if(httpPass){payload['httpPass']=httpPass;} if(httpPass){payload['httpPass']=httpPass;}
return http.put(path,{'content-type':'application/json',},payload);},deleteTask:function(projectId,taskId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} return http.put(path,{'content-type':'application/json',},payload);},deleteTask:function(projectId,taskId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
if(taskId===undefined){throw new Error('Missing required parameter: "taskId"');} if(taskId===undefined){throw new Error('Missing required parameter: "taskId"');}
let path='/projects/{projectId}/tasks/{taskId}'.replace(new RegExp('{projectId}','g'),projectId).replace(new RegExp('{taskId}','g'),taskId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getUsage:function(projectId,range='monthly'){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} let path='/projects/{projectId}/tasks/{taskId}'.replace(new RegExp('{projectId}','g'),projectId).replace(new RegExp('{taskId}','g'),taskId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getUsage:function(projectId,range='last30'){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
let path='/projects/{projectId}/usage'.replace(new RegExp('{projectId}','g'),projectId);let payload={};if(range){payload['range']=range;} let path='/projects/{projectId}/usage'.replace(new RegExp('{projectId}','g'),projectId);let payload={};if(range){payload['range']=range;}
return http.get(path,{'content-type':'application/json',},payload);},listWebhooks:function(projectId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} return http.get(path,{'content-type':'application/json',},payload);},listWebhooks:function(projectId){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
let path='/projects/{projectId}/webhooks'.replace(new RegExp('{projectId}','g'),projectId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createWebhook:function(projectId,name,events,url,security,httpUser='',httpPass=''){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');} let path='/projects/{projectId}/webhooks'.replace(new RegExp('{projectId}','g'),projectId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createWebhook:function(projectId,name,events,url,security,httpUser='',httpPass=''){if(projectId===undefined){throw new Error('Missing required parameter: "projectId"');}
@ -327,8 +325,12 @@ let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payloa
if(name===undefined){throw new Error('Missing required parameter: "name"');} if(name===undefined){throw new Error('Missing required parameter: "name"');}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload['name']=name;} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(name){payload['name']=name;}
return http.put(path,{'content-type':'application/json',},payload);},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} return http.put(path,{'content-type':'application/json',},payload);},delete:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getMemberships:function(teamId){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} let path='/teams/{teamId}'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},getMemberships:function(teamId,search='',limit=25,offset=0,orderType='ASC'){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};return http.get(path,{'content-type':'application/json',},payload);},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');} let path='/teams/{teamId}/memberships'.replace(new RegExp('{teamId}','g'),teamId);let payload={};if(search){payload['search']=search;}
if(limit){payload['limit']=limit;}
if(offset){payload['offset']=offset;}
if(orderType){payload['orderType']=orderType;}
return http.get(path,{'content-type':'application/json',},payload);},createMembership:function(teamId,email,roles,url,name=''){if(teamId===undefined){throw new Error('Missing required parameter: "teamId"');}
if(email===undefined){throw new Error('Missing required parameter: "email"');} if(email===undefined){throw new Error('Missing required parameter: "email"');}
if(roles===undefined){throw new Error('Missing required parameter: "roles"');} if(roles===undefined){throw new Error('Missing required parameter: "roles"');}
if(url===undefined){throw new Error('Missing required parameter: "url"');} if(url===undefined){throw new Error('Missing required parameter: "url"');}
@ -366,7 +368,7 @@ if(sessionId===undefined){throw new Error('Missing required parameter: "sessionI
let path='/users/{userId}/sessions/{sessionId}'.replace(new RegExp('{userId}','g'),userId).replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},updateStatus:function(userId,status){if(userId===undefined){throw new Error('Missing required parameter: "userId"');} let path='/users/{userId}/sessions/{sessionId}'.replace(new RegExp('{userId}','g'),userId).replace(new RegExp('{sessionId}','g'),sessionId);let payload={};return http.delete(path,{'content-type':'application/json',},payload);},updateStatus:function(userId,status){if(userId===undefined){throw new Error('Missing required parameter: "userId"');}
if(status===undefined){throw new Error('Missing required parameter: "status"');} if(status===undefined){throw new Error('Missing required parameter: "status"');}
let path='/users/{userId}/status'.replace(new RegExp('{userId}','g'),userId);let payload={};if(status){payload['status']=status;} let path='/users/{userId}/status'.replace(new RegExp('{userId}','g'),userId);let payload={};if(status){payload['status']=status;}
return http.patch(path,{'content-type':'application/json',},payload);}};return{setEndpoint:setEndpoint,setProject:setProject,setKey:setKey,setLocale:setLocale,setMode:setMode,account:account,avatars:avatars,database:database,locale:locale,projects:projects,storage:storage,teams:teams,users:users};};if(typeof module!=="undefined"){module.exports=window.Appwrite;}})((typeof window!=="undefined")?window:{});(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart=f()}})(function(){var define,module,exports;return(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){var colorNames=require(5);module.exports={getRgba:getRgba,getHsla:getHsla,getRgb:getRgb,getHsl:getHsl,getHwb:getHwb,getAlpha:getAlpha,hexString:hexString,rgbString:rgbString,rgbaString:rgbaString,percentString:percentString,percentaString:percentaString,hslString:hslString,hslaString:hslaString,hwbString:hwbString,keyword:keyword} return http.patch(path,{'content-type':'application/json',},payload);}};return{setEndpoint:setEndpoint,setProject:setProject,setKey:setKey,setLocale:setLocale,setMode:setMode,account:account,avatars:avatars,database:database,health:health,locale:locale,projects:projects,storage:storage,teams:teams,users:users};};if(typeof module!=="undefined"){module.exports=window.Appwrite;}})((typeof window!=="undefined")?window:{});(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart=f()}})(function(){var define,module,exports;return(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){var colorNames=require(5);module.exports={getRgba:getRgba,getHsla:getHsla,getRgb:getRgb,getHsl:getHsl,getHwb:getHwb,getAlpha:getAlpha,hexString:hexString,rgbString:rgbString,rgbaString:rgbaString,percentString:percentString,percentaString:percentaString,hslString:hslString,hslaString:hslaString,hwbString:hwbString,keyword:keyword}
function getRgba(string){if(!string){return;} function getRgba(string){if(!string){return;}
var abbr=/^#([a-fA-F0-9]{3})$/i,hex=/^#([a-fA-F0-9]{6})$/i,rgba=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,per=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,keyword=/(\w+)/;var rgb=[0,0,0],a=1,match=string.match(abbr);if(match){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match[i]+match[i],16);}} var abbr=/^#([a-fA-F0-9]{3})$/i,hex=/^#([a-fA-F0-9]{6})$/i,rgba=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,per=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,keyword=/(\w+)/;var rgb=[0,0,0],a=1,match=string.match(abbr);if(match){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match[i]+match[i],16);}}
else if(match=string.match(hex)){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match.slice(i*2,i*2+2),16);}} else if(match=string.match(hex)){match=match[1];for(var i=0;i<rgb.length;i++){rgb[i]=parseInt(match.slice(i*2,i*2+2),16);}}

View file

@ -248,7 +248,7 @@ return slf.renderToken(tokens,idx,opts);}
md.renderer.rules.strong_open=renderEm;md.renderer.rules.strong_close=renderEm;return md;},true);})(window);(function(window){"use strict";window.ls.container.set('rtl',function(){var rtlStock="^ا^ب^ت^ث^ج^ح^خ^د^ذ^ر^ز^س^ش^ص^ض^ط^ظ^ع^غ^ف^ق^ك^ل^م^ن^ه^و^ي^א^ב^ג^ד^ה^ו^ז^ח^ט^י^כ^ך^ל^מ^ם^נ^ן^ס^ע^פ^ף^צ^ץ^ק^ר^ש^ת^";var special=["\n"," "," ","״",'"',"_","'","!","@","#","$","^","&","%","*","(",")","+","=","-","[","]","\\","/","{","}","|",":","<",">","?",",",".","0","1","2","3","4","5","6","7","8","9"];var isRTL=function(value){for(var i=0;i<value.length;i++){if(/\s/g.test(value[i])){continue;} md.renderer.rules.strong_open=renderEm;md.renderer.rules.strong_close=renderEm;return md;},true);})(window);(function(window){"use strict";window.ls.container.set('rtl',function(){var rtlStock="^ا^ب^ت^ث^ج^ح^خ^د^ذ^ر^ز^س^ش^ص^ض^ط^ظ^ع^غ^ف^ق^ك^ل^م^ن^ه^و^ي^א^ב^ג^ד^ה^ו^ז^ח^ט^י^כ^ך^ל^מ^ם^נ^ן^ס^ע^פ^ף^צ^ץ^ק^ר^ש^ת^";var special=["\n"," "," ","״",'"',"_","'","!","@","#","$","^","&","%","*","(",")","+","=","-","[","]","\\","/","{","}","|",":","<",">","?",",",".","0","1","2","3","4","5","6","7","8","9"];var isRTL=function(value){for(var i=0;i<value.length;i++){if(/\s/g.test(value[i])){continue;}
if(-1===special.indexOf(value[i])){var firstChar=value[i];break;}} if(-1===special.indexOf(value[i])){var firstChar=value[i];break;}}
if(-1<rtlStock.indexOf("^"+firstChar+"^")){return true;} if(-1<rtlStock.indexOf("^"+firstChar+"^")){return true;}
return false;};return{isRTL:isRTL,};},true);})(window);(function(window){"use strict";window.ls.container.set('sdk',function(window,router){var sdk=new window.Appwrite();sdk.setEndpoint(APP_ENV.API).setProject(router.params.project||'').setLocale(APP_ENV.LOCALE).setMode('admin');return sdk;},false);})(window);(function(window){"use strict";window.ls.container.set('search',function(window){return{params:{},path:'',pointer:'',selected:'',};},true,true);})(window);(function(window){"use strict";window.ls.container.set('timezone',function(){return{convert:function(unixTime){var timezoneMinutes=new Date().getTimezoneOffset();timezoneMinutes=(timezoneMinutes===0)?0:-timezoneMinutes;return parseInt(unixTime)+(timezoneMinutes*60);}};},true);})(window);window.ls.router.add("/auth/signin",{template:"/auth/signin?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/signup",{template:"/auth/signup?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery",{template:"/auth/recovery?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery/reset",{template:"/auth/recovery/reset?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/confirm",{template:"/auth/confirm?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/join",{template:"/auth/join?version="+APP_ENV.VERSION,scope:"home"}).add("/console",{template:"/console?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account/:tab",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/home",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/home/:tab",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/platforms/:platform",{template:function(window){return window.location.pathname+"?version="+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/notifications",{template:"/console/notifications?version="+APP_ENV.VERSION,scope:"console"}).add("/console/settings",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/settings/:tab",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks/:tab",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys/:tab",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks/:tab",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database",{template:"/console/database?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database/collection",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/collection/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/storage",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/storage/:tab",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/view",{template:"/console/users/view?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/view/:tab",{template:"/console/users/view?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/:tab",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true});window.ls.filter.add("gravatar",function($value,element){if(!$value){return"";} return false;};return{isRTL:isRTL,};},true);})(window);(function(window){"use strict";window.ls.container.set('sdk',function(window,router){var sdk=new window.Appwrite();sdk.setEndpoint(APP_ENV.API).setProject(router.params.project||'').setLocale(APP_ENV.LOCALE).setMode('admin');return sdk;},false);})(window);(function(window){"use strict";window.ls.container.set('search',function(window){return{params:{},path:'',pointer:'',selected:'',};},true,true);})(window);(function(window){"use strict";window.ls.container.set('timezone',function(){return{convert:function(unixTime){var timezoneMinutes=new Date().getTimezoneOffset();timezoneMinutes=(timezoneMinutes===0)?0:-timezoneMinutes;return parseInt(unixTime)+(timezoneMinutes*60);}};},true);})(window);window.ls.router.add("/auth/signin",{template:"/auth/signin?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/signup",{template:"/auth/signup?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery",{template:"/auth/recovery?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/recovery/reset",{template:"/auth/recovery/reset?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/confirm",{template:"/auth/confirm?version="+APP_ENV.VERSION,scope:"home"}).add("/auth/join",{template:"/auth/join?version="+APP_ENV.VERSION,scope:"home"}).add("/console",{template:"/console?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/account/:tab",{template:"/console/account?version="+APP_ENV.VERSION,scope:"console"}).add("/console/home",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/home/:tab",{template:"/console/home?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/platforms/:platform",{template:function(window){return window.location.pathname+"?version="+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/notifications",{template:"/console/notifications?version="+APP_ENV.VERSION,scope:"console"}).add("/console/settings",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/settings/:tab",{template:"/console/settings?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/webhooks/:tab",{template:"/console/webhooks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/keys/:tab",{template:"/console/keys?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/tasks/:tab",{template:"/console/tasks?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database",{template:"/console/database?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/database/collection",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/collection/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/database/document/:tab",{template:function(window){return window.location.pathname+window.location.search+'&version='+APP_ENV.VERSION;},scope:"console",project:true}).add("/console/storage",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/storage/:tab",{template:"/console/storage?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/user",{template:"/console/users/user?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/user/:tab",{template:"/console/users/user?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/teams/team",{template:"/console/users/teams/team?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/teams/team/:tab",{template:"/console/users/teams/team?version="+APP_ENV.VERSION,scope:"console",project:true}).add("/console/users/:tab",{template:"/console/users?version="+APP_ENV.VERSION,scope:"console",project:true});window.ls.filter.add("gravatar",function($value,element){if(!$value){return"";}
let MD5=function(s){function L(k,d){return(k<<d)|(k>>>(32-d));} let MD5=function(s){function L(k,d){return(k<<d)|(k>>>(32-d));}
function K(G,k){let I,d,F,H,x;F=G&2147483648;H=k&2147483648;I=G&1073741824;d=k&1073741824;x=(G&1073741823)+(k&1073741823);if(I&d){return x^2147483648^F^H;} function K(G,k){let I,d,F,H,x;F=G&2147483648;H=k&2147483648;I=G&1073741824;d=k&1073741824;x=(G&1073741823)+(k&1073741823);if(I&d){return x^2147483648^F^H;}
if(I|d){if(x&1073741824){return x^3221225472^F^H;}else{return x^1073741824^F^H;}}else{return x^F^H;}} if(I|d){if(x&1073741824){return x^3221225472^F^H;}else{return x^1073741824^F^H;}}else{return x^F^H;}}
@ -283,7 +283,8 @@ $value=abbreviate($value,0,false,false);return $value==="0"?"N/A":$value;}).add(
return result.length;}).add("documentAction",function(container){let collection=container.get('project-collection');let document=container.get('project-document');if(collection&&document&&!document.$id){return'database.createDocument';} return result.length;}).add("documentAction",function(container){let collection=container.get('project-collection');let document=container.get('project-document');if(collection&&document&&!document.$id){return'database.createDocument';}
return'database.updateDocument';}).add("documentSuccess",function(container){let document=container.get('project-document');if(document&&!document.$id){return',redirect';} return'database.updateDocument';}).add("documentSuccess",function(container){let document=container.get('project-document');if(document&&!document.$id){return',redirect';}
return'';}).add("firstElement",function($value){if($value&&$value[0]){return $value[0];} return'';}).add("firstElement",function($value){if($value&&$value[0]){return $value[0];}
return $value;}).add("platformsLimit",function($value){return $value;}).add("limit",function($value){let postfix=($value.length>=50)?'...':'';return $value.substring(0,50)+postfix;;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);} return $value;}).add("platformsLimit",function($value){return $value;}).add("limit",function($value){let postfix=($value.length>=50)?'...':'';return $value.substring(0,50)+postfix;;}).add("arraySentence",function($value){if(!Array.isArray($value)){return'';}
return $value.join(", ").replace(/,\s([^,]+)$/,' and $1');});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);}
let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";} let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";}
return annotate(number,maxPlaces,forcePlaces,abbr);} return annotate(number,maxPlaces,forcePlaces,abbr);}
function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;} function annotate(number,maxPlaces,forcePlaces,abbr){let rounded=0;switch(abbr){case"T":rounded=number/1e12;break;case"B":rounded=number/1e9;break;case"M":rounded=number/1e6;break;case"K":rounded=number/1e3;break;case"":rounded=number;break;}

View file

@ -286,28 +286,6 @@
} }
}(window.document); }(window.document);
let iframe = function(method, url, params) {
let form = document.createElement('form');
form.setAttribute('method', method);
form.setAttribute('action', config.endpoint + url);
for(let key in params) {
if(params.hasOwnProperty(key)) {
let hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
return form.submit();
};
let account = { let account = {
/** /**
@ -334,10 +312,10 @@
* *
* Use this endpoint to allow a new user to register a new account in your * 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 * project. After the user registration completes successfully, you can use
* the [/account/verfication](/docs/account#createVerification) route to start * the [/account/verfication](/docs/client/account#createVerification) route
* verifying the user email address. To allow your new user to login to his * to start verifying the user email address. To allow your new user to login
* new account, you need to create a new [account * to his new account, you need to create a new [account
* session](/docs/account#createSession). * session](/docs/client/account#createSession).
* *
* @param {string} email * @param {string} email
* @param {string} password * @param {string} password
@ -580,7 +558,7 @@
* When the user clicks the confirmation link he is redirected back to your * 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 * 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 * attached to the URL query string. Use the query string params to submit a
* request to the [PUT /account/recovery](/docs/account#updateRecovery) * request to the [PUT /account/recovery](/docs/client/account#updateRecovery)
* endpoint to complete the process. * endpoint to complete the process.
* *
* @param {string} email * @param {string} email
@ -621,7 +599,7 @@
* Use this endpoint to complete the user account password reset. Both the * Use this endpoint to complete the user account password reset. Both the
* **userId** and **secret** arguments will be passed as query parameters to * **userId** and **secret** arguments will be passed as query parameters to
* the redirect URL you have provided when sending your request to the [POST * the redirect URL you have provided when sending your request to the [POST
* /account/recovery](/docs/account#createRecovery) endpoint. * /account/recovery](/docs/client/account#createRecovery) endpoint.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -768,21 +746,13 @@
* @param {string} success * @param {string} success
* @param {string} failure * @param {string} failure
* @throws {Error} * @throws {Error}
* @return {string} * @return {Promise}
*/ */
createOAuth2Session: function(provider, success, failure) { createOAuth2Session: function(provider, success = 'https://appwrite.io/auth/oauth2/success', failure = 'https://appwrite.io/auth/oauth2/failure') {
if(provider === undefined) { if(provider === undefined) {
throw new Error('Missing required parameter: "provider"'); throw new Error('Missing required parameter: "provider"');
} }
if(success === undefined) {
throw new Error('Missing required parameter: "success"');
}
if(failure === undefined) {
throw new Error('Missing required parameter: "failure"');
}
let path = '/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}', 'g'), provider); let path = '/account/sessions/oauth2/{provider}'.replace(new RegExp('{provider}', 'g'), provider);
let payload = {}; let payload = {};
@ -801,7 +771,7 @@
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&'); let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : ''); window.location = config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -840,7 +810,7 @@
* should redirect the user back for your app and allow you to complete the * should redirect the user back for your app and allow you to complete the
* verification process by verifying both the **userId** and **secret** * verification process by verifying both the **userId** and **secret**
* parameters. Learn more about how to [complete the verification * parameters. Learn more about how to [complete the verification
* process](/docs/account#updateAccountVerification). * process](/docs/client/account#updateAccountVerification).
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -926,7 +896,7 @@
* @param {number} height * @param {number} height
* @param {number} quality * @param {number} quality
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getBrowser: function(code, width = 100, height = 100, quality = 100) { getBrowser: function(code, width = 100, height = 100, quality = 100) {
if(code === undefined) { if(code === undefined) {
@ -949,10 +919,13 @@
payload['quality'] = quality; payload['quality'] = quality;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -968,7 +941,7 @@
* @param {number} height * @param {number} height
* @param {number} quality * @param {number} quality
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getCreditCard: function(code, width = 100, height = 100, quality = 100) { getCreditCard: function(code, width = 100, height = 100, quality = 100) {
if(code === undefined) { if(code === undefined) {
@ -991,10 +964,13 @@
payload['quality'] = quality; payload['quality'] = quality;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -1005,7 +981,7 @@
* *
* @param {string} url * @param {string} url
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getFavicon: function(url) { getFavicon: function(url) {
if(url === undefined) { if(url === undefined) {
@ -1020,10 +996,13 @@
payload['url'] = url; payload['url'] = url;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -1038,7 +1017,7 @@
* @param {number} height * @param {number} height
* @param {number} quality * @param {number} quality
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getFlag: function(code, width = 100, height = 100, quality = 100) { getFlag: function(code, width = 100, height = 100, quality = 100) {
if(code === undefined) { if(code === undefined) {
@ -1061,10 +1040,13 @@
payload['quality'] = quality; payload['quality'] = quality;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -1079,7 +1061,7 @@
* @param {number} width * @param {number} width
* @param {number} height * @param {number} height
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getImage: function(url, width = 400, height = 400) { getImage: function(url, width = 400, height = 400) {
if(url === undefined) { if(url === undefined) {
@ -1102,10 +1084,13 @@
payload['height'] = height; payload['height'] = height;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
}, },
/** /**
@ -1119,7 +1104,7 @@
* @param {number} margin * @param {number} margin
* @param {number} download * @param {number} download
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {string}
*/ */
getQR: function(text, size = 400, margin = 1, download = 0) { getQR: function(text, size = 400, margin = 1, download = 0) {
if(text === undefined) { if(text === undefined) {
@ -1146,10 +1131,13 @@
payload['download'] = download; payload['download'] = download;
} }
return http payload['project'] = config.project;
.get(path, {
'content-type': 'application/json', payload['key'] = config.key;
}, payload);
let query = Object.keys(payload).map(key => key + '=' + encodeURIComponent(payload[key])).join('&');
return config.endpoint + path + ((query) ? '?' + query : '');
} }
}; };
@ -1203,9 +1191,9 @@
* Create a new Collection. * Create a new Collection.
* *
* @param {string} name * @param {string} name
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @param {array} rules * @param {string[]} rules
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -1284,9 +1272,9 @@
* *
* @param {string} collectionId * @param {string} collectionId
* @param {string} name * @param {string} name
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @param {array} rules * @param {string[]} rules
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -1367,7 +1355,7 @@
* modes](/docs/admin). * modes](/docs/admin).
* *
* @param {string} collectionId * @param {string} collectionId
* @param {array} filters * @param {string[]} filters
* @param {number} offset * @param {number} offset
* @param {number} limit * @param {number} limit
* @param {string} orderField * @param {string} orderField
@ -1433,12 +1421,15 @@
/** /**
* Create Document * Create Document
* *
* Create a new Document. * Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database?sdk=nodejs#createCollection) API or
* directly from your database console.
* *
* @param {string} collectionId * @param {string} collectionId
* @param {object} data * @param {object} data
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @param {string} parentDocument * @param {string} parentDocument
* @param {string} parentProperty * @param {string} parentProperty
* @param {string} parentPropertyType * @param {string} parentPropertyType
@ -1533,8 +1524,8 @@
* @param {string} collectionId * @param {string} collectionId
* @param {string} documentId * @param {string} documentId
* @param {object} data * @param {object} data
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -1610,6 +1601,272 @@
.delete(path, { .delete(path, {
'content-type': 'application/json', 'content-type': 'application/json',
}, payload); }, payload);
},
/**
* Get Collection Logs
*
*
* @param {string} collectionId
* @throws {Error}
* @return {Promise}
*/
getCollectionLogs: function(collectionId) {
if(collectionId === undefined) {
throw new Error('Missing required parameter: "collectionId"');
}
let path = '/database/collections/{collectionId}/logs'.replace(new RegExp('{collectionId}', 'g'), collectionId);
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
}
};
let health = {
/**
* Get HTTP
*
* Check the Appwrite HTTP server is up and responsive.
*
* @throws {Error}
* @return {Promise}
*/
get: function() {
let path = '/health';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Anti virus
*
* Check the Appwrite Anti Virus server is up and connection is successful.
*
* @throws {Error}
* @return {Promise}
*/
getAntiVirus: function() {
let path = '/health/anti-virus';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Cache
*
* Check the Appwrite in-memory cache server is up and connection is
* successful.
*
* @throws {Error}
* @return {Promise}
*/
getCache: function() {
let path = '/health/cache';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get DB
*
* Check the Appwrite database server is up and connection is successful.
*
* @throws {Error}
* @return {Promise}
*/
getDB: function() {
let path = '/health/db';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Certificate Queue
*
* Get the number of certificates that are waiting to be issued against
* [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue
* server.
*
* @throws {Error}
* @return {Promise}
*/
getQueueCertificates: function() {
let path = '/health/queue/certificates';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Functions Queue
*
*
* @throws {Error}
* @return {Promise}
*/
getQueueFunctions: function() {
let path = '/health/queue/functions';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Logs Queue
*
* Get the number of logs that are waiting to be processed in the Appwrite
* internal queue server.
*
* @throws {Error}
* @return {Promise}
*/
getQueueLogs: function() {
let path = '/health/queue/logs';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Tasks Queue
*
* Get the number of tasks that are waiting to be processed in the Appwrite
* internal queue server.
*
* @throws {Error}
* @return {Promise}
*/
getQueueTasks: function() {
let path = '/health/queue/tasks';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Usage Queue
*
* Get the number of usage stats that are waiting to be processed in the
* Appwrite internal queue server.
*
* @throws {Error}
* @return {Promise}
*/
getQueueUsage: function() {
let path = '/health/queue/usage';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Webhooks Queue
*
* Get the number of webhooks that are waiting to be processed in the Appwrite
* internal queue server.
*
* @throws {Error}
* @return {Promise}
*/
getQueueWebhooks: function() {
let path = '/health/queue/webhooks';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Local Storage
*
* Check the Appwrite local storage device is up and connection is successful.
*
* @throws {Error}
* @return {Promise}
*/
getStorageLocal: function() {
let path = '/health/storage/local';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
},
/**
* Get Time
*
* Check the Appwrite server time is synced with Google remote NTP server. We
* use this technology to smoothly handle leap seconds with no disruptive
* events. The [Network Time
* Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is
* used by hundreds of millions of computers and devices to synchronize their
* clocks over the Internet. If your computer sets its own clock, it likely
* uses NTP.
*
* @throws {Error}
* @return {Promise}
*/
getTime: function() {
let path = '/health/time';
let payload = {};
return http
.get(path, {
'content-type': 'application/json',
}, payload);
} }
}; };
@ -1640,7 +1897,7 @@
}, },
/** /**
* List Countries * List Continents
* *
* List of all continents. You can use the locale header to get the data in a * List of all continents. You can use the locale header to get the data in a
* supported language. * supported language.
@ -2142,7 +2399,7 @@
* *
* @param {string} projectId * @param {string} projectId
* @param {string} name * @param {string} name
* @param {array} scopes * @param {string[]} scopes
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -2212,7 +2469,7 @@
* @param {string} projectId * @param {string} projectId
* @param {string} keyId * @param {string} keyId
* @param {string} name * @param {string} name
* @param {array} scopes * @param {string[]} scopes
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -2542,7 +2799,7 @@
* @param {number} security * @param {number} security
* @param {string} httpMethod * @param {string} httpMethod
* @param {string} httpUrl * @param {string} httpUrl
* @param {array} httpHeaders * @param {string[]} httpHeaders
* @param {string} httpUser * @param {string} httpUser
* @param {string} httpPass * @param {string} httpPass
* @throws {Error} * @throws {Error}
@ -2663,7 +2920,7 @@
* @param {number} security * @param {number} security
* @param {string} httpMethod * @param {string} httpMethod
* @param {string} httpUrl * @param {string} httpUrl
* @param {array} httpHeaders * @param {string[]} httpHeaders
* @param {string} httpUser * @param {string} httpUser
* @param {string} httpPass * @param {string} httpPass
* @throws {Error} * @throws {Error}
@ -2781,10 +3038,11 @@
* *
* *
* @param {string} projectId * @param {string} projectId
* @param {string} range
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getUsage: function(projectId, range = 'monthly') { getUsage: function(projectId, range = 'last30') {
if(projectId === undefined) { if(projectId === undefined) {
throw new Error('Missing required parameter: "projectId"'); throw new Error('Missing required parameter: "projectId"');
} }
@ -2832,7 +3090,7 @@
* *
* @param {string} projectId * @param {string} projectId
* @param {string} name * @param {string} name
* @param {array} events * @param {string[]} events
* @param {string} url * @param {string} url
* @param {number} security * @param {number} security
* @param {string} httpUser * @param {string} httpUser
@ -2930,7 +3188,7 @@
* @param {string} projectId * @param {string} projectId
* @param {string} webhookId * @param {string} webhookId
* @param {string} name * @param {string} name
* @param {array} events * @param {string[]} events
* @param {string} url * @param {string} url
* @param {number} security * @param {number} security
* @param {string} httpUser * @param {string} httpUser
@ -3077,8 +3335,8 @@
* read and write arguments. * read and write arguments.
* *
* @param {File} file * @param {File} file
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -3149,8 +3407,8 @@
* to update this resource. * to update this resource.
* *
* @param {string} fileId * @param {string} fileId
* @param {array} read * @param {string[]} read
* @param {array} write * @param {string[]} write
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -3380,7 +3638,7 @@
* project. * project.
* *
* @param {string} name * @param {string} name
* @param {array} roles * @param {string[]} roles
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
@ -3498,10 +3756,14 @@
* for this list of resources. * for this list of resources.
* *
* @param {string} teamId * @param {string} teamId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} orderType
* @throws {Error} * @throws {Error}
* @return {Promise} * @return {Promise}
*/ */
getMemberships: function(teamId) { getMemberships: function(teamId, search = '', limit = 25, offset = 0, orderType = 'ASC') {
if(teamId === undefined) { if(teamId === undefined) {
throw new Error('Missing required parameter: "teamId"'); throw new Error('Missing required parameter: "teamId"');
} }
@ -3510,6 +3772,22 @@
let payload = {}; let payload = {};
if(search) {
payload['search'] = search;
}
if(limit) {
payload['limit'] = limit;
}
if(offset) {
payload['offset'] = offset;
}
if(orderType) {
payload['orderType'] = orderType;
}
return http return http
.get(path, { .get(path, {
'content-type': 'application/json', 'content-type': 'application/json',
@ -3525,8 +3803,8 @@
* *
* Use the 'URL' parameter to redirect the user from the invitation email back * Use the 'URL' parameter to redirect the user from the invitation email back
* to your app. When the user is redirected, use the [Update Team Membership * to your app. When the user is redirected, use the [Update Team Membership
* Status](/docs/teams#updateMembershipStatus) endpoint to allow the user to * Status](/docs/client/teams#updateMembershipStatus) endpoint to allow the
* accept the invitation to the team. * user to accept the invitation to the team.
* *
* Please note that in order to avoid a [Redirect * Please note that in order to avoid a [Redirect
* Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) * Attacks](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md)
@ -3535,7 +3813,7 @@
* *
* @param {string} teamId * @param {string} teamId
* @param {string} email * @param {string} email
* @param {array} roles * @param {string[]} roles
* @param {string} url * @param {string} url
* @param {string} name * @param {string} name
* @throws {Error} * @throws {Error}
@ -3922,10 +4200,7 @@
throw new Error('Missing required parameter: "sessionId"'); throw new Error('Missing required parameter: "sessionId"');
} }
let path = '/users/{userId}/sessions/{sessionId}' let path = '/users/{userId}/sessions/{sessionId}'.replace(new RegExp('{userId}', 'g'), userId).replace(new RegExp('{sessionId}', 'g'), sessionId);
.replace(new RegExp('{userId}', 'g'), userId)
.replace(new RegExp('{sessionId}', 'g'), sessionId)
;
let payload = {}; let payload = {};
@ -3978,6 +4253,7 @@
account: account, account: account,
avatars: avatars, avatars: avatars,
database: database, database: database,
health: health,
locale: locale, locale: locale,
projects: projects, projects: projects,
storage: storage, storage: storage,

View file

@ -415,6 +415,13 @@ window.ls.filter
return $value.substring(0, 50) + postfix; return $value.substring(0, 50) + postfix;
; ;
}) })
.add("arraySentence", function($value) {
if(!Array.isArray($value)) {
return '';
}
return $value.join(", ").replace(/,\s([^,]+)$/, ' and $1');
})
; ;
function abbreviate(number, maxPlaces, forcePlaces, forceLetter) { function abbreviate(number, maxPlaces, forcePlaces, forceLetter) {

View file

@ -144,13 +144,23 @@ window.ls.router
scope: "console", scope: "console",
project: true project: true
}) })
.add("/console/users/view", { .add("/console/users/user", {
template: "/console/users/view?version=" + APP_ENV.VERSION, template: "/console/users/user?version=" + APP_ENV.VERSION,
scope: "console", scope: "console",
project: true project: true
}) })
.add("/console/users/view/:tab", { .add("/console/users/user/:tab", {
template: "/console/users/view?version=" + APP_ENV.VERSION, template: "/console/users/user?version=" + APP_ENV.VERSION,
scope: "console",
project: true
})
.add("/console/users/teams/team", {
template: "/console/users/teams/team?version=" + APP_ENV.VERSION,
scope: "console",
project: true
})
.add("/console/users/teams/team/:tab", {
template: "/console/users/teams/team?version=" + APP_ENV.VERSION,
scope: "console", scope: "console",
project: true project: true
}) })

View file

@ -22,10 +22,11 @@ trait TeamsBaseClient
], $this->getHeaders())); ], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body'][0]['$id']); $this->assertIsInt($response['body']['sum']);
$this->assertEquals($this->getUser()['name'], $response['body'][0]['name']); $this->assertNotEmpty($response['body']['memberships'][0]['$id']);
$this->assertEquals($this->getUser()['email'], $response['body'][0]['email']); $this->assertEquals($this->getUser()['name'], $response['body']['memberships'][0]['name']);
$this->assertEquals('owner', $response['body'][0]['roles'][0]); $this->assertEquals($this->getUser()['email'], $response['body']['memberships'][0]['email']);
$this->assertEquals('owner', $response['body']['memberships'][0]['roles'][0]);
/** /**
* Test for FAILURE * Test for FAILURE
@ -231,7 +232,7 @@ trait TeamsBaseClient
], $this->getHeaders())); ], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(1, $response['body']); $this->assertCount(1, $response['body']['memberships']);
return []; return [];
} }

View file

@ -22,7 +22,7 @@ trait TeamsBaseServer
], $this->getHeaders())); ], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertCount(0, $response['body']); $this->assertEquals(0, $response['body']['sum']);
/** /**
* Test for FAILURE * Test for FAILURE