Skip to content

Commit 4216a5b

Browse files
Merge pull request #223 from appwrite/dev
release: sdk
2 parents 67f4c14 + 8a9e6dd commit 4216a5b

22 files changed

+74
-39
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file:
2121

2222
```yml
2323
dependencies:
24-
appwrite: ^13.0.0
24+
appwrite: ^13.1.0
2525
```
2626
2727
You can install packages from the command line:

lib/services/account.dart

+10-10
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Account extends Service {
8585
return models.User.fromMap(res.data);
8686
}
8787

88-
/// List Identities
88+
/// List identities
8989
///
9090
/// Get the list of identities for the currently logged in user.
9191
Future<models.IdentityList> listIdentities({List<String>? queries}) async {
@@ -187,7 +187,7 @@ class Account extends Service {
187187
return models.User.fromMap(res.data);
188188
}
189189

190-
/// Create Authenticator
190+
/// Create authenticator
191191
///
192192
/// Add an authenticator app to be used as an MFA factor. Verify the
193193
/// authenticator using the [verify
@@ -210,7 +210,7 @@ class Account extends Service {
210210
return models.MfaType.fromMap(res.data);
211211
}
212212

213-
/// Verify Authenticator
213+
/// Verify authenticator
214214
///
215215
/// Verify an authenticator app after adding it using the [add
216216
/// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
@@ -234,7 +234,7 @@ class Account extends Service {
234234
return models.User.fromMap(res.data);
235235
}
236236

237-
/// Delete Authenticator
237+
/// Delete authenticator
238238
///
239239
/// Delete an authenticator for a user by ID.
240240
Future deleteMfaAuthenticator({required enums.AuthenticatorType type}) async {
@@ -253,7 +253,7 @@ class Account extends Service {
253253
return res.data;
254254
}
255255

256-
/// Create MFA Challenge
256+
/// Create MFA challenge
257257
///
258258
/// Begin the process of MFA verification after sign-in. Finish the flow with
259259
/// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge)
@@ -276,7 +276,7 @@ class Account extends Service {
276276
return models.MfaChallenge.fromMap(res.data);
277277
}
278278

279-
/// Create MFA Challenge (confirmation)
279+
/// Create MFA challenge (confirmation)
280280
///
281281
/// Complete the MFA challenge by providing the one-time password. Finish the
282282
/// process of MFA verification by providing the one-time password. To begin
@@ -302,7 +302,7 @@ class Account extends Service {
302302
return res.data;
303303
}
304304

305-
/// List Factors
305+
/// List factors
306306
///
307307
/// List the factors available on the account to be used as a MFA challange.
308308
Future<models.MfaFactors> listMfaFactors() async {
@@ -320,7 +320,7 @@ class Account extends Service {
320320
return models.MfaFactors.fromMap(res.data);
321321
}
322322

323-
/// Get MFA Recovery Codes
323+
/// Get MFA recovery codes
324324
///
325325
/// Get recovery codes that can be used as backup for MFA flow. Before getting
326326
/// codes, they must be generated using
@@ -341,7 +341,7 @@ class Account extends Service {
341341
return models.MfaRecoveryCodes.fromMap(res.data);
342342
}
343343

344-
/// Create MFA Recovery Codes
344+
/// Create MFA recovery codes
345345
///
346346
/// Generate recovery codes as backup for MFA flow. It's recommended to
347347
/// generate and show then immediately after user successfully adds their
@@ -363,7 +363,7 @@ class Account extends Service {
363363
return models.MfaRecoveryCodes.fromMap(res.data);
364364
}
365365

366-
/// Regenerate MFA Recovery Codes
366+
/// Regenerate MFA recovery codes
367367
///
368368
/// Regenerate recovery codes that can be used as backup for MFA flow. Before
369369
/// regenerating codes, they must be first generated using

lib/services/locale.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Locale extends Service {
2929
return models.Locale.fromMap(res.data);
3030
}
3131

32-
/// List Locale Codes
32+
/// List locale codes
3333
///
3434
/// List of all locale codes in [ISO
3535
/// 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).

lib/services/storage.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ class Storage extends Service {
133133
return models.File.fromMap(res.data);
134134
}
135135

136-
/// Delete File
136+
/// Delete file
137137
///
138138
/// Delete a file by its unique ID. Only users with write permissions have
139139
/// access to delete this resource.

lib/services/teams.dart

+4-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ class Teams extends Service {
116116
/// List team memberships
117117
///
118118
/// Use this endpoint to list a team's members using the team's ID. All team
119-
/// members have read access to this endpoint.
119+
/// members have read access to this endpoint. Hide sensitive attributes from
120+
/// the response by toggling membership privacy in the Console.
120121
Future<models.MembershipList> listMemberships(
121122
{required String teamId, List<String>? queries, String? search}) async {
122123
final String apiPath =
@@ -193,7 +194,8 @@ class Teams extends Service {
193194
/// Get team membership
194195
///
195196
/// Get a team member by the membership unique id. All team members have read
196-
/// access for this resource.
197+
/// access for this resource. Hide sensitive attributes from the response by
198+
/// toggling membership privacy in the Console.
197199
Future<models.Membership> getMembership(
198200
{required String teamId, required String membershipId}) async {
199201
final String apiPath = '/teams/{teamId}/memberships/{membershipId}'

lib/src/client_browser.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ClientBrowser extends ClientBase with ClientMixin {
4343
'x-sdk-name': 'Flutter',
4444
'x-sdk-platform': 'client',
4545
'x-sdk-language': 'flutter',
46-
'x-sdk-version': '13.0.0',
46+
'x-sdk-version': '13.1.0',
4747
'X-Appwrite-Response-Format': '1.6.0',
4848
};
4949

lib/src/client_io.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class ClientIO extends ClientBase with ClientMixin {
6464
'x-sdk-name': 'Flutter',
6565
'x-sdk-platform': 'client',
6666
'x-sdk-language': 'flutter',
67-
'x-sdk-version': '13.0.0',
67+
'x-sdk-version': '13.1.0',
6868
'X-Appwrite-Response-Format': '1.6.0',
6969
};
7070

lib/src/enums/image_format.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ enum ImageFormat {
55
jpeg(value: 'jpeg'),
66
gif(value: 'gif'),
77
png(value: 'png'),
8-
webp(value: 'webp');
8+
webp(value: 'webp'),
9+
avif(value: 'avif');
910

1011
const ImageFormat({required this.value});
1112

lib/src/models/document.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Document implements Model {
1818
final String $updatedAt;
1919

2020
/// Document permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
21-
final List $permissions;
21+
final List<String> $permissions;
2222
final Map<String, dynamic> data;
2323

2424
Document({

lib/src/models/execution.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Execution implements Model {
1212
final String $updatedAt;
1313

1414
/// Execution roles.
15-
final List $permissions;
15+
final List<String> $permissions;
1616

1717
/// Function ID.
1818
final String functionId;

lib/src/models/file.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class File implements Model {
1515
final String $updatedAt;
1616

1717
/// File permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
18-
final List $permissions;
18+
final List<String> $permissions;
1919

2020
/// File name.
2121
final String name;

lib/src/models/membership.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ class Membership implements Model {
1414
/// User ID.
1515
final String userId;
1616

17-
/// User name.
17+
/// User name. Hide this attribute by toggling membership privacy in the Console.
1818
final String userName;
1919

20-
/// User email address.
20+
/// User email address. Hide this attribute by toggling membership privacy in the Console.
2121
final String userEmail;
2222

2323
/// Team ID.
@@ -35,11 +35,11 @@ class Membership implements Model {
3535
/// User confirmation status, true if the user has joined the team or false otherwise.
3636
final bool confirm;
3737

38-
/// Multi factor authentication status, true if the user has MFA enabled or false otherwise.
38+
/// Multi factor authentication status, true if the user has MFA enabled or false otherwise. Hide this attribute by toggling membership privacy in the Console.
3939
final bool mfa;
4040

4141
/// User list of roles
42-
final List roles;
42+
final List<String> roles;
4343

4444
Membership({
4545
required this.$id,

lib/src/models/mfa_recovery_codes.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ part of '../../models.dart';
33
/// MFA Recovery Codes
44
class MfaRecoveryCodes implements Model {
55
/// Recovery codes.
6-
final List recoveryCodes;
6+
final List<String> recoveryCodes;
77

88
MfaRecoveryCodes({
99
required this.recoveryCodes,

lib/src/models/session.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Session implements Model {
8181
final bool current;
8282

8383
/// Returns a list of active session factors.
84-
final List factors;
84+
final List<String> factors;
8585

8686
/// Secret used to authenticate the user. Only included if the request was made with an API key
8787
final String secret;

lib/src/models/target.dart

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class Target implements Model {
2626
/// The target identifier.
2727
final String identifier;
2828

29+
/// Is the target expired.
30+
final bool expired;
31+
2932
Target({
3033
required this.$id,
3134
required this.$createdAt,
@@ -35,6 +38,7 @@ class Target implements Model {
3538
this.providerId,
3639
required this.providerType,
3740
required this.identifier,
41+
required this.expired,
3842
});
3943

4044
factory Target.fromMap(Map<String, dynamic> map) {
@@ -47,6 +51,7 @@ class Target implements Model {
4751
providerId: map['providerId']?.toString(),
4852
providerType: map['providerType'].toString(),
4953
identifier: map['identifier'].toString(),
54+
expired: map['expired'],
5055
);
5156
}
5257

@@ -60,6 +65,7 @@ class Target implements Model {
6065
"providerId": providerId,
6166
"providerType": providerType,
6267
"identifier": identifier,
68+
"expired": expired,
6369
};
6470
}
6571
}

lib/src/models/user.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class User implements Model {
3030
final bool status;
3131

3232
/// Labels for the user.
33-
final List labels;
33+
final List<String> labels;
3434

3535
/// Password update time in ISO 8601 format.
3636
final String passwordUpdate;

lib/src/realtime_mixin.dart

+22
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,31 @@ mixin RealtimeMixin {
2727
int _retries = 0;
2828
StreamSubscription? _websocketSubscription;
2929
bool _creatingSocket = false;
30+
Timer? _heartbeatTimer;
3031

3132
Future<dynamic> _closeConnection() async {
33+
_stopHeartbeat();
3234
await _websocketSubscription?.cancel();
3335
await _websok?.sink.close(status.normalClosure, 'Ending session');
3436
_lastUrl = null;
3537
_retries = 0;
3638
_reconnect = false;
3739
}
3840

41+
void _startHeartbeat() {
42+
_stopHeartbeat();
43+
_heartbeatTimer = Timer.periodic(Duration(seconds: 20), (_) {
44+
if (_websok != null) {
45+
_websok!.sink.add(jsonEncode({"type": "ping"}));
46+
}
47+
});
48+
}
49+
50+
void _stopHeartbeat() {
51+
_heartbeatTimer?.cancel();
52+
_heartbeatTimer = null;
53+
}
54+
3955
_createSocket() async {
4056
if (_creatingSocket || _channels.isEmpty) return;
4157
_creatingSocket = true;
@@ -78,6 +94,10 @@ mixin RealtimeMixin {
7894
}));
7995
}
8096
}
97+
_startHeartbeat(); // Start heartbeat after successful connection
98+
break;
99+
case 'pong':
100+
debugPrint('Received heartbeat response from realtime server');
81101
break;
82102
case 'event':
83103
final message = RealtimeMessage.fromMap(data.data);
@@ -91,8 +111,10 @@ mixin RealtimeMixin {
91111
break;
92112
}
93113
}, onDone: () {
114+
_stopHeartbeat();
94115
_retry();
95116
}, onError: (err, stack) {
117+
_stopHeartbeat();
96118
for (var subscription in _subscriptions.values) {
97119
subscription.controller.addError(err, stack);
98120
}

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: appwrite
2-
version: 13.0.0
2+
version: 13.1.0
33
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
44
homepage: https://appwrite.io
55
repository: https://github.com/appwrite/sdk-for-flutter

test/services/account_test.dart

+6-4
Original file line numberDiff line numberDiff line change
@@ -1011,10 +1011,11 @@ void main() {
10111011
'\$id': '259125845563242502',
10121012
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
10131013
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
1014-
'name': 'Aegon apple token',
1014+
'name': 'Apple iPhone 12',
10151015
'userId': '259125845563242502',
10161016
'providerType': 'email',
1017-
'identifier': 'token',};
1017+
'identifier': 'token',
1018+
'expired': true,};
10181019

10191020

10201021
when(client.call(
@@ -1035,10 +1036,11 @@ void main() {
10351036
'\$id': '259125845563242502',
10361037
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
10371038
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
1038-
'name': 'Aegon apple token',
1039+
'name': 'Apple iPhone 12',
10391040
'userId': '259125845563242502',
10401041
'providerType': 'email',
1041-
'identifier': 'token',};
1042+
'identifier': 'token',
1043+
'expired': true,};
10421044

10431045

10441046
when(client.call(

test/services/functions_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void main() {
8585
'requestPath': '/articles?id=5',
8686
'requestHeaders': [],
8787
'responseStatusCode': 200,
88-
'responseBody': 'Developers are awesome.',
88+
'responseBody': '',
8989
'responseHeaders': [],
9090
'logs': '',
9191
'errors': '',
@@ -117,7 +117,7 @@ void main() {
117117
'requestPath': '/articles?id=5',
118118
'requestHeaders': [],
119119
'responseStatusCode': 200,
120-
'responseBody': 'Developers are awesome.',
120+
'responseBody': '',
121121
'responseHeaders': [],
122122
'logs': '',
123123
'errors': '',

0 commit comments

Comments
 (0)