Merge pull request #109 from appwrite/dev

This commit is contained in:
Jake Barnby
2026-03-26 06:06:02 +00:00
committed by GitHub
64 changed files with 1344 additions and 225 deletions
+19
View File
@@ -1,5 +1,24 @@
# Change Log
## 22.0.0
* [BREAKING] Changed `$sequence` type from `int` to `String` for `Row` and `Document` models
* [BREAKING] Renamed `IndexType` enum: split into `DatabasesIndexType` (for Databases) and `TablesDBIndexType` (for TablesDB)
* [BREAKING] Replaced `specification` parameter with `buildSpecification` and `runtimeSpecification` in `Functions.create()`, `Functions.update()`, `Sites.create()`, `Sites.update()`
* Added new `Project` service with full CRUD for project-level environment variables
* Added new `Webhooks` service with full CRUD for project webhooks (including `updateSignature`)
* Added `Webhook` and `WebhookList` models
* Added `Users.updateImpersonator()` method for enabling/disabling user impersonation
* Added impersonation support: `setImpersonateUserId()`, `setImpersonateUserEmail()`, `setImpersonateUserPhone()` on `Client`
* Added `impersonator` and `impersonatorUserId` optional fields to `User` model
* Added `deploymentRetention` parameter to Functions and Sites create/update
* Added `startCommand` parameter to Sites create/update
* Added `Documentsdb`, `Vectorsdb` values to `BackupServices` and `DatabaseType` enums
* Added `WebhooksRead`, `WebhooksWrite`, `ProjectRead`, `ProjectWrite` scopes
* Removed `getQueueBillingProjectAggregation`, `getQueueBillingTeamAggregation`, `getQueuePriorityBuilds`, `getQueueRegionManager`, `getQueueThreats` from `Health` service
* Updated `Log` model field descriptions to clarify impersonation behavior
* Updated `X-Appwrite-Response-Format` header to `1.9.0`
## 21.3.0
* Added `ttl` parameter to listDocuments
+3 -3
View File
@@ -2,12 +2,12 @@
[![pub package](https://img.shields.io/pub/v/dart_appwrite.svg?style=flat-square)](https://pub.dartlang.org/packages/dart_appwrite)
![License](https://img.shields.io/github/license/appwrite/sdk-for-dart.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.8.x-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.9.x-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 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-dart/releases).**
**This SDK is compatible with Appwrite server version 1.9.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-dart/releases).**
> This is the Dart SDK for integrating with Appwrite from your Dart server-side code. If you're looking for the Flutter SDK you should check [appwrite/sdk-for-flutter](https://github.com/appwrite/sdk-for-flutter)
@@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file:
```yml
dependencies:
dart_appwrite: ^21.3.0
dart_appwrite: ^22.0.0
```
You can install packages from the command line:
+1 -1
View File
@@ -13,7 +13,7 @@ Index result = await databases.createIndex(
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
type: enums.IndexType.key,
type: enums.DatabasesIndexType.key,
attributes: [],
orders: [enums.OrderBy.asc], // (optional)
lengths: [], // (optional)
+3 -1
View File
@@ -27,6 +27,8 @@ Func result = await functions.create(
providerBranch: '<PROVIDER_BRANCH>', // (optional)
providerSilentMode: false, // (optional)
providerRootDirectory: '<PROVIDER_ROOT_DIRECTORY>', // (optional)
specification: '', // (optional)
buildSpecification: '', // (optional)
runtimeSpecification: '', // (optional)
deploymentRetention: 0, // (optional)
);
```
+3 -1
View File
@@ -27,6 +27,8 @@ Func result = await functions.update(
providerBranch: '<PROVIDER_BRANCH>', // (optional)
providerSilentMode: false, // (optional)
providerRootDirectory: '<PROVIDER_ROOT_DIRECTORY>', // (optional)
specification: '', // (optional)
buildSpecification: '', // (optional)
runtimeSpecification: '', // (optional)
deploymentRetention: 0, // (optional)
);
```
+17
View File
@@ -0,0 +1,17 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Project project = Project(client);
Variable result = await project.createVariable(
variableId: '<VARIABLE_ID>',
key: '<KEY>',
value: '<VALUE>',
secret: false, // (optional)
);
```
+14
View File
@@ -0,0 +1,14 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Project project = Project(client);
await project.deleteVariable(
variableId: '<VARIABLE_ID>',
);
```
+14
View File
@@ -0,0 +1,14 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Project project = Project(client);
Variable result = await project.getVariable(
variableId: '<VARIABLE_ID>',
);
```
+15
View File
@@ -0,0 +1,15 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Project project = Project(client);
VariableList result = await project.listVariables(
queries: [], // (optional)
total: false, // (optional)
);
```
+17
View File
@@ -0,0 +1,17 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Project project = Project(client);
Variable result = await project.updateVariable(
variableId: '<VARIABLE_ID>',
key: '<KEY>', // (optional)
value: '<VALUE>', // (optional)
secret: false, // (optional)
);
```
+4 -1
View File
@@ -19,6 +19,7 @@ Site result = await sites.create(
timeout: 1, // (optional)
installCommand: '<INSTALL_COMMAND>', // (optional)
buildCommand: '<BUILD_COMMAND>', // (optional)
startCommand: '<START_COMMAND>', // (optional)
outputDirectory: '<OUTPUT_DIRECTORY>', // (optional)
adapter: enums.Adapter.static, // (optional)
installationId: '<INSTALLATION_ID>', // (optional)
@@ -27,6 +28,8 @@ Site result = await sites.create(
providerBranch: '<PROVIDER_BRANCH>', // (optional)
providerSilentMode: false, // (optional)
providerRootDirectory: '<PROVIDER_ROOT_DIRECTORY>', // (optional)
specification: '', // (optional)
buildSpecification: '', // (optional)
runtimeSpecification: '', // (optional)
deploymentRetention: 0, // (optional)
);
```
+4 -1
View File
@@ -18,6 +18,7 @@ Site result = await sites.update(
timeout: 1, // (optional)
installCommand: '<INSTALL_COMMAND>', // (optional)
buildCommand: '<BUILD_COMMAND>', // (optional)
startCommand: '<START_COMMAND>', // (optional)
outputDirectory: '<OUTPUT_DIRECTORY>', // (optional)
buildRuntime: enums.BuildRuntime.node145, // (optional)
adapter: enums.Adapter.static, // (optional)
@@ -27,6 +28,8 @@ Site result = await sites.update(
providerBranch: '<PROVIDER_BRANCH>', // (optional)
providerSilentMode: false, // (optional)
providerRootDirectory: '<PROVIDER_ROOT_DIRECTORY>', // (optional)
specification: '', // (optional)
buildSpecification: '', // (optional)
runtimeSpecification: '', // (optional)
deploymentRetention: 0, // (optional)
);
```
+1 -1
View File
@@ -13,7 +13,7 @@ ColumnIndex result = await tablesDB.createIndex(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
key: '',
type: enums.IndexType.key,
type: enums.TablesDBIndexType.key,
columns: [],
orders: [enums.OrderBy.asc], // (optional)
lengths: [], // (optional)
@@ -0,0 +1,15 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Users users = Users(client);
User result = await users.updateImpersonator(
userId: '<USER_ID>',
impersonator: false,
);
```
+21
View File
@@ -0,0 +1,21 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
Webhook result = await webhooks.create(
webhookId: '<WEBHOOK_ID>',
url: '',
name: '<NAME>',
events: [],
enabled: false, // (optional)
security: false, // (optional)
httpUser: '<HTTP_USER>', // (optional)
httpPass: '<HTTP_PASS>', // (optional)
);
```
+14
View File
@@ -0,0 +1,14 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
await webhooks.delete(
webhookId: '<WEBHOOK_ID>',
);
```
+14
View File
@@ -0,0 +1,14 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
Webhook result = await webhooks.get(
webhookId: '<WEBHOOK_ID>',
);
```
+15
View File
@@ -0,0 +1,15 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
WebhookList result = await webhooks.list(
queries: [], // (optional)
total: false, // (optional)
);
```
@@ -0,0 +1,14 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
Webhook result = await webhooks.updateSignature(
webhookId: '<WEBHOOK_ID>',
);
```
+21
View File
@@ -0,0 +1,21 @@
```dart
import 'package:dart_appwrite/dart_appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>') // Your project ID
.setKey('<YOUR_API_KEY>'); // Your secret API key
Webhooks webhooks = Webhooks(client);
Webhook result = await webhooks.update(
webhookId: '<WEBHOOK_ID>',
name: '<NAME>',
url: '',
events: [],
enabled: false, // (optional)
security: false, // (optional)
httpUser: '<HTTP_USER>', // (optional)
httpPass: '<HTTP_PASS>', // (optional)
);
```
+3 -1
View File
@@ -1,6 +1,6 @@
/// Appwrite Dart SDK
///
/// This SDK is compatible with Appwrite server version 1.8.x.
/// This SDK is compatible with Appwrite server version 1.9.x.
/// For older versions, please check
/// [previous releases](https://github.com/appwrite/sdk-for-dart/releases).
library dart_appwrite;
@@ -38,9 +38,11 @@ part 'services/graphql.dart';
part 'services/health.dart';
part 'services/locale.dart';
part 'services/messaging.dart';
part 'services/project.dart';
part 'services/sites.dart';
part 'services/storage.dart';
part 'services/tables_db.dart';
part 'services/teams.dart';
part 'services/tokens.dart';
part 'services/users.dart';
part 'services/webhooks.dart';
+2 -1
View File
@@ -14,7 +14,7 @@ part 'src/enums/image_format.dart';
part 'src/enums/backup_services.dart';
part 'src/enums/relationship_type.dart';
part 'src/enums/relation_mutate.dart';
part 'src/enums/index_type.dart';
part 'src/enums/databases_index_type.dart';
part 'src/enums/order_by.dart';
part 'src/enums/runtime.dart';
part 'src/enums/scopes.dart';
@@ -30,6 +30,7 @@ part 'src/enums/build_runtime.dart';
part 'src/enums/adapter.dart';
part 'src/enums/compression.dart';
part 'src/enums/image_gravity.dart';
part 'src/enums/tables_db_index_type.dart';
part 'src/enums/password_hash.dart';
part 'src/enums/messaging_provider_type.dart';
part 'src/enums/database_type.dart';
+2
View File
@@ -26,6 +26,7 @@ part 'src/models/framework_list.dart';
part 'src/models/runtime_list.dart';
part 'src/models/deployment_list.dart';
part 'src/models/execution_list.dart';
part 'src/models/webhook_list.dart';
part 'src/models/country_list.dart';
part 'src/models/continent_list.dart';
part 'src/models/language_list.dart';
@@ -112,6 +113,7 @@ part 'src/models/framework.dart';
part 'src/models/framework_adapter.dart';
part 'src/models/deployment.dart';
part 'src/models/execution.dart';
part 'src/models/webhook.dart';
part 'src/models/variable.dart';
part 'src/models/country.dart';
part 'src/models/continent.dart';
+1 -1
View File
@@ -2002,7 +2002,7 @@ class Databases extends Service {
{required String databaseId,
required String collectionId,
required String key,
required enums.IndexType type,
required enums.DatabasesIndexType type,
required List<String> attributes,
List<enums.OrderBy>? orders,
List<int>? lengths}) async {
+16 -4
View File
@@ -47,7 +47,9 @@ class Functions extends Service {
String? providerBranch,
bool? providerSilentMode,
String? providerRootDirectory,
String? specification}) async {
String? buildSpecification,
String? runtimeSpecification,
int? deploymentRetention}) async {
final String apiPath = '/functions';
final Map<String, dynamic> apiParams = {
@@ -70,7 +72,11 @@ class Functions extends Service {
if (providerSilentMode != null) 'providerSilentMode': providerSilentMode,
if (providerRootDirectory != null)
'providerRootDirectory': providerRootDirectory,
if (specification != null) 'specification': specification,
if (buildSpecification != null) 'buildSpecification': buildSpecification,
if (runtimeSpecification != null)
'runtimeSpecification': runtimeSpecification,
if (deploymentRetention != null)
'deploymentRetention': deploymentRetention,
};
final Map<String, String> apiHeaders = {
@@ -145,7 +151,9 @@ class Functions extends Service {
String? providerBranch,
bool? providerSilentMode,
String? providerRootDirectory,
String? specification}) async {
String? buildSpecification,
String? runtimeSpecification,
int? deploymentRetention}) async {
final String apiPath =
'/functions/{functionId}'.replaceAll('{functionId}', functionId);
@@ -167,7 +175,11 @@ class Functions extends Service {
if (providerSilentMode != null) 'providerSilentMode': providerSilentMode,
if (providerRootDirectory != null)
'providerRootDirectory': providerRootDirectory,
if (specification != null) 'specification': specification,
if (buildSpecification != null) 'buildSpecification': buildSpecification,
if (runtimeSpecification != null)
'runtimeSpecification': runtimeSpecification,
if (deploymentRetention != null)
'deploymentRetention': deploymentRetention,
};
final Map<String, String> apiHeaders = {
-82
View File
@@ -129,40 +129,6 @@ class Health extends Service {
return models.HealthQueue.fromMap(res.data);
}
/// Get billing project aggregation queue.
Future<models.HealthQueue> getQueueBillingProjectAggregation(
{int? threshold}) async {
final String apiPath = '/health/queue/billing-project-aggregation';
final Map<String, dynamic> apiParams = {
if (threshold != null) 'threshold': threshold,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.HealthQueue.fromMap(res.data);
}
/// Get billing team aggregation queue.
Future<models.HealthQueue> getQueueBillingTeamAggregation(
{int? threshold}) async {
final String apiPath = '/health/queue/billing-team-aggregation';
final Map<String, dynamic> apiParams = {
if (threshold != null) 'threshold': threshold,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.HealthQueue.fromMap(res.data);
}
/// Get the number of builds that are waiting to be processed in the Appwrite
/// internal queue server.
Future<models.HealthQueue> getQueueBuilds({int? threshold}) async {
@@ -180,22 +146,6 @@ class Health extends Service {
return models.HealthQueue.fromMap(res.data);
}
/// Get the priority builds queue size.
Future<models.HealthQueue> getQueuePriorityBuilds({int? threshold}) async {
final String apiPath = '/health/queue/builds-priority';
final Map<String, dynamic> apiParams = {
if (threshold != null) 'threshold': threshold,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.HealthQueue.fromMap(res.data);
}
/// Get the number of certificates that are waiting to be issued against
/// [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue
/// server.
@@ -354,22 +304,6 @@ class Health extends Service {
return models.HealthQueue.fromMap(res.data);
}
/// Get region manager queue.
Future<models.HealthQueue> getQueueRegionManager({int? threshold}) async {
final String apiPath = '/health/queue/region-manager';
final Map<String, dynamic> apiParams = {
if (threshold != null) 'threshold': threshold,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.HealthQueue.fromMap(res.data);
}
/// Get the number of metrics that are waiting to be processed in the Appwrite
/// stats resources queue.
Future<models.HealthQueue> getQueueStatsResources({int? threshold}) async {
@@ -404,22 +338,6 @@ class Health extends Service {
return models.HealthQueue.fromMap(res.data);
}
/// Get threats queue.
Future<models.HealthQueue> getQueueThreats({int? threshold}) async {
final String apiPath = '/health/queue/threats';
final Map<String, dynamic> apiParams = {
if (threshold != null) 'threshold': threshold,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.HealthQueue.fromMap(res.data);
}
/// Get the number of webhooks that are waiting to be processed in the Appwrite
/// internal queue server.
Future<models.HealthQueue> getQueueWebhooks({int? threshold}) async {
+108
View File
@@ -0,0 +1,108 @@
part of '../dart_appwrite.dart';
/// The Project service allows you to manage all the projects in your Appwrite
/// server.
class Project extends Service {
Project(super.client);
/// Get a list of all project environment variables.
Future<models.VariableList> listVariables(
{List<String>? queries, bool? total}) async {
final String apiPath = '/project/variables';
final Map<String, dynamic> apiParams = {
if (queries != null) 'queries': queries,
if (total != null) 'total': total,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.VariableList.fromMap(res.data);
}
/// Create a new project environment variable. These variables can be accessed
/// by all functions and sites in the project.
Future<models.Variable> createVariable(
{required String variableId,
required String key,
required String value,
bool? secret}) async {
final String apiPath = '/project/variables';
final Map<String, dynamic> apiParams = {
'variableId': variableId,
'key': key,
'value': value,
if (secret != null) 'secret': secret,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Variable.fromMap(res.data);
}
/// Get a variable by its unique ID.
Future<models.Variable> getVariable({required String variableId}) async {
final String apiPath = '/project/variables/{variableId}'
.replaceAll('{variableId}', variableId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Variable.fromMap(res.data);
}
/// Update variable by its unique ID.
Future<models.Variable> updateVariable(
{required String variableId,
String? key,
String? value,
bool? secret}) async {
final String apiPath = '/project/variables/{variableId}'
.replaceAll('{variableId}', variableId);
final Map<String, dynamic> apiParams = {
'key': key,
'value': value,
'secret': secret,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Variable.fromMap(res.data);
}
/// Delete a variable by its unique ID.
Future deleteVariable({required String variableId}) async {
final String apiPath = '/project/variables/{variableId}'
.replaceAll('{variableId}', variableId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete,
path: apiPath, params: apiParams, headers: apiHeaders);
return res.data;
}
}
+20 -4
View File
@@ -35,6 +35,7 @@ class Sites extends Service {
int? timeout,
String? installCommand,
String? buildCommand,
String? startCommand,
String? outputDirectory,
enums.Adapter? adapter,
String? installationId,
@@ -43,7 +44,9 @@ class Sites extends Service {
String? providerBranch,
bool? providerSilentMode,
String? providerRootDirectory,
String? specification}) async {
String? buildSpecification,
String? runtimeSpecification,
int? deploymentRetention}) async {
final String apiPath = '/sites';
final Map<String, dynamic> apiParams = {
@@ -55,6 +58,7 @@ class Sites extends Service {
if (timeout != null) 'timeout': timeout,
if (installCommand != null) 'installCommand': installCommand,
if (buildCommand != null) 'buildCommand': buildCommand,
if (startCommand != null) 'startCommand': startCommand,
if (outputDirectory != null) 'outputDirectory': outputDirectory,
'buildRuntime': buildRuntime.value,
if (adapter != null) 'adapter': adapter.value,
@@ -66,7 +70,11 @@ class Sites extends Service {
if (providerSilentMode != null) 'providerSilentMode': providerSilentMode,
if (providerRootDirectory != null)
'providerRootDirectory': providerRootDirectory,
if (specification != null) 'specification': specification,
if (buildSpecification != null) 'buildSpecification': buildSpecification,
if (runtimeSpecification != null)
'runtimeSpecification': runtimeSpecification,
if (deploymentRetention != null)
'deploymentRetention': deploymentRetention,
};
final Map<String, String> apiHeaders = {
@@ -132,6 +140,7 @@ class Sites extends Service {
int? timeout,
String? installCommand,
String? buildCommand,
String? startCommand,
String? outputDirectory,
enums.BuildRuntime? buildRuntime,
enums.Adapter? adapter,
@@ -141,7 +150,9 @@ class Sites extends Service {
String? providerBranch,
bool? providerSilentMode,
String? providerRootDirectory,
String? specification}) async {
String? buildSpecification,
String? runtimeSpecification,
int? deploymentRetention}) async {
final String apiPath = '/sites/{siteId}'.replaceAll('{siteId}', siteId);
final Map<String, dynamic> apiParams = {
@@ -152,6 +163,7 @@ class Sites extends Service {
if (timeout != null) 'timeout': timeout,
if (installCommand != null) 'installCommand': installCommand,
if (buildCommand != null) 'buildCommand': buildCommand,
if (startCommand != null) 'startCommand': startCommand,
if (outputDirectory != null) 'outputDirectory': outputDirectory,
if (buildRuntime != null) 'buildRuntime': buildRuntime.value,
if (adapter != null) 'adapter': adapter.value,
@@ -163,7 +175,11 @@ class Sites extends Service {
if (providerSilentMode != null) 'providerSilentMode': providerSilentMode,
if (providerRootDirectory != null)
'providerRootDirectory': providerRootDirectory,
if (specification != null) 'specification': specification,
if (buildSpecification != null) 'buildSpecification': buildSpecification,
if (runtimeSpecification != null)
'runtimeSpecification': runtimeSpecification,
if (deploymentRetention != null)
'deploymentRetention': deploymentRetention,
};
final Map<String, String> apiHeaders = {
+1 -1
View File
@@ -1534,7 +1534,7 @@ class TablesDB extends Service {
{required String databaseId,
required String tableId,
required String key,
required enums.IndexType type,
required enums.TablesDBIndexType type,
required List<String> columns,
List<enums.OrderBy>? orders,
List<int>? lengths}) async {
+25
View File
@@ -357,6 +357,31 @@ class Users extends Service {
return models.User.fromMap(res.data);
}
/// Enable or disable whether a user can impersonate other users. When
/// impersonation headers are used, the request runs as the target user for API
/// behavior, while internal audit logs still attribute the action to the
/// original impersonator and store the impersonated target details only in
/// internal audit payload data.
///
Future<models.User> updateImpersonator(
{required String userId, required bool impersonator}) async {
final String apiPath =
'/users/{userId}/impersonator'.replaceAll('{userId}', userId);
final Map<String, dynamic> apiParams = {
'impersonator': impersonator,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.User.fromMap(res.data);
}
/// Use this endpoint to create a JSON Web Token for user by its unique ID. You
/// can use the resulting JWT to authenticate on behalf of the user. The JWT
/// secret will become invalid if the session it uses gets deleted.
+144
View File
@@ -0,0 +1,144 @@
part of '../dart_appwrite.dart';
class Webhooks extends Service {
Webhooks(super.client);
/// Get a list of all webhooks belonging to the project. You can use the query
/// params to filter your results.
Future<models.WebhookList> list({List<String>? queries, bool? total}) async {
final String apiPath = '/webhooks';
final Map<String, dynamic> apiParams = {
if (queries != null) 'queries': queries,
if (total != null) 'total': total,
};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.WebhookList.fromMap(res.data);
}
/// Create a new webhook. Use this endpoint to configure a URL that will
/// receive events from Appwrite when specific events occur.
Future<models.Webhook> create(
{required String webhookId,
required String url,
required String name,
required List<String> events,
bool? enabled,
bool? security,
String? httpUser,
String? httpPass}) async {
final String apiPath = '/webhooks';
final Map<String, dynamic> apiParams = {
'webhookId': webhookId,
'url': url,
'name': name,
'events': events,
if (enabled != null) 'enabled': enabled,
if (security != null) 'security': security,
if (httpUser != null) 'httpUser': httpUser,
if (httpPass != null) 'httpPass': httpPass,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.post,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Webhook.fromMap(res.data);
}
/// Get a webhook by its unique ID. This endpoint returns details about a
/// specific webhook configured for a project.
Future<models.Webhook> get({required String webhookId}) async {
final String apiPath =
'/webhooks/{webhookId}'.replaceAll('{webhookId}', webhookId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {};
final res = await client.call(HttpMethod.get,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Webhook.fromMap(res.data);
}
/// Update a webhook by its unique ID. Use this endpoint to update the URL,
/// events, or status of an existing webhook.
Future<models.Webhook> update(
{required String webhookId,
required String name,
required String url,
required List<String> events,
bool? enabled,
bool? security,
String? httpUser,
String? httpPass}) async {
final String apiPath =
'/webhooks/{webhookId}'.replaceAll('{webhookId}', webhookId);
final Map<String, dynamic> apiParams = {
'name': name,
'url': url,
'events': events,
if (enabled != null) 'enabled': enabled,
if (security != null) 'security': security,
if (httpUser != null) 'httpUser': httpUser,
if (httpPass != null) 'httpPass': httpPass,
};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.put,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Webhook.fromMap(res.data);
}
/// Delete a webhook by its unique ID. Once deleted, the webhook will no longer
/// receive project events.
Future delete({required String webhookId}) async {
final String apiPath =
'/webhooks/{webhookId}'.replaceAll('{webhookId}', webhookId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.delete,
path: apiPath, params: apiParams, headers: apiHeaders);
return res.data;
}
/// Update the webhook signature key. This endpoint can be used to regenerate
/// the signature key used to sign and validate payload deliveries for a
/// specific webhook.
Future<models.Webhook> updateSignature({required String webhookId}) async {
final String apiPath =
'/webhooks/{webhookId}/signature'.replaceAll('{webhookId}', webhookId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {
'content-type': 'application/json',
};
final res = await client.call(HttpMethod.patch,
path: apiPath, params: apiParams, headers: apiHeaders);
return models.Webhook.fromMap(res.data);
}
}
+15
View File
@@ -65,6 +65,21 @@ abstract class Client {
/// The user agent string of the client that made the request
Client setForwardedUserAgent(String value);
/// Set ImpersonateUserId
///
/// Impersonate a user by ID on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
Client setImpersonateUserId(String value);
/// Set ImpersonateUserEmail
///
/// Impersonate a user by email on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
Client setImpersonateUserEmail(String value);
/// Set ImpersonateUserPhone
///
/// Impersonate a user by phone on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
Client setImpersonateUserPhone(String value);
/// Add headers that should be sent with all API calls.
Client addHeader(String key, String value);
+12
View File
@@ -25,6 +25,18 @@ abstract class ClientBase implements Client {
@override
ClientBase setForwardedUserAgent(value);
/// Impersonate a user by ID on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBase setImpersonateUserId(value);
/// Impersonate a user by email on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBase setImpersonateUserEmail(value);
/// Impersonate a user by phone on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBase setImpersonateUserPhone(value);
@override
ClientBase setSelfSigned({bool status = true});
+26 -2
View File
@@ -33,8 +33,8 @@ class ClientBrowser extends ClientBase with ClientMixin {
'x-sdk-name': 'Dart',
'x-sdk-platform': 'server',
'x-sdk-language': 'dart',
'x-sdk-version': '21.3.0',
'X-Appwrite-Response-Format': '1.8.0',
'x-sdk-version': '22.0.0',
'X-Appwrite-Response-Format': '1.9.0',
};
config = {};
@@ -93,6 +93,30 @@ class ClientBrowser extends ClientBase with ClientMixin {
return this;
}
/// Impersonate a user by ID on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBrowser setImpersonateUserId(value) {
config['impersonateUserId'] = value;
addHeader('X-Appwrite-Impersonate-User-Id', value);
return this;
}
/// Impersonate a user by email on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBrowser setImpersonateUserEmail(value) {
config['impersonateUserEmail'] = value;
addHeader('X-Appwrite-Impersonate-User-Email', value);
return this;
}
/// Impersonate a user by phone on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientBrowser setImpersonateUserPhone(value) {
config['impersonateUserPhone'] = value;
addHeader('X-Appwrite-Impersonate-User-Phone', value);
return this;
}
@override
ClientBrowser setSelfSigned({bool status = true}) {
return this;
+27 -3
View File
@@ -42,10 +42,10 @@ class ClientIO extends ClientBase with ClientMixin {
'x-sdk-name': 'Dart',
'x-sdk-platform': 'server',
'x-sdk-language': 'dart',
'x-sdk-version': '21.3.0',
'x-sdk-version': '22.0.0',
'user-agent':
'AppwriteDartSDK/21.3.0 (${Platform.operatingSystem}; ${Platform.operatingSystemVersion})',
'X-Appwrite-Response-Format': '1.8.0',
'AppwriteDartSDK/22.0.0 (${Platform.operatingSystem}; ${Platform.operatingSystemVersion})',
'X-Appwrite-Response-Format': '1.9.0',
};
config = {};
@@ -104,6 +104,30 @@ class ClientIO extends ClientBase with ClientMixin {
return this;
}
/// Impersonate a user by ID on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientIO setImpersonateUserId(value) {
config['impersonateUserId'] = value;
addHeader('X-Appwrite-Impersonate-User-Id', value);
return this;
}
/// Impersonate a user by email on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientIO setImpersonateUserEmail(value) {
config['impersonateUserEmail'] = value;
addHeader('X-Appwrite-Impersonate-User-Email', value);
return this;
}
/// Impersonate a user by phone on an already user-authenticated request. Requires the current request to be authenticated as a user with impersonator capability; X-Appwrite-Key alone is not sufficient. Impersonator users are intentionally granted users.read so they can discover a target before impersonation begins. Internal audit logs still attribute actions to the original impersonator and record the impersonated target only in internal audit payload data.
@override
ClientIO setImpersonateUserPhone(value) {
config['impersonateUserPhone'] = value;
addHeader('X-Appwrite-Impersonate-User-Phone', value);
return this;
}
@override
ClientIO setSelfSigned({bool status = true}) {
_nativeClient.badCertificateCallback =
+3
View File
@@ -2,6 +2,9 @@ part of '../../enums.dart';
enum BackupServices {
databases(value: 'databases'),
tablesdb(value: 'tablesdb'),
documentsdb(value: 'documentsdb'),
vectorsdb(value: 'vectorsdb'),
functions(value: 'functions'),
storage(value: 'storage');
+3 -1
View File
@@ -2,7 +2,9 @@ part of '../../enums.dart';
enum DatabaseType {
legacy(value: 'legacy'),
tablesdb(value: 'tablesdb');
tablesdb(value: 'tablesdb'),
documentsdb(value: 'documentsdb'),
vectorsdb(value: 'vectorsdb');
const DatabaseType({required this.value});
+14
View File
@@ -0,0 +1,14 @@
part of '../../enums.dart';
enum DatabasesIndexType {
key(value: 'key'),
fulltext(value: 'fulltext'),
unique(value: 'unique'),
spatial(value: 'spatial');
const DatabasesIndexType({required this.value});
final String value;
String toJson() => value;
}
+4
View File
@@ -58,6 +58,10 @@ enum Scopes {
assistantRead(value: 'assistant.read'),
tokensRead(value: 'tokens.read'),
tokensWrite(value: 'tokens.write'),
webhooksRead(value: 'webhooks.read'),
webhooksWrite(value: 'webhooks.write'),
projectRead(value: 'project.read'),
projectWrite(value: 'project.write'),
policiesWrite(value: 'policies.write'),
policiesRead(value: 'policies.read'),
archivesRead(value: 'archives.read'),
@@ -1,12 +1,12 @@
part of '../../enums.dart';
enum IndexType {
enum TablesDBIndexType {
key(value: 'key'),
fulltext(value: 'fulltext'),
unique(value: 'unique'),
spatial(value: 'spatial');
const IndexType({required this.value});
const TablesDBIndexType({required this.value});
final String value;
+1 -1
View File
@@ -1,8 +1,8 @@
part of '../../enums.dart';
enum TemplateReferenceType {
branch(value: 'branch'),
commit(value: 'commit'),
branch(value: 'branch'),
tag(value: 'tag');
const TemplateReferenceType({required this.value});
+2 -2
View File
@@ -6,7 +6,7 @@ class Document implements Model {
final String $id;
/// Document sequence ID.
final int $sequence;
final String $sequence;
/// Collection ID.
final String $collectionId;
@@ -39,7 +39,7 @@ class Document implements Model {
factory Document.fromMap(Map<String, dynamic> map) {
return Document(
$id: map['\$id'].toString(),
$sequence: map['\$sequence'],
$sequence: map['\$sequence'].toString(),
$collectionId: map['\$collectionId'].toString(),
$databaseId: map['\$databaseId'].toString(),
$createdAt: map['\$createdAt'].toString(),
+17 -5
View File
@@ -29,6 +29,9 @@ class Func implements Model {
/// Function execution and build runtime.
final String runtime;
/// How many days to keep the non-active deployments before they will be automatically deleted.
final int deploymentRetention;
/// Function&#039;s active deployment ID.
final String deploymentId;
@@ -83,8 +86,11 @@ class Func implements Model {
/// Is VCS (Version Control System) connection is in silent mode? When in silence mode, no comments will be posted on the repository pull or merge requests
final bool providerSilentMode;
/// Machine specification for builds and executions.
final String specification;
/// Machine specification for deployment builds.
final String buildSpecification;
/// Machine specification for executions.
final String runtimeSpecification;
Func({
required this.$id,
@@ -96,6 +102,7 @@ class Func implements Model {
required this.live,
required this.logging,
required this.runtime,
required this.deploymentRetention,
required this.deploymentId,
required this.deploymentCreatedAt,
required this.latestDeploymentId,
@@ -114,7 +121,8 @@ class Func implements Model {
required this.providerBranch,
required this.providerRootDirectory,
required this.providerSilentMode,
required this.specification,
required this.buildSpecification,
required this.runtimeSpecification,
});
factory Func.fromMap(Map<String, dynamic> map) {
@@ -128,6 +136,7 @@ class Func implements Model {
live: map['live'],
logging: map['logging'],
runtime: map['runtime'].toString(),
deploymentRetention: map['deploymentRetention'],
deploymentId: map['deploymentId'].toString(),
deploymentCreatedAt: map['deploymentCreatedAt'].toString(),
latestDeploymentId: map['latestDeploymentId'].toString(),
@@ -146,7 +155,8 @@ class Func implements Model {
providerBranch: map['providerBranch'].toString(),
providerRootDirectory: map['providerRootDirectory'].toString(),
providerSilentMode: map['providerSilentMode'],
specification: map['specification'].toString(),
buildSpecification: map['buildSpecification'].toString(),
runtimeSpecification: map['runtimeSpecification'].toString(),
);
}
@@ -162,6 +172,7 @@ class Func implements Model {
"live": live,
"logging": logging,
"runtime": runtime,
"deploymentRetention": deploymentRetention,
"deploymentId": deploymentId,
"deploymentCreatedAt": deploymentCreatedAt,
"latestDeploymentId": latestDeploymentId,
@@ -180,7 +191,8 @@ class Func implements Model {
"providerBranch": providerBranch,
"providerRootDirectory": providerRootDirectory,
"providerSilentMode": providerSilentMode,
"specification": specification,
"buildSpecification": buildSpecification,
"runtimeSpecification": runtimeSpecification,
};
}
}
+3 -3
View File
@@ -5,13 +5,13 @@ class Log implements Model {
/// Event name.
final String event;
/// User ID.
/// User ID of the actor recorded for this log. During impersonation, this is the original impersonator, not the impersonated target user.
final String userId;
/// User Email.
/// User email of the actor recorded for this log. During impersonation, this is the original impersonator.
final String userEmail;
/// User Name.
/// User name of the actor recorded for this log. During impersonation, this is the original impersonator.
final String userName;
/// API mode when event triggered.
+2 -2
View File
@@ -6,7 +6,7 @@ class Row implements Model {
final String $id;
/// Row sequence ID.
final int $sequence;
final String $sequence;
/// Table ID.
final String $tableId;
@@ -39,7 +39,7 @@ class Row implements Model {
factory Row.fromMap(Map<String, dynamic> map) {
return Row(
$id: map['\$id'].toString(),
$sequence: map['\$sequence'],
$sequence: map['\$sequence'].toString(),
$tableId: map['\$tableId'].toString(),
$databaseId: map['\$databaseId'].toString(),
$createdAt: map['\$createdAt'].toString(),
+23 -5
View File
@@ -26,6 +26,9 @@ class Site implements Model {
/// Site framework.
final String framework;
/// How many days to keep the non-active deployments before they will be automatically deleted.
final int deploymentRetention;
/// Site&#039;s active deployment ID.
final String deploymentId;
@@ -59,6 +62,9 @@ class Site implements Model {
/// The build command used to build the site.
final String buildCommand;
/// Custom command to use when starting site runtime.
final String startCommand;
/// The directory where the site build output is located.
final String outputDirectory;
@@ -77,8 +83,11 @@ class Site implements Model {
/// Is VCS (Version Control System) connection is in silent mode? When in silence mode, no comments will be posted on the repository pull or merge requests
final bool providerSilentMode;
/// Machine specification for builds and executions.
final String specification;
/// Machine specification for deployment builds.
final String buildSpecification;
/// Machine specification for SSR executions.
final String runtimeSpecification;
/// Site build runtime.
final String buildRuntime;
@@ -98,6 +107,7 @@ class Site implements Model {
required this.live,
required this.logging,
required this.framework,
required this.deploymentRetention,
required this.deploymentId,
required this.deploymentCreatedAt,
required this.deploymentScreenshotLight,
@@ -109,13 +119,15 @@ class Site implements Model {
required this.timeout,
required this.installCommand,
required this.buildCommand,
required this.startCommand,
required this.outputDirectory,
required this.installationId,
required this.providerRepositoryId,
required this.providerBranch,
required this.providerRootDirectory,
required this.providerSilentMode,
required this.specification,
required this.buildSpecification,
required this.runtimeSpecification,
required this.buildRuntime,
required this.adapter,
required this.fallbackFile,
@@ -131,6 +143,7 @@ class Site implements Model {
live: map['live'],
logging: map['logging'],
framework: map['framework'].toString(),
deploymentRetention: map['deploymentRetention'],
deploymentId: map['deploymentId'].toString(),
deploymentCreatedAt: map['deploymentCreatedAt'].toString(),
deploymentScreenshotLight: map['deploymentScreenshotLight'].toString(),
@@ -142,13 +155,15 @@ class Site implements Model {
timeout: map['timeout'],
installCommand: map['installCommand'].toString(),
buildCommand: map['buildCommand'].toString(),
startCommand: map['startCommand'].toString(),
outputDirectory: map['outputDirectory'].toString(),
installationId: map['installationId'].toString(),
providerRepositoryId: map['providerRepositoryId'].toString(),
providerBranch: map['providerBranch'].toString(),
providerRootDirectory: map['providerRootDirectory'].toString(),
providerSilentMode: map['providerSilentMode'],
specification: map['specification'].toString(),
buildSpecification: map['buildSpecification'].toString(),
runtimeSpecification: map['runtimeSpecification'].toString(),
buildRuntime: map['buildRuntime'].toString(),
adapter: map['adapter'].toString(),
fallbackFile: map['fallbackFile'].toString(),
@@ -166,6 +181,7 @@ class Site implements Model {
"live": live,
"logging": logging,
"framework": framework,
"deploymentRetention": deploymentRetention,
"deploymentId": deploymentId,
"deploymentCreatedAt": deploymentCreatedAt,
"deploymentScreenshotLight": deploymentScreenshotLight,
@@ -177,13 +193,15 @@ class Site implements Model {
"timeout": timeout,
"installCommand": installCommand,
"buildCommand": buildCommand,
"startCommand": startCommand,
"outputDirectory": outputDirectory,
"installationId": installationId,
"providerRepositoryId": providerRepositoryId,
"providerBranch": providerBranch,
"providerRootDirectory": providerRootDirectory,
"providerSilentMode": providerSilentMode,
"specification": specification,
"buildSpecification": buildSpecification,
"runtimeSpecification": runtimeSpecification,
"buildRuntime": buildRuntime,
"adapter": adapter,
"fallbackFile": fallbackFile,
+12
View File
@@ -59,6 +59,12 @@ class User implements Model {
/// Most recent access date in ISO 8601 format. This attribute is only updated again after 24 hours.
final String accessedAt;
/// Whether the user can impersonate other users.
final bool? impersonator;
/// ID of the original actor performing the impersonation. Present only when the current request is impersonating another user. Internal audit logs attribute the action to this user, while the impersonated target is recorded only in internal audit payload data.
final String? impersonatorUserId;
User({
required this.$id,
required this.$createdAt,
@@ -79,6 +85,8 @@ class User implements Model {
required this.prefs,
required this.targets,
required this.accessedAt,
this.impersonator,
this.impersonatorUserId,
});
factory User.fromMap(Map<String, dynamic> map) {
@@ -102,6 +110,8 @@ class User implements Model {
prefs: Preferences.fromMap(map['prefs']),
targets: List<Target>.from(map['targets'].map((p) => Target.fromMap(p))),
accessedAt: map['accessedAt'].toString(),
impersonator: map['impersonator'],
impersonatorUserId: map['impersonatorUserId']?.toString(),
);
}
@@ -127,6 +137,8 @@ class User implements Model {
"prefs": prefs.toMap(),
"targets": targets.map((p) => p.toMap()).toList(),
"accessedAt": accessedAt,
"impersonator": impersonator,
"impersonatorUserId": impersonatorUserId,
};
}
}
+96
View File
@@ -0,0 +1,96 @@
part of '../../models.dart';
/// Webhook
class Webhook implements Model {
/// Webhook ID.
final String $id;
/// Webhook creation date in ISO 8601 format.
final String $createdAt;
/// Webhook update date in ISO 8601 format.
final String $updatedAt;
/// Webhook name.
final String name;
/// Webhook URL endpoint.
final String url;
/// Webhook trigger events.
final List<String> events;
/// Indicated if SSL / TLS Certificate verification is enabled.
final bool security;
/// HTTP basic authentication username.
final String httpUser;
/// HTTP basic authentication password.
final String httpPass;
/// Signature key which can be used to validated incoming
final String signatureKey;
/// Indicates if this webhook is enabled.
final bool enabled;
/// Webhook error logs from the most recent failure.
final String logs;
/// Number of consecutive failed webhook attempts.
final int attempts;
Webhook({
required this.$id,
required this.$createdAt,
required this.$updatedAt,
required this.name,
required this.url,
required this.events,
required this.security,
required this.httpUser,
required this.httpPass,
required this.signatureKey,
required this.enabled,
required this.logs,
required this.attempts,
});
factory Webhook.fromMap(Map<String, dynamic> map) {
return Webhook(
$id: map['\$id'].toString(),
$createdAt: map['\$createdAt'].toString(),
$updatedAt: map['\$updatedAt'].toString(),
name: map['name'].toString(),
url: map['url'].toString(),
events: List.from(map['events'] ?? []),
security: map['security'],
httpUser: map['httpUser'].toString(),
httpPass: map['httpPass'].toString(),
signatureKey: map['signatureKey'].toString(),
enabled: map['enabled'],
logs: map['logs'].toString(),
attempts: map['attempts'],
);
}
@override
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"name": name,
"url": url,
"events": events,
"security": security,
"httpUser": httpUser,
"httpPass": httpPass,
"signatureKey": signatureKey,
"enabled": enabled,
"logs": logs,
"attempts": attempts,
};
}
}
+31
View File
@@ -0,0 +1,31 @@
part of '../../models.dart';
/// Webhooks List
class WebhookList implements Model {
/// Total number of webhooks that matched your query.
final int total;
/// List of webhooks.
final List<Webhook> webhooks;
WebhookList({
required this.total,
required this.webhooks,
});
factory WebhookList.fromMap(Map<String, dynamic> map) {
return WebhookList(
total: map['total'],
webhooks:
List<Webhook>.from(map['webhooks'].map((p) => Webhook.fromMap(p))),
);
}
@override
Map<String, dynamic> toMap() {
return {
"total": total,
"webhooks": webhooks.map((p) => p.toMap()).toList(),
};
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: dart_appwrite
version: 21.3.0
version: 22.0.0
description: Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API
homepage: https://appwrite.io
repository: https://github.com/appwrite/sdk-for-dart
+7 -7
View File
@@ -1296,7 +1296,7 @@ void main() {
test('test method createDocument()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1390,7 +1390,7 @@ void main() {
test('test method getDocument()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1413,7 +1413,7 @@ void main() {
test('test method upsertDocument()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1436,7 +1436,7 @@ void main() {
test('test method updateDocument()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1473,7 +1473,7 @@ void main() {
test('test method decrementDocumentAttribute()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1497,7 +1497,7 @@ void main() {
test('test method incrementDocumentAttribute()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$collectionId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1556,7 +1556,7 @@ void main() {
databaseId: '<DATABASE_ID>',
collectionId: '<COLLECTION_ID>',
key: '',
type: enums.IndexType.key,
type: enums.DatabasesIndexType.key,
attributes: [],
);
expect(response, isA<models.Index>());
+12 -4
View File
@@ -79,6 +79,7 @@ void main() {
'live': true,
'logging': true,
'runtime': 'python-3.8',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'latestDeploymentId': '5e5ea5c16897e',
@@ -97,7 +98,8 @@ void main() {
'providerBranch': 'main',
'providerRootDirectory': 'functions/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
};
when(client.call(
@@ -151,6 +153,7 @@ void main() {
'live': true,
'logging': true,
'runtime': 'python-3.8',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'latestDeploymentId': '5e5ea5c16897e',
@@ -169,7 +172,8 @@ void main() {
'providerBranch': 'main',
'providerRootDirectory': 'functions/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
};
when(client.call(
@@ -193,6 +197,7 @@ void main() {
'live': true,
'logging': true,
'runtime': 'python-3.8',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'latestDeploymentId': '5e5ea5c16897e',
@@ -211,7 +216,8 @@ void main() {
'providerBranch': 'main',
'providerRootDirectory': 'functions/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
};
when(client.call(
@@ -248,6 +254,7 @@ void main() {
'live': true,
'logging': true,
'runtime': 'python-3.8',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'latestDeploymentId': '5e5ea5c16897e',
@@ -266,7 +273,8 @@ void main() {
'providerBranch': 'main',
'providerRootDirectory': 'functions/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
};
when(client.call(
-65
View File
@@ -171,32 +171,6 @@ void main() {
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueBillingProjectAggregation()', () async {
final Map<String, dynamic> data = {
'size': 8,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await health.getQueueBillingProjectAggregation();
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueBillingTeamAggregation()', () async {
final Map<String, dynamic> data = {
'size': 8,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await health.getQueueBillingTeamAggregation();
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueBuilds()', () async {
final Map<String, dynamic> data = {
'size': 8,
@@ -210,19 +184,6 @@ void main() {
expect(response, isA<models.HealthQueue>());
});
test('test method getQueuePriorityBuilds()', () async {
final Map<String, dynamic> data = {
'size': 8,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await health.getQueuePriorityBuilds();
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueCertificates()', () async {
final Map<String, dynamic> data = {
'size': 8,
@@ -342,19 +303,6 @@ void main() {
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueRegionManager()', () async {
final Map<String, dynamic> data = {
'size': 8,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await health.getQueueRegionManager();
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueStatsResources()', () async {
final Map<String, dynamic> data = {
'size': 8,
@@ -381,19 +329,6 @@ void main() {
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueThreats()', () async {
final Map<String, dynamic> data = {
'size': 8,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await health.getQueueThreats();
expect(response, isA<models.HealthQueue>());
});
test('test method getQueueWebhooks()', () async {
final Map<String, dynamic> data = {
'size': 8,
+151
View File
@@ -0,0 +1,151 @@
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:dart_appwrite/models.dart' as models;
import 'package:dart_appwrite/enums.dart' as enums;
import 'package:dart_appwrite/src/enums.dart';
import 'package:dart_appwrite/src/response.dart';
import 'dart:typed_data';
import 'package:dart_appwrite/dart_appwrite.dart';
class MockClient extends Mock implements Client {
Map<String, String> config = {'project': 'testproject'};
String endPoint = 'https://localhost/v1';
@override
Future<Response> call(
HttpMethod? method, {
String path = '',
Map<String, String> headers = const {},
Map<String, dynamic> params = const {},
ResponseType? responseType,
}) async {
return super.noSuchMethod(Invocation.method(#call, [method]),
returnValue: Response());
}
@override
Future<String?> webAuth(Uri url) async {
return super
.noSuchMethod(Invocation.method(#webAuth, [url]), returnValue: 'done');
}
@override
Future<Response> chunkedUpload({
String? path,
Map<String, dynamic>? params,
String? paramName,
String? idParamName,
Map<String, String>? headers,
Function(UploadProgress)? onProgress,
}) async {
return super.noSuchMethod(
Invocation.method(
#chunkedUpload, [path, params, paramName, idParamName, headers]),
returnValue: Response(data: {}));
}
}
void main() {
group('Project test', () {
late MockClient client;
late Project project;
setUp(() {
client = MockClient();
project = Project(client);
});
test('test method listVariables()', () async {
final Map<String, dynamic> data = {
'total': 5,
'variables': [],
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await project.listVariables();
expect(response, isA<models.VariableList>());
});
test('test method createVariable()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'key': 'API_KEY',
'value': 'myPa\$\$word1',
'secret': true,
'resourceType': 'function',
'resourceId': 'myAwesomeFunction',
};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await project.createVariable(
variableId: '<VARIABLE_ID>',
key: '<KEY>',
value: '<VALUE>',
);
expect(response, isA<models.Variable>());
});
test('test method getVariable()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'key': 'API_KEY',
'value': 'myPa\$\$word1',
'secret': true,
'resourceType': 'function',
'resourceId': 'myAwesomeFunction',
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await project.getVariable(
variableId: '<VARIABLE_ID>',
);
expect(response, isA<models.Variable>());
});
test('test method updateVariable()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'key': 'API_KEY',
'value': 'myPa\$\$word1',
'secret': true,
'resourceType': 'function',
'resourceId': 'myAwesomeFunction',
};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await project.updateVariable(
variableId: '<VARIABLE_ID>',
);
expect(response, isA<models.Variable>());
});
test('test method deleteVariable()', () async {
final data = '';
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await project.deleteVariable(
variableId: '<VARIABLE_ID>',
);
});
});
}
+16 -4
View File
@@ -78,6 +78,7 @@ void main() {
'live': true,
'logging': true,
'framework': 'react',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'deploymentScreenshotLight': '5e5ea5c16897e',
@@ -89,13 +90,15 @@ void main() {
'timeout': 300,
'installCommand': 'npm install',
'buildCommand': 'npm run build',
'startCommand': 'node custom-server.mjs',
'outputDirectory': 'build',
'installationId': '6m40at4ejk5h2u9s1hboo',
'providerRepositoryId': 'appwrite',
'providerBranch': 'main',
'providerRootDirectory': 'sites/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
'buildRuntime': 'node-22',
'adapter': 'static',
'fallbackFile': 'index.html',
@@ -152,6 +155,7 @@ void main() {
'live': true,
'logging': true,
'framework': 'react',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'deploymentScreenshotLight': '5e5ea5c16897e',
@@ -163,13 +167,15 @@ void main() {
'timeout': 300,
'installCommand': 'npm install',
'buildCommand': 'npm run build',
'startCommand': 'node custom-server.mjs',
'outputDirectory': 'build',
'installationId': '6m40at4ejk5h2u9s1hboo',
'providerRepositoryId': 'appwrite',
'providerBranch': 'main',
'providerRootDirectory': 'sites/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
'buildRuntime': 'node-22',
'adapter': 'static',
'fallbackFile': 'index.html',
@@ -195,6 +201,7 @@ void main() {
'live': true,
'logging': true,
'framework': 'react',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'deploymentScreenshotLight': '5e5ea5c16897e',
@@ -206,13 +213,15 @@ void main() {
'timeout': 300,
'installCommand': 'npm install',
'buildCommand': 'npm run build',
'startCommand': 'node custom-server.mjs',
'outputDirectory': 'build',
'installationId': '6m40at4ejk5h2u9s1hboo',
'providerRepositoryId': 'appwrite',
'providerBranch': 'main',
'providerRootDirectory': 'sites/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
'buildRuntime': 'node-22',
'adapter': 'static',
'fallbackFile': 'index.html',
@@ -252,6 +261,7 @@ void main() {
'live': true,
'logging': true,
'framework': 'react',
'deploymentRetention': 7,
'deploymentId': '5e5ea5c16897e',
'deploymentCreatedAt': '2020-10-15T06:38:00.000+00:00',
'deploymentScreenshotLight': '5e5ea5c16897e',
@@ -263,13 +273,15 @@ void main() {
'timeout': 300,
'installCommand': 'npm install',
'buildCommand': 'npm run build',
'startCommand': 'node custom-server.mjs',
'outputDirectory': 'build',
'installationId': '6m40at4ejk5h2u9s1hboo',
'providerRepositoryId': 'appwrite',
'providerBranch': 'main',
'providerRootDirectory': 'sites/helloWorld',
'providerSilentMode': true,
'specification': 's-1vcpu-512mb',
'buildSpecification': 's-1vcpu-512mb',
'runtimeSpecification': 's-1vcpu-512mb',
'buildRuntime': 'node-22',
'adapter': 'static',
'fallbackFile': 'index.html',
+7 -7
View File
@@ -1314,7 +1314,7 @@ void main() {
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
key: '',
type: enums.IndexType.key,
type: enums.TablesDBIndexType.key,
columns: [],
);
expect(response, isA<models.ColumnIndex>());
@@ -1379,7 +1379,7 @@ void main() {
test('test method createRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1473,7 +1473,7 @@ void main() {
test('test method getRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1496,7 +1496,7 @@ void main() {
test('test method upsertRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1519,7 +1519,7 @@ void main() {
test('test method updateRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1556,7 +1556,7 @@ void main() {
test('test method decrementRowColumn()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
@@ -1580,7 +1580,7 @@ void main() {
test('test method incrementRowColumn()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$sequence': '1',
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
+31
View File
@@ -429,6 +429,37 @@ void main() {
expect(response, isA<models.User>());
});
test('test method updateImpersonator()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',
};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await users.updateImpersonator(
userId: '<USER_ID>',
impersonator: true,
);
expect(response, isA<models.User>());
});
test('test method createJWT()', () async {
final Map<String, dynamic> data = {
'jwt':
+197
View File
@@ -0,0 +1,197 @@
import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
import 'package:dart_appwrite/models.dart' as models;
import 'package:dart_appwrite/enums.dart' as enums;
import 'package:dart_appwrite/src/enums.dart';
import 'package:dart_appwrite/src/response.dart';
import 'dart:typed_data';
import 'package:dart_appwrite/dart_appwrite.dart';
class MockClient extends Mock implements Client {
Map<String, String> config = {'project': 'testproject'};
String endPoint = 'https://localhost/v1';
@override
Future<Response> call(
HttpMethod? method, {
String path = '',
Map<String, String> headers = const {},
Map<String, dynamic> params = const {},
ResponseType? responseType,
}) async {
return super.noSuchMethod(Invocation.method(#call, [method]),
returnValue: Response());
}
@override
Future<String?> webAuth(Uri url) async {
return super
.noSuchMethod(Invocation.method(#webAuth, [url]), returnValue: 'done');
}
@override
Future<Response> chunkedUpload({
String? path,
Map<String, dynamic>? params,
String? paramName,
String? idParamName,
Map<String, String>? headers,
Function(UploadProgress)? onProgress,
}) async {
return super.noSuchMethod(
Invocation.method(
#chunkedUpload, [path, params, paramName, idParamName, headers]),
returnValue: Response(data: {}));
}
}
void main() {
group('Webhooks test', () {
late MockClient client;
late Webhooks webhooks;
setUp(() {
client = MockClient();
webhooks = Webhooks(client);
});
test('test method list()', () async {
final Map<String, dynamic> data = {
'total': 5,
'webhooks': [],
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.list();
expect(response, isA<models.WebhookList>());
});
test('test method create()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'My Webhook',
'url': 'https://example.com/webhook',
'events': [],
'security': true,
'httpUser': 'username',
'httpPass': 'password',
'signatureKey': 'ad3d581ca230e2b7059c545e5a',
'enabled': true,
'logs': 'Failed to connect to remote server.',
'attempts': 10,
};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.create(
webhookId: '<WEBHOOK_ID>',
url: '',
name: '<NAME>',
events: [],
);
expect(response, isA<models.Webhook>());
});
test('test method get()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'My Webhook',
'url': 'https://example.com/webhook',
'events': [],
'security': true,
'httpUser': 'username',
'httpPass': 'password',
'signatureKey': 'ad3d581ca230e2b7059c545e5a',
'enabled': true,
'logs': 'Failed to connect to remote server.',
'attempts': 10,
};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.get(
webhookId: '<WEBHOOK_ID>',
);
expect(response, isA<models.Webhook>());
});
test('test method update()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'My Webhook',
'url': 'https://example.com/webhook',
'events': [],
'security': true,
'httpUser': 'username',
'httpPass': 'password',
'signatureKey': 'ad3d581ca230e2b7059c545e5a',
'enabled': true,
'logs': 'Failed to connect to remote server.',
'attempts': 10,
};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.update(
webhookId: '<WEBHOOK_ID>',
name: '<NAME>',
url: '',
events: [],
);
expect(response, isA<models.Webhook>());
});
test('test method delete()', () async {
final data = '';
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.delete(
webhookId: '<WEBHOOK_ID>',
);
});
test('test method updateSignature()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'My Webhook',
'url': 'https://example.com/webhook',
'events': [],
'security': true,
'httpUser': 'username',
'httpPass': 'password',
'signatureKey': 'ad3d581ca230e2b7059c545e5a',
'enabled': true,
'logs': 'Failed to connect to remote server.',
'attempts': 10,
};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await webhooks.updateSignature(
webhookId: '<WEBHOOK_ID>',
);
expect(response, isA<models.Webhook>());
});
});
}
+2 -2
View File
@@ -6,7 +6,7 @@ void main() {
test('model', () {
final model = Document(
$id: '5e5ea5c16897e',
$sequence: 1,
$sequence: '1',
$collectionId: '5e5ea5c15117e',
$databaseId: '5e5ea5c15117e',
$createdAt: '2020-10-15T06:38:00.000+00:00',
@@ -19,7 +19,7 @@ void main() {
final result = Document.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$sequence, 1);
expect(result.$sequence, '1');
expect(result.$collectionId, '5e5ea5c15117e');
expect(result.$databaseId, '5e5ea5c15117e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+6 -2
View File
@@ -14,6 +14,7 @@ void main() {
live: true,
logging: true,
runtime: 'python-3.8',
deploymentRetention: 7,
deploymentId: '5e5ea5c16897e',
deploymentCreatedAt: '2020-10-15T06:38:00.000+00:00',
latestDeploymentId: '5e5ea5c16897e',
@@ -32,7 +33,8 @@ void main() {
providerBranch: 'main',
providerRootDirectory: 'functions/helloWorld',
providerSilentMode: true,
specification: 's-1vcpu-512mb',
buildSpecification: 's-1vcpu-512mb',
runtimeSpecification: 's-1vcpu-512mb',
);
final map = model.toMap();
@@ -47,6 +49,7 @@ void main() {
expect(result.live, true);
expect(result.logging, true);
expect(result.runtime, 'python-3.8');
expect(result.deploymentRetention, 7);
expect(result.deploymentId, '5e5ea5c16897e');
expect(result.deploymentCreatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.latestDeploymentId, '5e5ea5c16897e');
@@ -65,7 +68,8 @@ void main() {
expect(result.providerBranch, 'main');
expect(result.providerRootDirectory, 'functions/helloWorld');
expect(result.providerSilentMode, true);
expect(result.specification, 's-1vcpu-512mb');
expect(result.buildSpecification, 's-1vcpu-512mb');
expect(result.runtimeSpecification, 's-1vcpu-512mb');
});
});
}
+2 -2
View File
@@ -6,7 +6,7 @@ void main() {
test('model', () {
final model = Row(
$id: '5e5ea5c16897e',
$sequence: 1,
$sequence: '1',
$tableId: '5e5ea5c15117e',
$databaseId: '5e5ea5c15117e',
$createdAt: '2020-10-15T06:38:00.000+00:00',
@@ -19,7 +19,7 @@ void main() {
final result = Row.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$sequence, 1);
expect(result.$sequence, '1');
expect(result.$tableId, '5e5ea5c15117e');
expect(result.$databaseId, '5e5ea5c15117e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
+8 -2
View File
@@ -13,6 +13,7 @@ void main() {
live: true,
logging: true,
framework: 'react',
deploymentRetention: 7,
deploymentId: '5e5ea5c16897e',
deploymentCreatedAt: '2020-10-15T06:38:00.000+00:00',
deploymentScreenshotLight: '5e5ea5c16897e',
@@ -24,13 +25,15 @@ void main() {
timeout: 300,
installCommand: 'npm install',
buildCommand: 'npm run build',
startCommand: 'node custom-server.mjs',
outputDirectory: 'build',
installationId: '6m40at4ejk5h2u9s1hboo',
providerRepositoryId: 'appwrite',
providerBranch: 'main',
providerRootDirectory: 'sites/helloWorld',
providerSilentMode: true,
specification: 's-1vcpu-512mb',
buildSpecification: 's-1vcpu-512mb',
runtimeSpecification: 's-1vcpu-512mb',
buildRuntime: 'node-22',
adapter: 'static',
fallbackFile: 'index.html',
@@ -47,6 +50,7 @@ void main() {
expect(result.live, true);
expect(result.logging, true);
expect(result.framework, 'react');
expect(result.deploymentRetention, 7);
expect(result.deploymentId, '5e5ea5c16897e');
expect(result.deploymentCreatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.deploymentScreenshotLight, '5e5ea5c16897e');
@@ -58,13 +62,15 @@ void main() {
expect(result.timeout, 300);
expect(result.installCommand, 'npm install');
expect(result.buildCommand, 'npm run build');
expect(result.startCommand, 'node custom-server.mjs');
expect(result.outputDirectory, 'build');
expect(result.installationId, '6m40at4ejk5h2u9s1hboo');
expect(result.providerRepositoryId, 'appwrite');
expect(result.providerBranch, 'main');
expect(result.providerRootDirectory, 'sites/helloWorld');
expect(result.providerSilentMode, true);
expect(result.specification, 's-1vcpu-512mb');
expect(result.buildSpecification, 's-1vcpu-512mb');
expect(result.runtimeSpecification, 's-1vcpu-512mb');
expect(result.buildRuntime, 'node-22');
expect(result.adapter, 'static');
expect(result.fallbackFile, 'index.html');
+19
View File
@@ -0,0 +1,19 @@
import 'package:dart_appwrite/models.dart';
import 'package:test/test.dart';
void main() {
group('WebhookList', () {
test('model', () {
final model = WebhookList(
total: 5,
webhooks: [],
);
final map = model.toMap();
final result = WebhookList.fromMap(map);
expect(result.total, 5);
expect(result.webhooks, []);
});
});
}
+41
View File
@@ -0,0 +1,41 @@
import 'package:dart_appwrite/models.dart';
import 'package:test/test.dart';
void main() {
group('Webhook', () {
test('model', () {
final model = Webhook(
$id: '5e5ea5c16897e',
$createdAt: '2020-10-15T06:38:00.000+00:00',
$updatedAt: '2020-10-15T06:38:00.000+00:00',
name: 'My Webhook',
url: 'https://example.com/webhook',
events: [],
security: true,
httpUser: 'username',
httpPass: 'password',
signatureKey: 'ad3d581ca230e2b7059c545e5a',
enabled: true,
logs: 'Failed to connect to remote server.',
attempts: 10,
);
final map = model.toMap();
final result = Webhook.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.name, 'My Webhook');
expect(result.url, 'https://example.com/webhook');
expect(result.events, []);
expect(result.security, true);
expect(result.httpUser, 'username');
expect(result.httpPass, 'password');
expect(result.signatureKey, 'ad3d581ca230e2b7059c545e5a');
expect(result.enabled, true);
expect(result.logs, 'Failed to connect to remote server.');
expect(result.attempts, 10);
});
});
}