Skip to content

Commit

Permalink
Merge pull request #372 from appwrite/feat-improve-dart-flutter-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
lohanidamodar authored Feb 23, 2022
2 parents 0d13b2c + 0e12987 commit de3ece1
Show file tree
Hide file tree
Showing 21 changed files with 107 additions and 118 deletions.
12 changes: 0 additions & 12 deletions src/SDK/Language/Flutter.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,6 @@ public function getFiles()
'template' => 'flutter/lib/src/interceptor.dart.twig',
'minify' => false,
],
[
'scope' => 'default',
'destination' => '/lib/src/redirect_browser.dart',
'template' => 'flutter/lib/src/redirect_browser.dart.twig',
'minify' => false,
],
[
'scope' => 'default',
'destination' => '/lib/src/redirect_stub.dart',
'template' => 'flutter/lib/src/redirect_stub.dart.twig',
'minify' => false,
],
[
'scope' => 'default',
'destination' => '/lib/src/response.dart',
Expand Down
4 changes: 0 additions & 4 deletions templates/dart/lib/services/service.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ class {{ service.name | caseUcfirst }} extends Service {
};

{% if method.type == 'location' %}
params.keys.forEach((key) {if (params[key] is int || params[key] is double) {
params[key] = params[key].toString();
}});

final res = await client.call(HttpMethod.{{ method.method | caseLower }}, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
{% else %}
Expand Down
5 changes: 5 additions & 0 deletions templates/dart/lib/src/client_base.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ abstract class ClientBase implements Client {
{% if header.description %}
/// {{header.description}}
{% endif %}
@override
ClientBase set{{header.key | caseUcfirst}}(value);
{% endfor %}

@override
ClientBase setSelfSigned({bool status = true});

@override
ClientBase setEndpoint(String endPoint);

@override
ClientBase addHeader(String key, String value);

@override
Future<Response> call(
HttpMethod method, {
String path = '',
Expand Down
19 changes: 13 additions & 6 deletions templates/dart/lib/src/client_browser.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ClientBase createClient({
class ClientBrowser extends ClientBase with ClientMixin {
String _endPoint;
Map<String, String>? _headers;
@override
late Map<String, String> config;
late BrowserClient _httpClient;

Expand All @@ -31,39 +32,45 @@ class ClientBrowser extends ClientBase with ClientMixin {
{% endfor %}
};

this.config = {};
config = {};

assert(_endPoint.startsWith(RegExp("http://|https://")),
"endPoint $_endPoint must start with 'http'");
}

@override
String get endPoint => _endPoint;

{% for header in spec.global.headers %}
{% if header.description %}
/// {{header.description}}
{% endif %}
@override
ClientBrowser set{{header.key | caseUcfirst}}(value) {
config['{{ header.key | caseCamel }}'] = value;
addHeader('{{header.name}}', value);
return this;
}
{% endfor %}

@override
ClientBrowser setSelfSigned({bool status = true}) {
return this;
}

@override
ClientBrowser setEndpoint(String endPoint) {
this._endPoint = endPoint;
_endPoint = endPoint;
return this;
}

@override
ClientBrowser addHeader(String key, String value) {
_headers![key] = value;
return this;
}

@override
Future<Response> call(
HttpMethod method, {
String path = '',
Expand All @@ -72,20 +79,20 @@ class ClientBrowser extends ClientBase with ClientMixin {
ResponseType? responseType,
}) async {
late http.Response res;
http.BaseRequest request = this.prepareRequest(
http.BaseRequest request = prepareRequest(
method,
uri: Uri.parse(_endPoint + path),
headers: {...this._headers!, ...headers},
headers: {..._headers!, ...headers},
params: params,
);
try {
final streamedResponse = await _httpClient.send(request);
res = await toResponse(streamedResponse);

return this.prepareResponse(res, responseType: responseType);
return prepareResponse(res, responseType: responseType);
} catch (e) {
if (e is {{spec.title | caseUcfirst}}Exception) {
throw e;
rethrow;
}
throw {{spec.title | caseUcfirst}}Exception(e.toString());
}
Expand Down
28 changes: 17 additions & 11 deletions templates/dart/lib/src/client_io.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -19,63 +19,69 @@ ClientBase createClient({
class ClientIO extends ClientBase with ClientMixin {
String _endPoint;
Map<String, String>? _headers;
@override
late Map<String, String> config;
bool _initialized = false;
late http.Client _httpClient;
late HttpClient _nativeClient;

ClientIO({
String endPoint = '{{ spec.endpoint }}',
bool selfSigned = false,
}) : _endPoint = endPoint {
_nativeClient = new HttpClient()
_nativeClient = HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) => selfSigned);
_httpClient = new IOClient(_nativeClient);
this._endPoint = endPoint;
this._headers = {
_httpClient = IOClient(_nativeClient);
_endPoint = endPoint;
_headers = {
'content-type': 'application/json',
'x-sdk-version': '{{spec.title | caseDash}}:{{ language.name | caseLower }}:{{ sdk.version }}',
{% for key,header in spec.global.defaultHeaders %}
'{{key}}' : '{{header}}',
{% endfor %}
};

this.config = {};
config = {};

assert(_endPoint.startsWith(RegExp("http://|https://")),
"endPoint $_endPoint must start with 'http'");
}

@override
String get endPoint => _endPoint;

{% for header in spec.global.headers %}
{% if header.description %}
/// {{header.description}}
{% endif %}
@override
ClientIO set{{header.key | caseUcfirst}}(value) {
config['{{ header.key | caseCamel }}'] = value;
addHeader('{{header.name}}', value);
return this;
}
{% endfor %}

@override
ClientIO setSelfSigned({bool status = true}) {
_nativeClient.badCertificateCallback =
((X509Certificate cert, String host, int port) => status);
return this;
}

@override
ClientIO setEndpoint(String endPoint) {
this._endPoint = endPoint;
_endPoint = endPoint;
return this;
}

@override
ClientIO addHeader(String key, String value) {
_headers![key] = value;
return this;
}

@override
Future<Response> call(
HttpMethod method, {
String path = '',
Expand All @@ -84,23 +90,23 @@ class ClientIO extends ClientBase with ClientMixin {
ResponseType? responseType,
}) async {
late http.Response res;
http.BaseRequest request = this.prepareRequest(
http.BaseRequest request = prepareRequest(
method,
uri: Uri.parse(_endPoint + path),
headers: {...this._headers!, ...headers},
headers: {..._headers!, ...headers},
params: params,
);

try {
final streamedResponse = await _httpClient.send(request);
res = await toResponse(streamedResponse);
return this.prepareResponse(
return prepareResponse(
res,
responseType: responseType,
);
} catch (e) {
if (e is {{spec.title | caseUcfirst}}Exception) {
throw e;
rethrow;
}
throw {{spec.title | caseUcfirst}}Exception(e.toString());
}
Expand Down
25 changes: 11 additions & 14 deletions templates/dart/lib/src/client_mixin.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,23 @@ class ClientMixin {
});
}
} else if (method == HttpMethod.get) {
final encoded = <String, dynamic>{};
if (params.isNotEmpty) {
params.keys.forEach((key) {
if (params[key] is int || params[key] is double) {
encoded[key] = params[key].toString();
} else if (params[key] is List) {
encoded[key + "[]"] = params[key];
} else {
encoded[key] = params[key];
params = params.map((key, value){
if (value is int || value is double) {
return MapEntry(key, value.toString());
}
if (value is List) {
return MapEntry(key + "[]", value);
}
return MapEntry(key, value);
});
}
uri = Uri(
fragment: uri.fragment,
path: uri.path,
host: uri.host,
scheme: uri.scheme,
queryParameters: encoded,
queryParameters: params,
port: uri.port);
request = http.Request(method.name(), uri);
} else {
Expand All @@ -67,9 +66,7 @@ class ClientMixin {
}

Response prepareResponse(http.Response res, {ResponseType? responseType}) {
if (responseType == null) {
responseType = ResponseType.json;
}
responseType ??= ResponseType.json;
if (res.statusCode >= 400) {
if ((res.headers['content-type'] ?? '').contains('application/json')) {
final response = json.decode(res.body);
Expand All @@ -82,7 +79,7 @@ class ClientMixin {
throw {{spec.title | caseUcfirst}}Exception(res.body);
}
}
var data;
dynamic data;
if ((res.headers['content-type'] ?? '').contains('application/json')) {
if (responseType == ResponseType.json) {
data = json.decode(res.body);
Expand All @@ -103,7 +100,7 @@ class ClientMixin {

Future<http.Response> toResponse(http.StreamedResponse streamedResponse) async {
if(streamedResponse.statusCode == 204) {
return new http.Response('',
return http.Response('',
streamedResponse.statusCode,
headers: streamedResponse.headers.map((k,v) => k.toLowerCase()=='content-type' ? MapEntry(k, 'text/plain') : MapEntry(k,v)),
request: streamedResponse.request,
Expand Down
2 changes: 1 addition & 1 deletion templates/dart/lib/src/enums.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ enum HttpMethod { get, post, put, delete, patch }

extension HttpMethodString on HttpMethod {
String name() {
return this.toString().split('.').last.toUpperCase();
return toString().split('.').last.toUpperCase();
}
}

Expand Down
1 change: 1 addition & 0 deletions templates/dart/lib/src/exception.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class {{spec.title | caseUcfirst}}Exception implements Exception {

{{spec.title | caseUcfirst}}Exception([this.message = "", this.code, this.response]);

@override
String toString() {
if (message == null) return "{{spec.title | caseUcfirst}}Exception";
return "{{spec.title | caseUcfirst}}Exception: $message (${code ?? 0})";
Expand Down
3 changes: 2 additions & 1 deletion templates/dart/pubspec.yaml.twig
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ dependencies:
http: ^0.13.4
dev_dependencies:
test: ^1.16.8
test: ^1.16.8
lints: ^1.0.1
3 changes: 1 addition & 2 deletions templates/flutter/lib/package.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ library {{ language.params.packageName }};

import 'dart:async';
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'src/redirect_stub.dart'
if (dart.library.html) 'src/redirect_browser.dart';
import 'src/chunked_upload_stub.dart'
if (dart.library.io) 'src/chunked_upload_io.dart';
import 'src/enums.dart';
Expand Down
6 changes: 1 addition & 5 deletions templates/flutter/lib/services/service.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class {{ service.name | caseUcfirst }} extends Service {
///
{% endif %}
{% if method.type == 'webAuth' %}Future{% elseif method.type == 'location' %} Future<Uint8List> {% else %} {% if method.responseModel and method.responseModel != 'any' %}Future<models.{{method.responseModel | caseUcfirst}}>{% else %}Future{% endif %}{% endif %} {{ method.name | caseCamel }}({{ _self.method_parameters(method.parameters, method.consumes) }}) async {
final String path = '{{ method.path }}'{% for parameter in method.parameters.path %}.replaceAll('{{ '{' }}{{ parameter.name | caseCamel }}{{ '}' }}', {{ parameter.name | caseCamel | escapeKeyword }}){% endfor %};
{% if method.parameters.path | length > 0 %}final{% else %}const{% endif %} String path = '{{ method.path }}'{% for parameter in method.parameters.path %}.replaceAll('{{ '{' }}{{ parameter.name | caseCamel }}{{ '}' }}', {{ parameter.name | caseCamel | escapeKeyword }}){% endfor %};

final Map<String, dynamic> params = {
{% for parameter in method.parameters.query %}
Expand Down Expand Up @@ -61,10 +61,6 @@ class {{ service.name | caseUcfirst }} extends Service {
return client.webAuth(url);

{% elseif method.type == 'location' %}
params.keys.forEach((key) {if (params[key] is int || params[key] is double) {
params[key] = params[key].toString();
}});

final res = await client.call(HttpMethod.{{ method.method | caseLower }}, path: path, params: params, responseType: ResponseType.bytes);
return res.data;
{% else %}
Expand Down
Loading

0 comments on commit de3ece1

Please sign in to comment.