feat: introduce 0.15.x support

This commit is contained in:
Torsten Dittmann
2022-06-28 13:33:05 +02:00
parent 1e8c379743
commit 2f1f7c3f9c
37 changed files with 1182 additions and 419 deletions
+13
View File
@@ -1,3 +1,16 @@
## 6.0.0
* Support for Appwrite 0.15
* **NEW** Phone authentication `account.createPhoneSession()`
* **BREAKING** `Database` -> `Databases`
* **BREAKING** `account.createSession()` -> `account.createEmailSession()`
* **BREAKING** `dateCreated` attribute removed from `Team`, `Execution`, `File` models
* **BREAKING** `dateCreated` and `dateUpdated` attribute removed from `Func`, `Deployment`, `Bucket` models
* **BREAKING** Realtime channels
* collections.[COLLECTION_ID] is now databases.[DATABASE_ID].ollections.[COLLECTION_ID]
* collections.[COLLECTION_ID].documents is now databases.[DATABASE_ID].ollections.[COLLECTION_ID].documents
**Full Changelog for Appwrite 0.15 can be found here**: https://github.com/appwrite/appwrite/blob/master/CHANGES.md#version-0150
## 5.0.0
* Support for Appwrite 0.14
* **BREAKING** `account.delete()` -> `account.updateStatus()`
+9 -6
View File
@@ -2,12 +2,12 @@
[![pub package](https://img.shields.io/pub/v/appwrite?style=flat-square)](https://pub.dartlang.org/packages/appwrite)
![License](https://img.shields.io/github/license/appwrite/sdk-for-flutter.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-0.14.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-0.15.0-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
**This SDK is compatible with Appwrite server version 0.14.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).**
**This SDK is compatible with Appwrite server version 0.15.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).**
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
@@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file:
```yml
dependencies:
appwrite: ^5.0.0
appwrite: ^6.0.0
```
You can install packages from the command line:
@@ -43,11 +43,14 @@ If you are building your Flutter application for multiple devices, you have to f
### Android
For **Android** first add your app <u>name</u> and <u>package name</u>, Your package name is generally the **applicationId** in your app-level <a href="https://github.com/appwrite/playground-for-flutter/blob/0fdbdff98384fff940ed0b1e08cf14cfe3a2be3e/android/app/build.gradle#L41" target="_blank" rel="noopener">build.gradle</a> file. By registering your new app platform, you are allowing your app to communicate with the Appwrite API.
In order to capture the Appwrite OAuth callback url, the following activity needs to be added to your [AndroidManifest.xml](https://github.com/appwrite/playground-for-flutter/blob/master/android/app/src/main/AndroidManifest.xml). Be sure to replace the **[PROJECT_ID]** string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in the console.
In order to capture the Appwrite OAuth callback url, the following activity needs to be added inside the `<application>` tag, along side the existing `<activity>` tags in your [AndroidManifest.xml](https://github.com/appwrite/playground-for-flutter/blob/master/android/app/src/main/AndroidManifest.xml). Be sure to replace the **[PROJECT_ID]** string with your actual Appwrite project ID. You can find your Appwrite project ID in your project settings screen in the console.
```xml
<manifest>
<application>
<manifest ...>
....
<application ...>
....
<!-- Add this inside the <application> tag, along side the existing <activity> tags -->
<activity android:name="com.linusu.flutter_web_auth.CallbackActivity" >
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW" />
@@ -8,7 +8,7 @@ void main() { // Init SDK
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createSession(
Future result = account.createEmailSession(
email: 'email@example.com',
password: 'password',
);
@@ -0,0 +1,22 @@
import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createPhoneSession(
userId: '[USER_ID]',
number: '',
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -0,0 +1,19 @@
import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.createPhoneVerification();
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -0,0 +1,22 @@
import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updatePhoneSession(
userId: '[USER_ID]',
secret: '[SECRET]',
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -0,0 +1,22 @@
import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updatePhoneVerification(
userId: '[USER_ID]',
secret: '[SECRET]',
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
+22
View File
@@ -0,0 +1,22 @@
import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = account.updatePhone(
number: '',
password: 'password',
);
result
.then((response) {
print(response);
}).catchError((error) {
print(error.response);
});
}
@@ -2,13 +2,13 @@ import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
Databases databases = Databases(client, databaseId: '[DATABASE_ID]');
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.createDocument(
Future result = databases.createDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
data: {},
@@ -2,13 +2,13 @@ import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
Databases databases = Databases(client, databaseId: '[DATABASE_ID]');
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.deleteDocument(
Future result = databases.deleteDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
);
@@ -2,13 +2,13 @@ import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
Databases databases = Databases(client, databaseId: '[DATABASE_ID]');
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.getDocument(
Future result = databases.getDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
);
@@ -2,13 +2,13 @@ import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
Databases databases = Databases(client, databaseId: '[DATABASE_ID]');
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.listDocuments(
Future result = databases.listDocuments(
collectionId: '[COLLECTION_ID]',
);
@@ -2,16 +2,15 @@ import 'package:appwrite/appwrite.dart';
void main() { // Init SDK
Client client = Client();
Database database = Database(client);
Databases databases = Databases(client, databaseId: '[DATABASE_ID]');
client
.setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
.setProject('5df5acd0d48c2') // Your project ID
;
Future result = database.updateDocument(
Future result = databases.updateDocument(
collectionId: '[COLLECTION_ID]',
documentId: '[DOCUMENT_ID]',
data: {},
);
result
+3 -4
View File
@@ -3,14 +3,14 @@ library appwrite;
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'src/chunked_upload_stub.dart'
if (dart.library.io) 'src/chunked_upload_io.dart';
import 'package:http/http.dart' show MultipartFile;
import 'src/enums.dart';
import 'src/client.dart';
import 'src/service.dart';
import 'src/input_file.dart';
import 'models.dart' as models;
import 'src/upload_progress.dart';
import 'src/exception.dart';
export 'src/response.dart';
export 'src/client.dart';
@@ -20,12 +20,11 @@ export 'src/upload_progress.dart';
export 'src/realtime_subscription.dart';
export 'src/realtime_message.dart';
export 'src/input_file.dart';
export 'package:http/http.dart' show MultipartFile;
part 'query.dart';
part 'services/account.dart';
part 'services/avatars.dart';
part 'services/database.dart';
part 'services/databases.dart';
part 'services/functions.dart';
part 'services/locale.dart';
part 'services/storage.dart';
+353 -61
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Account service allows you to authenticate and manage a user account.
class Account extends Service {
Account(Client client): super(client);
@@ -13,14 +12,20 @@ class Account extends Service {
const String path = '/account';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Create Account
@@ -36,18 +41,24 @@ class Account extends Service {
const String path = '/account';
final Map<String, dynamic> params = {
'userId': userId,
'email': email,
'password': password,
'name': name,
'email': email,
'password': password,
'name': name,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Update Account Email
@@ -65,16 +76,22 @@ class Account extends Service {
const String path = '/account/email';
final Map<String, dynamic> params = {
'email': email,
'password': password,
'password': password,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Create Account JWT
@@ -89,14 +106,20 @@ class Account extends Service {
const String path = '/account/jwt';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Jwt.fromMap(res.data);
}
/// Get Account Logs
@@ -109,15 +132,21 @@ class Account extends Service {
final Map<String, dynamic> params = {
'limit': limit,
'offset': offset,
'offset': offset,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.LogList.fromMap(res.data);
}
/// Update Account Name
@@ -128,15 +157,21 @@ class Account extends Service {
const String path = '/account/name';
final Map<String, dynamic> params = {
'name': name,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Update Account Password
@@ -149,16 +184,51 @@ class Account extends Service {
const String path = '/account/password';
final Map<String, dynamic> params = {
'password': password,
'oldPassword': oldPassword,
'oldPassword': oldPassword,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Update Account Phone
///
/// Update currently logged in user account phone number. After changing phone
/// number, the user confirmation status will get reset. A new confirmation SMS
/// is not sent automatically however you can use the phone confirmation
/// endpoint again to send the confirmation SMS.
///
Future<models.User> updatePhone({required String number, required String password}) async {
const String path = '/account/phone';
final Map<String, dynamic> params = {
'number': number,
'password': password,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Get Account Preferences
@@ -169,14 +239,20 @@ class Account extends Service {
const String path = '/account/prefs';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Preferences.fromMap(res.data);
}
/// Update Account Preferences
@@ -189,15 +265,21 @@ class Account extends Service {
const String path = '/account/prefs';
final Map<String, dynamic> params = {
'prefs': prefs,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Create Password Recovery
@@ -215,16 +297,22 @@ class Account extends Service {
const String path = '/account/recovery';
final Map<String, dynamic> params = {
'email': email,
'url': url,
'url': url,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Password Recovery (confirmation)
@@ -243,18 +331,24 @@ class Account extends Service {
const String path = '/account/recovery';
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
'password': password,
'passwordAgain': passwordAgain,
'secret': secret,
'password': password,
'passwordAgain': passwordAgain,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Get Account Sessions
@@ -266,35 +360,20 @@ class Account extends Service {
const String path = '/account/sessions';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.SessionList.fromMap(res.data);
}
/// Create Account Session
///
/// Allow the user to login into their account by providing a valid email and
/// password combination. This route will create a new session for the user.
///
Future<models.Session> createSession({required String email, required String password}) async {
const String path = '/account/sessions';
final Map<String, dynamic> params = {
'email': email,
'password': password,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Delete All Account Sessions
@@ -306,14 +385,20 @@ class Account extends Service {
const String path = '/account/sessions';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
/// Create Anonymous Session
@@ -329,14 +414,47 @@ class Account extends Service {
const String path = '/account/sessions/anonymous';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Create Account Session with Email
///
/// Allow the user to login into their account by providing a valid email and
/// password combination. This route will create a new session for the user.
///
Future<models.Session> createEmailSession({required String email, required String password}) async {
const String path = '/account/sessions/email';
final Map<String, dynamic> params = {
'email': email,
'password': password,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Create Magic URL session
@@ -356,17 +474,23 @@ class Account extends Service {
const String path = '/account/sessions/magic-url';
final Map<String, dynamic> params = {
'userId': userId,
'email': email,
'url': url,
'email': email,
'url': url,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Magic URL session (confirmation)
@@ -387,16 +511,22 @@ class Account extends Service {
const String path = '/account/sessions/magic-url';
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
'secret': secret,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Create Account Session with OAuth2
@@ -419,12 +549,13 @@ class Account extends Service {
final Map<String, dynamic> params = {
'success': success,
'failure': failure,
'scopes': scopes,
'failure': failure,
'scopes': scopes,
'project': client.config['project'],
};
final List query = [];
params.forEach((key, value) {
@@ -447,6 +578,72 @@ class Account extends Service {
return client.webAuth(url);
}
/// Create Phone session
///
/// Sends the user a SMS with a secret key for creating a session. Use the
/// returned user ID and the secret to submit a request to the [PUT
/// /account/sessions/phone](/docs/client/account#accountUpdatePhoneSession)
/// endpoint to complete the login process. The secret sent to the user's phone
/// is valid for 15 minutes.
///
Future<models.Token> createPhoneSession({required String userId, required String number}) async {
const String path = '/account/sessions/phone';
final Map<String, dynamic> params = {
'userId': userId,
'number': number,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Phone session (confirmation)
///
/// Use this endpoint to complete creating the session with the Magic URL. Both
/// the **userId** and **secret** arguments will be passed as query parameters
/// to the redirect URL you have provided when sending your request to the
/// [POST
/// /account/sessions/magic-url](/docs/client/account#accountCreateMagicURLSession)
/// endpoint.
///
/// 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)
/// the only valid redirect URLs are the ones from domains you have set when
/// adding your platforms in the console interface.
///
Future<models.Session> updatePhoneSession({required String userId, required String secret}) async {
const String path = '/account/sessions/phone';
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Get Session By ID
@@ -458,14 +655,20 @@ class Account extends Service {
final String path = '/account/sessions/{sessionId}'.replaceAll('{sessionId}', sessionId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Update Session (Refresh Tokens)
@@ -478,14 +681,20 @@ class Account extends Service {
final String path = '/account/sessions/{sessionId}'.replaceAll('{sessionId}', sessionId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.Session.fromMap(res.data);
}
/// Delete Account Session
@@ -499,14 +708,20 @@ class Account extends Service {
final String path = '/account/sessions/{sessionId}'.replaceAll('{sessionId}', sessionId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
/// Update Account Status
@@ -519,14 +734,20 @@ class Account extends Service {
const String path = '/account/status';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.User.fromMap(res.data);
}
/// Create Email Verification
@@ -538,8 +759,8 @@ class Account extends Service {
/// should redirect the user back to your app and allow you to complete the
/// verification process by verifying both the **userId** and **secret**
/// parameters. Learn more about how to [complete the verification
/// process](/docs/client/account#accountUpdateVerification). The verification
/// link sent to the user's email address is valid for 7 days.
/// process](/docs/client/account#accountUpdateEmailVerification). The
/// verification link sent to the user's email address is valid for 7 days.
///
/// 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),
@@ -551,15 +772,21 @@ class Account extends Service {
const String path = '/account/verification';
final Map<String, dynamic> params = {
'url': url,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Email Verification (confirmation)
@@ -573,15 +800,80 @@ class Account extends Service {
const String path = '/account/verification';
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
'secret': secret,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Phone Verification
///
/// Use this endpoint to send a verification message to your user's phone
/// number to confirm they are the valid owners of that address. The provided
/// secret should allow you to complete the verification process by verifying
/// both the **userId** and **secret** parameters. Learn more about how to
/// [complete the verification
/// process](/docs/client/account#accountUpdatePhoneVerification). The
/// verification link sent to the user's phone number is valid for 15 minutes.
///
Future<models.Token> createPhoneVerification() async {
const String path = '/account/verification/phone';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
/// Create Phone Verification (confirmation)
///
/// Use this endpoint to complete the user phone verification process. Use the
/// **userId** and **secret** that were sent to your user's phone number to
/// verify the user email ownership. If confirmed this route will return a 200
/// status code.
///
Future<models.Token> updatePhoneVerification({required String userId, required String secret}) async {
const String path = '/account/verification/phone';
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Token.fromMap(res.data);
}
}
+36 -16
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Avatars service aims to help you complete everyday tasks related to
/// your app image, icons, and avatars.
class Avatars extends Service {
@@ -23,13 +22,16 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'width': width,
'height': height,
'quality': quality,
'height': height,
'quality': quality,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get Credit Card Icon
@@ -49,13 +51,16 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'width': width,
'height': height,
'quality': quality,
'height': height,
'quality': quality,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get Favicon
@@ -69,11 +74,14 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'url': url,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get Country Flag
@@ -93,13 +101,16 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'width': width,
'height': height,
'quality': quality,
'height': height,
'quality': quality,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get Image from URL
@@ -120,13 +131,16 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'url': url,
'width': width,
'height': height,
'width': width,
'height': height,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get User Initials
@@ -153,15 +167,18 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'name': name,
'width': width,
'height': height,
'color': color,
'background': background,
'width': width,
'height': height,
'color': color,
'background': background,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get QR Code
@@ -175,13 +192,16 @@ class Avatars extends Service {
final Map<String, dynamic> params = {
'text': text,
'size': size,
'margin': margin,
'download': download,
'size': size,
'margin': margin,
'download': download,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
}
-120
View File
@@ -1,120 +0,0 @@
part of appwrite;
/// The Database service allows you to create structured collections of
/// documents, query and filter lists of documents
class Database extends Service {
Database(Client client): super(client);
/// List Documents
///
/// Get a list of all the user documents. You can use the query params to
/// filter your results. On admin mode, this endpoint will return a list of all
/// of the project's documents. [Learn more about different API
/// modes](/docs/admin).
///
Future<models.DocumentList> listDocuments({required String collectionId, List? queries, int? limit, int? offset, String? cursor, String? cursorDirection, List? orderAttributes, List? orderTypes}) async {
final String path = '/database/collections/{collectionId}/documents'.replaceAll('{collectionId}', collectionId);
final Map<String, dynamic> params = {
'queries': queries,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderAttributes': orderAttributes,
'orderTypes': orderTypes,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.DocumentList.fromMap(res.data);
}
/// Create Document
///
/// Create a new Document. Before using this route, you should create a new
/// collection resource using either a [server
/// integration](/docs/server/database#databaseCreateCollection) API or
/// directly from your database console.
///
Future<models.Document> createDocument({required String collectionId, required String documentId, required Map data, List? read, List? write}) async {
final String path = '/database/collections/{collectionId}/documents'.replaceAll('{collectionId}', collectionId);
final Map<String, dynamic> params = {
'documentId': documentId,
'data': data,
'read': read,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Get Document
///
/// Get a document by its unique ID. This endpoint response returns a JSON
/// object with the document data.
///
Future<models.Document> getDocument({required String collectionId, required String documentId}) async {
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Update Document
///
/// Update a document by its unique ID. Using the patch method you can pass
/// only specific fields that will get updated.
///
Future<models.Document> updateDocument({required String collectionId, required String documentId, required Map data, List? read, List? write}) async {
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
'data': data,
'read': read,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Delete Document
///
/// Delete a document by its unique ID.
///
Future deleteDocument({required String collectionId, required String documentId}) async {
final String path = '/database/collections/{collectionId}/documents/{documentId}'.replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
}
+127
View File
@@ -0,0 +1,127 @@
part of appwrite;
/// The Databases service allows you to create structured collections of
/// documents, query and filter lists of documents
class Databases extends Service {
Databases(Client client, {required this.databaseId}): super(client);
String databaseId;
/// List Documents
Future<models.DocumentList> listDocuments({required String collectionId, List? queries, int? limit, int? offset, String? cursor, String? cursorDirection, List? orderAttributes, List? orderTypes}) async {
final String path = '/databases/{databaseId}/collections/{collectionId}/documents'.replaceAll('{databaseId}', databaseId).replaceAll('{collectionId}', collectionId);
final Map<String, dynamic> params = {
'queries': queries,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderAttributes': orderAttributes,
'orderTypes': orderTypes,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.DocumentList.fromMap(res.data);
}
/// Create Document
Future<models.Document> createDocument({required String collectionId, required String documentId, required Map data, List? read, List? write}) async {
final String path = '/databases/{databaseId}/collections/{collectionId}/documents'.replaceAll('{databaseId}', databaseId).replaceAll('{collectionId}', collectionId);
final Map<String, dynamic> params = {
'documentId': documentId,
'data': data,
'read': read,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Get Document
Future<models.Document> getDocument({required String collectionId, required String documentId}) async {
final String path = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}'.replaceAll('{databaseId}', databaseId).replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Update Document
Future<models.Document> updateDocument({required String collectionId, required String documentId, Map? data, List? read, List? write}) async {
final String path = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}'.replaceAll('{databaseId}', databaseId).replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
'data': data,
'read': read,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.Document.fromMap(res.data);
}
/// Delete Document
Future deleteDocument({required String collectionId, required String documentId}) async {
final String path = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}'.replaceAll('{databaseId}', databaseId).replaceAll('{collectionId}', collectionId).replaceAll('{documentId}', documentId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
}
+33 -10
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Functions Service allows you view, create and manage your Cloud
/// Functions.
class Functions extends Service {
@@ -11,14 +10,20 @@ class Functions extends Service {
final String path = '/functions/{functionId}/deployments/{deploymentId}/builds/{buildId}'.replaceAll('{functionId}', functionId).replaceAll('{deploymentId}', deploymentId).replaceAll('{buildId}', buildId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return res.data;
}
/// List Executions
@@ -33,18 +38,24 @@ class Functions extends Service {
final Map<String, dynamic> params = {
'limit': limit,
'offset': offset,
'search': search,
'cursor': cursor,
'cursorDirection': cursorDirection,
'offset': offset,
'search': search,
'cursor': cursor,
'cursorDirection': cursorDirection,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.ExecutionList.fromMap(res.data);
}
/// Create Execution
@@ -58,16 +69,22 @@ class Functions extends Service {
final String path = '/functions/{functionId}/executions'.replaceAll('{functionId}', functionId);
final Map<String, dynamic> params = {
'data': data,
'async': xasync,
'async': xasync,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Execution.fromMap(res.data);
}
/// Get Execution
@@ -78,13 +95,19 @@ class Functions extends Service {
final String path = '/functions/{functionId}/executions/{executionId}'.replaceAll('{functionId}', functionId).replaceAll('{executionId}', executionId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Execution.fromMap(res.data);
}
}
+49 -8
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Locale service allows you to customize your app based on your users'
/// location.
class Locale extends Service {
@@ -19,14 +18,20 @@ class Locale extends Service {
const String path = '/locale';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Locale.fromMap(res.data);
}
/// List Continents
@@ -38,14 +43,20 @@ class Locale extends Service {
const String path = '/locale/continents';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.ContinentList.fromMap(res.data);
}
/// List Countries
@@ -57,14 +68,20 @@ class Locale extends Service {
const String path = '/locale/countries';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.CountryList.fromMap(res.data);
}
/// List EU Countries
@@ -76,14 +93,20 @@ class Locale extends Service {
const String path = '/locale/countries/eu';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.CountryList.fromMap(res.data);
}
/// List Countries Phone Codes
@@ -95,14 +118,20 @@ class Locale extends Service {
const String path = '/locale/countries/phones';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.PhoneList.fromMap(res.data);
}
/// List Currencies
@@ -115,14 +144,20 @@ class Locale extends Service {
const String path = '/locale/currencies';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.CurrencyList.fromMap(res.data);
}
/// List Languages
@@ -134,13 +169,19 @@ class Locale extends Service {
const String path = '/locale/languages';
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.LanguageList.fromMap(res.data);
}
}
+68 -37
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Storage service allows you to manage your project files.
class Storage extends Service {
Storage(Client client): super(client);
@@ -16,19 +15,25 @@ class Storage extends Service {
final Map<String, dynamic> params = {
'search': search,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.FileList.fromMap(res.data);
}
/// Create File
@@ -55,27 +60,24 @@ class Storage extends Service {
Future<models.File> createFile({required String bucketId, required String fileId, required InputFile file, List? read, List? write, Function(UploadProgress)? onProgress}) async {
final String path = '/storage/buckets/{bucketId}/files'.replaceAll('{bucketId}', bucketId);
final Map<String, dynamic> params = {
final Map<String, dynamic> params = {
'fileId': fileId,
'file': file,
'read': read,
'write': write,
'file': file,
'read': read,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'multipart/form-data',
'content-type': 'multipart/form-data',
};
dynamic res;
if(kIsWeb) {
params['file'] = file.file;
res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
} else {
String idParamName = '';
idParamName = 'fileId';
final paramName = 'file';
res = await chunkedUpload(
client: client,
String idParamName = '';
idParamName = 'fileId';
final paramName = 'file';
final res = await client.chunkedUpload(
path: path,
params: params,
paramName: paramName,
@@ -83,8 +85,10 @@ class Storage extends Service {
headers: headers,
onProgress: onProgress,
);
}
return models.File.fromMap(res.data);
}
/// Get File
@@ -96,14 +100,20 @@ class Storage extends Service {
final String path = '/storage/buckets/{bucketId}/files/{fileId}'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.File.fromMap(res.data);
}
/// Update File
@@ -115,16 +125,22 @@ class Storage extends Service {
final String path = '/storage/buckets/{bucketId}/files/{fileId}'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId);
final Map<String, dynamic> params = {
'read': read,
'write': write,
'write': write,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.File.fromMap(res.data);
}
/// Delete File
@@ -136,14 +152,20 @@ class Storage extends Service {
final String path = '/storage/buckets/{bucketId}/files/{fileId}'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
/// Get File for Download
@@ -156,11 +178,14 @@ class Storage extends Service {
final String path = '/storage/buckets/{bucketId}/files/{fileId}/download'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId);
final Map<String, dynamic> params = {
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get File Preview
@@ -176,21 +201,24 @@ class Storage extends Service {
final Map<String, dynamic> params = {
'width': width,
'height': height,
'gravity': gravity,
'quality': quality,
'borderWidth': borderWidth,
'borderColor': borderColor,
'borderRadius': borderRadius,
'opacity': opacity,
'rotation': rotation,
'background': background,
'output': output,
'height': height,
'gravity': gravity,
'quality': quality,
'borderWidth': borderWidth,
'borderColor': borderColor,
'borderRadius': borderRadius,
'opacity': opacity,
'rotation': rotation,
'background': background,
'output': output,
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
/// Get File for View
@@ -203,10 +231,13 @@ class Storage extends Service {
final String path = '/storage/buckets/{bucketId}/files/{fileId}/view'.replaceAll('{bucketId}', bucketId).replaceAll('{fileId}', fileId);
final Map<String, dynamic> params = {
'project': client.config['project'],
};
final res = await client.call(HttpMethod.get, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
}
}
+93 -28
View File
@@ -1,6 +1,5 @@
part of appwrite;
/// The Teams service allows you to group users of your project and to enable
/// them to share read and write access to your project resources
class Teams extends Service {
@@ -19,19 +18,25 @@ class Teams extends Service {
final Map<String, dynamic> params = {
'search': search,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.TeamList.fromMap(res.data);
}
/// Create Team
@@ -44,17 +49,23 @@ class Teams extends Service {
const String path = '/teams';
final Map<String, dynamic> params = {
'teamId': teamId,
'name': name,
'roles': roles,
'name': name,
'roles': roles,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Team.fromMap(res.data);
}
/// Get Team
@@ -65,14 +76,20 @@ class Teams extends Service {
final String path = '/teams/{teamId}'.replaceAll('{teamId}', teamId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.Team.fromMap(res.data);
}
/// Update Team
@@ -84,15 +101,21 @@ class Teams extends Service {
final String path = '/teams/{teamId}'.replaceAll('{teamId}', teamId);
final Map<String, dynamic> params = {
'name': name,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put, path: path, params: params, headers: headers);
return models.Team.fromMap(res.data);
}
/// Delete Team
@@ -104,14 +127,20 @@ class Teams extends Service {
final String path = '/teams/{teamId}'.replaceAll('{teamId}', teamId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
/// Get Team Memberships
@@ -124,19 +153,25 @@ class Teams extends Service {
final Map<String, dynamic> params = {
'search': search,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
'limit': limit,
'offset': offset,
'cursor': cursor,
'cursorDirection': cursorDirection,
'orderType': orderType,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.MembershipList.fromMap(res.data);
}
/// Create Team Membership
@@ -161,18 +196,24 @@ class Teams extends Service {
final String path = '/teams/{teamId}/memberships'.replaceAll('{teamId}', teamId);
final Map<String, dynamic> params = {
'email': email,
'roles': roles,
'url': url,
'name': name,
'roles': roles,
'url': url,
'name': name,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post, path: path, params: params, headers: headers);
return models.Membership.fromMap(res.data);
}
/// Get Team Membership
@@ -184,14 +225,20 @@ class Teams extends Service {
final String path = '/teams/{teamId}/memberships/{membershipId}'.replaceAll('{teamId}', teamId).replaceAll('{membershipId}', membershipId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.get, path: path, params: params, headers: headers);
return models.MembershipList.fromMap(res.data);
}
/// Update Membership Roles
@@ -204,15 +251,21 @@ class Teams extends Service {
final String path = '/teams/{teamId}/memberships/{membershipId}'.replaceAll('{teamId}', teamId).replaceAll('{membershipId}', membershipId);
final Map<String, dynamic> params = {
'roles': roles,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.Membership.fromMap(res.data);
}
/// Delete Team Membership
@@ -225,14 +278,20 @@ class Teams extends Service {
final String path = '/teams/{teamId}/memberships/{membershipId}'.replaceAll('{teamId}', teamId).replaceAll('{membershipId}', membershipId);
final Map<String, dynamic> params = {
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete, path: path, params: params, headers: headers);
return res.data;
}
/// Update Team Membership Status
@@ -249,15 +308,21 @@ class Teams extends Service {
final String path = '/teams/{teamId}/memberships/{membershipId}/status'.replaceAll('{teamId}', teamId).replaceAll('{membershipId}', membershipId);
final Map<String, dynamic> params = {
'userId': userId,
'secret': secret,
'secret': secret,
};
final Map<String, String> headers = {
'content-type': 'application/json',
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch, path: path, params: params, headers: headers);
return models.Membership.fromMap(res.data);
}
}
-78
View File
@@ -1,78 +0,0 @@
import 'client.dart';
import 'dart:io' as io;
import 'enums.dart';
import 'package:http/http.dart' as http;
import 'response.dart';
import 'dart:math';
import 'input_file.dart';
import 'exception.dart';
import 'upload_progress.dart';
Future<Response> chunkedUpload({
required Client client,
required String path,
required Map<String, dynamic> params,
required String paramName,
required String idParamName,
required Map<String, String> headers,
Function(UploadProgress)? onProgress,
}) async {
InputFile file = params[paramName];
if (file.path == null) {
throw AppwriteException("File path must be provided for dart:io");
}
io.File iofile = io.File(file.path!);
final size = await iofile.length();
late Response res;
if (size <= Client.CHUNK_SIZE) {
params[paramName] = await http.MultipartFile.fromPath(paramName, file.path!, filename: file.filename);
return client.call(
HttpMethod.post,
path: path,
params: params,
headers: headers,
);
}
var offset = 0;
if(idParamName.isNotEmpty && params[idParamName] != 'unique()') {
//make a request to check if a file already exists
try {
res = await client.call(
HttpMethod.get,
path: path + '/' + params[idParamName],
headers: headers,
);
final int chunksUploaded = res.data['chunksUploaded'] as int;
offset = min(size, chunksUploaded * Client.CHUNK_SIZE);
} on AppwriteException catch (_) {}
}
// read chunk and upload each chunk
final raf = iofile.openSync(mode: io.FileMode.read);
while (offset < size) {
raf.setPositionSync(offset);
final chunk = raf.readSync(Client.CHUNK_SIZE);
params[paramName] =
http.MultipartFile.fromBytes(paramName, chunk, filename: file.filename);
headers['content-range'] =
'bytes $offset-${min<int>(((offset + Client.CHUNK_SIZE) - 1), size)}/$size';
res = await client.call(HttpMethod.post,
path: path, headers: headers, params: params);
offset += Client.CHUNK_SIZE;
if(offset < size) {
headers['x-appwrite-id'] = res.data['\$id'];
}
final progress = UploadProgress(
$id: res.data['\$id'] ?? '',
progress: min(offset-1,size)/size * 100,
sizeUploaded: min(offset-1,size),
chunksTotal: res.data['chunksTotal'] ?? 0,
chunksUploaded: res.data['chunksUploaded'] ?? 0,
);
onProgress?.call(progress);
}
raf.close();
return res;
}
-14
View File
@@ -1,14 +0,0 @@
import 'response.dart';
import 'client.dart';
import 'upload_progress.dart';
Future<Response> chunkedUpload({
required Client client,
required String path,
required Map<String, dynamic> params,
required String paramName,
required String idParamName,
required Map<String, String> headers,
Function(UploadProgress)? onProgress,
}) =>
throw UnsupportedError('Cannot redirect to url without dart:html');
+10
View File
@@ -3,6 +3,7 @@ import 'client_stub.dart'
if (dart.library.html) 'client_browser.dart'
if (dart.library.io) 'client_io.dart';
import 'response.dart';
import 'upload_progress.dart';
abstract class Client {
static const int CHUNK_SIZE = 5*1024*1024;
@@ -20,6 +21,15 @@ abstract class Client {
Future webAuth(Uri url);
Future<Response> chunkedUpload({
required String path,
required Map<String, dynamic> params,
required String paramName,
required String idParamName,
required Map<String, String> headers,
Function(UploadProgress)? onProgress,
});
Client setSelfSigned({bool status = true});
Client setEndpoint(String endPoint);
+73 -3
View File
@@ -1,4 +1,5 @@
import 'dart:html' as html;
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter_web_auth/flutter_web_auth.dart';
import 'package:http/http.dart' as http;
@@ -7,7 +8,8 @@ import 'client_mixin.dart';
import 'enums.dart';
import 'exception.dart';
import 'client_base.dart';
import 'input_file.dart';
import 'upload_progress.dart';
import 'response.dart';
ClientBase createClient({
@@ -17,6 +19,7 @@ ClientBase createClient({
ClientBrowser(endPoint: endPoint, selfSigned: selfSigned);
class ClientBrowser extends ClientBase with ClientMixin {
static const int CHUNK_SIZE = 5*1024*1024;
String _endPoint;
Map<String, String>? _headers;
@override
@@ -37,8 +40,8 @@ class ClientBrowser extends ClientBase with ClientMixin {
.replaceFirst('http://', 'ws://');
_headers = {
'content-type': 'application/json',
'x-sdk-version': 'appwrite:flutter:5.0.0',
'X-Appwrite-Response-Format' : '0.14.0',
'x-sdk-version': 'appwrite:flutter:6.0.0',
'X-Appwrite-Response-Format' : '0.15.0',
};
config = {};
@@ -107,6 +110,73 @@ class ClientBrowser extends ClientBase with ClientMixin {
_httpClient.withCredentials = true;
}
@override
Future<Response> chunkedUpload({
required String path,
required Map<String, dynamic> params,
required String paramName,
required String idParamName,
required Map<String, String> headers,
Function(UploadProgress)? onProgress,
}) async {
InputFile file = params[paramName];
if (file.bytes == null) {
throw AppwriteException("File bytes must be provided for Flutter web");
}
int size = file.bytes!.length;
late Response res;
if (size <= CHUNK_SIZE) {
params[paramName] = http.MultipartFile.fromBytes(paramName, file.bytes!, filename: file.filename);
return call(
HttpMethod.post,
path: path,
params: params,
headers: headers,
);
}
var offset = 0;
if (idParamName.isNotEmpty && params[idParamName] != 'unique()') {
//make a request to check if a file already exists
try {
res = await call(
HttpMethod.get,
path: path + '/' + params[idParamName],
headers: headers,
);
final int chunksUploaded = res.data['chunksUploaded'] as int;
offset = min(size, chunksUploaded * CHUNK_SIZE);
} on AppwriteException catch (_) {}
}
while (offset < size) {
var chunk;
final end = min(offset + CHUNK_SIZE-1, size-1);
chunk = file.bytes!.getRange(offset, end).toList();
params[paramName] =
http.MultipartFile.fromBytes(paramName, chunk, filename: file.filename);
headers['content-range'] =
'bytes $offset-${min<int>(((offset + CHUNK_SIZE) - 1), size)}/$size';
res = await call(HttpMethod.post,
path: path, headers: headers, params: params);
offset += CHUNK_SIZE;
if (offset < size) {
headers['x-appwrite-id'] = res.data['\$id'];
}
final progress = UploadProgress(
$id: res.data['\$id'] ?? '',
progress: min(offset - 1, size) / size * 100,
sizeUploaded: min(offset - 1, size),
chunksTotal: res.data['chunksTotal'] ?? 0,
chunksUploaded: res.data['chunksUploaded'] ?? 0,
);
onProgress?.call(progress);
}
return res;
}
@override
Future<Response> call(
HttpMethod method, {
+102 -2
View File
@@ -1,4 +1,5 @@
import 'dart:io';
import 'dart:math';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:http/http.dart' as http;
@@ -14,6 +15,8 @@ import 'exception.dart';
import 'interceptor.dart';
import 'response.dart';
import 'package:flutter/foundation.dart';
import 'input_file.dart';
import 'upload_progress.dart';
ClientBase createClient({
required String endPoint,
@@ -25,6 +28,7 @@ ClientBase createClient({
);
class ClientIO extends ClientBase with ClientMixin {
static const int CHUNK_SIZE = 5*1024*1024;
String _endPoint;
Map<String, String>? _headers;
@override
@@ -55,8 +59,8 @@ class ClientIO extends ClientBase with ClientMixin {
.replaceFirst('http://', 'ws://');
_headers = {
'content-type': 'application/json',
'x-sdk-version': 'appwrite:flutter:5.0.0',
'X-Appwrite-Response-Format' : '0.14.0',
'x-sdk-version': 'appwrite:flutter:6.0.0',
'X-Appwrite-Response-Format' : '0.15.0',
};
config = {};
@@ -202,6 +206,102 @@ class ClientIO extends ClientBase with ClientMixin {
return response;
}
@override
Future<Response> chunkedUpload({
required String path,
required Map<String, dynamic> params,
required String paramName,
required String idParamName,
required Map<String, String> headers,
Function(UploadProgress)? onProgress,
}) async {
InputFile file = params[paramName];
if (file.path == null && file.bytes == null) {
throw AppwriteException("File path or bytes must be provided");
}
int size = 0;
if (file.bytes != null) {
size = file.bytes!.length;
}
File? iofile;
if (file.path != null) {
iofile = File(file.path!);
size = await iofile.length();
}
late Response res;
if (size <= CHUNK_SIZE) {
if (file.path != null) {
params[paramName] = await http.MultipartFile.fromPath(
paramName, file.path!,
filename: file.filename);
} else {
params[paramName] = http.MultipartFile.fromBytes(paramName, file.bytes!,
filename: file.filename);
}
return call(
HttpMethod.post,
path: path,
params: params,
headers: headers,
);
}
var offset = 0;
if (idParamName.isNotEmpty && params[idParamName] != 'unique()') {
//make a request to check if a file already exists
try {
res = await call(
HttpMethod.get,
path: path + '/' + params[idParamName],
headers: headers,
);
final int chunksUploaded = res.data['chunksUploaded'] as int;
offset = min(size, chunksUploaded * CHUNK_SIZE);
} on AppwriteException catch (_) {}
}
RandomAccessFile? raf;
// read chunk and upload each chunk
if (iofile != null) {
raf = await iofile.open(mode: FileMode.read);
}
while (offset < size) {
var chunk;
if (file.bytes != null) {
final end = min(offset + CHUNK_SIZE-1, size-1);
chunk = file.bytes!.getRange(offset, end).toList();
} else {
raf!.setPositionSync(offset);
chunk = raf.readSync(CHUNK_SIZE);
}
params[paramName] =
http.MultipartFile.fromBytes(paramName, chunk, filename: file.filename);
headers['content-range'] =
'bytes $offset-${min<int>(((offset + CHUNK_SIZE) - 1), size)}/$size';
res = await call(HttpMethod.post,
path: path, headers: headers, params: params);
offset += CHUNK_SIZE;
if (offset < size) {
headers['x-appwrite-id'] = res.data['\$id'];
}
final progress = UploadProgress(
$id: res.data['\$id'] ?? '',
progress: min(offset - 1, size) / size * 100,
sizeUploaded: min(offset - 1, size),
chunksTotal: res.data['chunksTotal'] ?? 0,
chunksUploaded: res.data['chunksUploaded'] ?? 0,
);
onProgress?.call(progress);
}
raf?.close();
return res;
}
@override
Future webAuth(Uri url) {
return FlutterWebAuth.authenticate(
+14 -4
View File
@@ -1,9 +1,19 @@
import 'package:http/http.dart' show MultipartFile;
import 'package:flutter/foundation.dart';
import 'exception.dart';
class InputFile {
final MultipartFile? file;
final String? path;
late final String? path;
late final List<int>? bytes;
final String? filename;
final String? contentType;
InputFile({this.file, this.path, this.filename});
/// Provide a file, use `path` for IO platforms
/// and provide `bytes` for web platform
InputFile({this.path, this.filename, this.contentType, this.bytes}) {
if (kIsWeb && bytes == null) {
throw AppwriteException('On web `bytes` is required');
} else if(!kIsWeb && path == null && bytes == null) {
throw AppwriteException('On IO platforms one of `path` or `bytes` is required');
}
}
}
+10
View File
@@ -6,6 +6,10 @@ class Document implements Model {
final String $id;
/// Collection ID.
final String $collection;
/// Document creation date in Unix timestamp.
final int $createdAt;
/// Document update date in Unix timestamp.
final int $updatedAt;
/// Document read permissions.
final List $read;
/// Document write permissions.
@@ -15,6 +19,8 @@ class Document implements Model {
Document({
required this.$id,
required this.$collection,
required this.$createdAt,
required this.$updatedAt,
required this.$read,
required this.$write,
required this.data,
@@ -24,6 +30,8 @@ class Document implements Model {
return Document(
$id: map['\$id'].toString(),
$collection: map['\$collection'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
$read: map['\$read'],
$write: map['\$write'],
data: map,
@@ -35,6 +43,8 @@ class Document implements Model {
return {
"\$id": $id,
"\$collection": $collection,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"\$read": $read,
"\$write": $write,
"data": data,
+10 -5
View File
@@ -4,12 +4,14 @@ part of appwrite.models;
class Execution implements Model {
/// Execution ID.
final String $id;
/// Execution creation date in Unix timestamp.
final int $createdAt;
/// Execution update date in Unix timestamp.
final int $updatedAt;
/// Execution read permissions.
final List $read;
/// Function ID.
final String functionId;
/// The execution creation date in Unix timestamp.
final int dateCreated;
/// The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.
final String trigger;
/// The status of the function execution. Possible values can be: `waiting`, `processing`, `completed`, or `failed`.
@@ -25,9 +27,10 @@ class Execution implements Model {
Execution({
required this.$id,
required this.$createdAt,
required this.$updatedAt,
required this.$read,
required this.functionId,
required this.dateCreated,
required this.trigger,
required this.status,
required this.statusCode,
@@ -39,9 +42,10 @@ class Execution implements Model {
factory Execution.fromMap(Map<String, dynamic> map) {
return Execution(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
$read: map['\$read'],
functionId: map['functionId'].toString(),
dateCreated: map['dateCreated'],
trigger: map['trigger'].toString(),
status: map['status'].toString(),
statusCode: map['statusCode'],
@@ -55,9 +59,10 @@ class Execution implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"\$read": $read,
"functionId": functionId,
"dateCreated": dateCreated,
"trigger": trigger,
"status": status,
"statusCode": statusCode,
+10 -5
View File
@@ -6,14 +6,16 @@ class File implements Model {
final String $id;
/// Bucket ID.
final String bucketId;
/// File creation date in Unix timestamp.
final int $createdAt;
/// File update date in Unix timestamp.
final int $updatedAt;
/// File read permissions.
final List $read;
/// File write permissions.
final List $write;
/// File name.
final String name;
/// File creation date in Unix timestamp.
final int dateCreated;
/// File MD5 signature.
final String signature;
/// File mime type.
@@ -28,10 +30,11 @@ class File implements Model {
File({
required this.$id,
required this.bucketId,
required this.$createdAt,
required this.$updatedAt,
required this.$read,
required this.$write,
required this.name,
required this.dateCreated,
required this.signature,
required this.mimeType,
required this.sizeOriginal,
@@ -43,10 +46,11 @@ class File implements Model {
return File(
$id: map['\$id'].toString(),
bucketId: map['bucketId'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
$read: map['\$read'],
$write: map['\$write'],
name: map['name'].toString(),
dateCreated: map['dateCreated'],
signature: map['signature'].toString(),
mimeType: map['mimeType'].toString(),
sizeOriginal: map['sizeOriginal'],
@@ -60,10 +64,11 @@ class File implements Model {
return {
"\$id": $id,
"bucketId": bucketId,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"\$read": $read,
"\$write": $write,
"name": name,
"dateCreated": dateCreated,
"signature": signature,
"mimeType": mimeType,
"sizeOriginal": sizeOriginal,
+10
View File
@@ -4,6 +4,10 @@ part of appwrite.models;
class Membership implements Model {
/// Membership ID.
final String $id;
/// Membership creation date in Unix timestamp.
final int $createdAt;
/// Membership update date in Unix timestamp.
final int $updatedAt;
/// User ID.
final String userId;
/// User name.
@@ -25,6 +29,8 @@ class Membership implements Model {
Membership({
required this.$id,
required this.$createdAt,
required this.$updatedAt,
required this.userId,
required this.userName,
required this.userEmail,
@@ -39,6 +45,8 @@ class Membership implements Model {
factory Membership.fromMap(Map<String, dynamic> map) {
return Membership(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
userId: map['userId'].toString(),
userName: map['userName'].toString(),
userEmail: map['userEmail'].toString(),
@@ -55,6 +63,8 @@ class Membership implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"userId": userId,
"userName": userName,
"userEmail": userEmail,
+5
View File
@@ -4,6 +4,8 @@ part of appwrite.models;
class Session implements Model {
/// Session ID.
final String $id;
/// Session creation date in Unix timestamp.
final int $createdAt;
/// User ID.
final String userId;
/// Session expiration date in Unix timestamp.
@@ -53,6 +55,7 @@ class Session implements Model {
Session({
required this.$id,
required this.$createdAt,
required this.userId,
required this.expire,
required this.provider,
@@ -81,6 +84,7 @@ class Session implements Model {
factory Session.fromMap(Map<String, dynamic> map) {
return Session(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
userId: map['userId'].toString(),
expire: map['expire'],
provider: map['provider'].toString(),
@@ -111,6 +115,7 @@ class Session implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"userId": userId,
"expire": expire,
"provider": provider,
+10 -5
View File
@@ -4,25 +4,29 @@ part of appwrite.models;
class Team implements Model {
/// Team ID.
final String $id;
/// Team creation date in Unix timestamp.
final int $createdAt;
/// Team update date in Unix timestamp.
final int $updatedAt;
/// Team name.
final String name;
/// Team creation date in Unix timestamp.
final int dateCreated;
/// Total number of team members.
final int total;
Team({
required this.$id,
required this.$createdAt,
required this.$updatedAt,
required this.name,
required this.dateCreated,
required this.total,
});
factory Team.fromMap(Map<String, dynamic> map) {
return Team(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
name: map['name'].toString(),
dateCreated: map['dateCreated'],
total: map['total'],
);
}
@@ -31,8 +35,9 @@ class Team implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"name": name,
"dateCreated": dateCreated,
"total": total,
};
}
+5
View File
@@ -4,6 +4,8 @@ part of appwrite.models;
class Token implements Model {
/// Token ID.
final String $id;
/// Token creation date in Unix timestamp.
final int $createdAt;
/// User ID.
final String userId;
/// Token secret key. This will return an empty string unless the response is returned using an API key or as part of a webhook payload.
@@ -13,6 +15,7 @@ class Token implements Model {
Token({
required this.$id,
required this.$createdAt,
required this.userId,
required this.secret,
required this.expire,
@@ -21,6 +24,7 @@ class Token implements Model {
factory Token.fromMap(Map<String, dynamic> map) {
return Token(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
userId: map['userId'].toString(),
secret: map['secret'].toString(),
expire: map['expire'],
@@ -31,6 +35,7 @@ class Token implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"userId": userId,
"secret": secret,
"expire": expire,
+20
View File
@@ -4,6 +4,10 @@ part of appwrite.models;
class User implements Model {
/// User ID.
final String $id;
/// User creation date in Unix timestamp.
final int $createdAt;
/// User update date in Unix timestamp.
final int $updatedAt;
/// User name.
final String name;
/// User registration date in Unix timestamp.
@@ -14,31 +18,43 @@ class User implements Model {
final int passwordUpdate;
/// User email address.
final String email;
/// User phone number in E.164 format.
final String phone;
/// Email verification status.
final bool emailVerification;
/// Phone verification status.
final bool phoneVerification;
/// User preferences as a key-value object
final Preferences prefs;
User({
required this.$id,
required this.$createdAt,
required this.$updatedAt,
required this.name,
required this.registration,
required this.status,
required this.passwordUpdate,
required this.email,
required this.phone,
required this.emailVerification,
required this.phoneVerification,
required this.prefs,
});
factory User.fromMap(Map<String, dynamic> map) {
return User(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'],
$updatedAt: map['\$updatedAt'],
name: map['name'].toString(),
registration: map['registration'],
status: map['status'],
passwordUpdate: map['passwordUpdate'],
email: map['email'].toString(),
phone: map['phone'].toString(),
emailVerification: map['emailVerification'],
phoneVerification: map['phoneVerification'],
prefs: Preferences.fromMap(map['prefs']),
);
}
@@ -47,12 +63,16 @@ class User implements Model {
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"name": name,
"registration": registration,
"status": status,
"passwordUpdate": passwordUpdate,
"email": email,
"phone": phone,
"emailVerification": emailVerification,
"phoneVerification": phoneVerification,
"prefs": prefs.toMap(),
};
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: appwrite
version: 5.0.0
version: 6.0.0
description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API
homepage: https://appwrite.io
repository: https://github.com/appwrite/sdk-for-flutter