From a541436dd48d4734a81bc2b3ba2766bf3265ac31 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 22 Jun 2023 22:17:33 +0200 Subject: [PATCH] dynamite, dynamite_runtime, nextcloud: improve data fetching performance --- .../dynamite/lib/src/openapi_builder.dart | 88 +++--- .../dynamite_runtime/lib/src/http_client.dart | 59 ++-- .../nextcloud/lib/src/nextcloud.openapi.dart | 277 +++++++++--------- packages/nextcloud/lib/src/webdav/client.dart | 8 +- 4 files changed, 218 insertions(+), 214 deletions(-) diff --git a/packages/dynamite/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/dynamite/lib/src/openapi_builder.dart index 687f8bb4..58d28b2e 100644 --- a/packages/dynamite/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/dynamite/lib/src/openapi_builder.dart @@ -69,6 +69,7 @@ class OpenAPIBuilder implements Builder { "import 'package:built_value/standard_json_plugin.dart';", "import 'package:dynamite_runtime/content_string.dart';", "import 'package:dynamite_runtime/http_client.dart';", + "import 'package:universal_io/io.dart';", '', "export 'package:dynamite_runtime/http_client.dart';", '', @@ -113,37 +114,51 @@ class OpenAPIBuilder implements Builder { (final b) => b ..name = '${prefix}ApiException' ..extend = refer('DynamiteApiException') - ..constructors.addAll( - [ - Constructor( - (final b) => b - ..requiredParameters.addAll( - ['statusCode', 'headers', 'body'].map( - (final name) => Parameter( - (final b) => b - ..name = name - ..toSuper = true, - ), - ), - ), - ), - Constructor( - (final b) => b - ..name = 'fromResponse' - ..factory = true - ..lambda = true - ..requiredParameters.add( - Parameter( + ..constructors.add( + Constructor( + (final b) => b + ..requiredParameters.addAll( + ['statusCode', 'headers', 'body'].map( + (final name) => Parameter( (final b) => b - ..name = 'response' - ..type = refer('RawResponse'), + ..name = name + ..toSuper = true, ), - ) - ..body = Code('${prefix}ApiException(response.statusCode, response.headers, response.body,)'), - ), - ], + ), + ), + ), ) - ..methods.add( + ..methods.addAll([ + Method( + (final b) => b + ..name = 'fromResponse' + ..returns = refer('Future<${prefix}ApiException>') + ..static = true + ..modifier = MethodModifier.async + ..requiredParameters.add( + Parameter( + (final b) => b + ..name = 'response' + ..type = refer('HttpClientResponse'), + ), + ) + ..body = Block.of([ + const Code('final data = await response.bodyBytes;'), + const Code(''), + const Code('String body;'), + const Code('try {'), + const Code('body = utf8.decode(data);'), + const Code('} on FormatException {'), + const Code("body = 'binary';"), + const Code('}'), + const Code(''), + Code('return ${prefix}ApiException('), + const Code('response.statusCode,'), + const Code('response.responseHeaders,'), + const Code('body,'), + const Code(');'), + ]), + ), Method( (final b) => b ..name = 'toString' @@ -151,10 +166,10 @@ class OpenAPIBuilder implements Builder { ..annotations.add(refer('override')) ..lambda = true ..body = Code( - "'${prefix}ApiException(statusCode: \${super.statusCode}, headers: \${super.headers}, body: \${utf8.decode(super.body)})'", + "'${prefix}ApiException(statusCode: \$statusCode, headers: \$headers, body: \$body)'", ), ), - ), + ]), ).accept(emitter).toString(), ]; @@ -715,16 +730,21 @@ class OpenAPIBuilder implements Builder { if (mimeType == '*/*' || mimeType.startsWith('image/')) { dataType = 'Uint8List'; - dataValue = 'response.body'; + dataValue = 'response.bodyBytes'; } else if (mimeType.startsWith('text/')) { dataType = 'String'; - dataValue = 'utf8.decode(response.body)'; + dataValue = 'await response.body'; } else if (mimeType == 'application/json') { dataType = result.name; if (result.name == 'dynamic') { dataValue = ''; + } else if (result.name == 'String') { + // avoid unnecessary_await_in_return lint + dataValue = 'response.body'; + } else if (result is TypeResultEnum || result is TypeResultBase) { + dataValue = result.deserialize(result.decode('await response.body')); } else { - dataValue = result.deserialize(result.decode('utf8.decode(response.body)')); + dataValue = result.deserialize('await response.jsonBody'); } } else { throw Exception('Can not parse mime type "$mimeType"'); @@ -751,7 +771,7 @@ class OpenAPIBuilder implements Builder { code.write('}'); } code.write( - 'throw ${prefix}ApiException.fromResponse(response); // coverage:ignore-line\n', + 'throw await ${prefix}ApiException.fromResponse(response); // coverage:ignore-line\n', ); } else { b.returns = refer('Future'); diff --git a/packages/dynamite/dynamite_runtime/lib/src/http_client.dart b/packages/dynamite/dynamite_runtime/lib/src/http_client.dart index 6d873624..f428be79 100644 --- a/packages/dynamite/dynamite_runtime/lib/src/http_client.dart +++ b/packages/dynamite/dynamite_runtime/lib/src/http_client.dart @@ -14,6 +14,17 @@ extension DynamiteHttpClientResponseBody on HttpClientResponse { } Future get body => transform(utf8.decoder).join(); + + Future get jsonBody => transform(utf8.decoder).transform(json.decoder).first; + + Map get responseHeaders { + final responseHeaders = {}; + headers.forEach((final name, final values) { + responseHeaders[name] = values.last; + }); + + return responseHeaders; + } } class DynamiteResponse { @@ -30,8 +41,8 @@ class DynamiteResponse { String toString() => 'DynamiteResponse(data: $data, headers: $headers)'; } -class RawResponse { - RawResponse( +class DynamiteApiException implements Exception { + DynamiteApiException( this.statusCode, this.headers, this.body, @@ -41,22 +52,10 @@ class RawResponse { final Map headers; - final Uint8List body; + final String body; @override - String toString() => 'RawResponse(statusCode: $statusCode, headers: $headers, body: ${utf8.decode(body)})'; -} - -class DynamiteApiException extends RawResponse implements Exception { - DynamiteApiException( - super.statusCode, - super.headers, - super.body, - ); - - @override - String toString() => - 'DynamiteApiException(statusCode: ${super.statusCode}, headers: ${super.headers}, body: ${utf8.decode(super.body)})'; + String toString() => 'DynamiteApiException(statusCode: $statusCode, headers: $headers, body: $body)'; } abstract class DynamiteAuthentication { @@ -85,29 +84,24 @@ class DynamiteHttpBasicAuthentication extends DynamiteAuthentication { class DynamiteClient { DynamiteClient( this.baseURL, { - final Map? baseHeaders, + this.baseHeaders, final String? userAgent, final HttpClient? httpClient, this.cookieJar, this.authentications = const [], - }) { - this.baseHeaders = { - ...?baseHeaders, - }; - this.httpClient = (httpClient ?? HttpClient())..userAgent = userAgent; - } + }) : httpClient = (httpClient ?? HttpClient())..userAgent = userAgent; final String baseURL; - late final Map baseHeaders; + final Map? baseHeaders; - late final HttpClient httpClient; + final HttpClient httpClient; final CookieJar? cookieJar; final List authentications; - Future doRequest( + Future doRequest( final String method, final String path, final Map headers, @@ -115,7 +109,7 @@ class DynamiteClient { ) async { final uri = Uri.parse('$baseURL$path'); final request = await httpClient.openUrl(method, uri); - for (final header in {...baseHeaders, ...headers}.entries) { + for (final header in {...?baseHeaders, ...headers}.entries) { request.headers.add(header.key, header.value); } if (body != null) { @@ -129,14 +123,7 @@ class DynamiteClient { if (cookieJar != null) { await cookieJar!.saveFromResponse(uri, response.cookies); } - final responseHeaders = {}; - response.headers.forEach((final name, final values) { - responseHeaders[name] = values.last; - }); - return RawResponse( - response.statusCode, - responseHeaders, - await response.bodyBytes, - ); + + return response; } } diff --git a/packages/nextcloud/lib/src/nextcloud.openapi.dart b/packages/nextcloud/lib/src/nextcloud.openapi.dart index d7dd424c..1adb9c87 100644 --- a/packages/nextcloud/lib/src/nextcloud.openapi.dart +++ b/packages/nextcloud/lib/src/nextcloud.openapi.dart @@ -10,6 +10,7 @@ import 'package:built_value/serializer.dart'; import 'package:built_value/standard_json_plugin.dart'; import 'package:dynamite_runtime/content_string.dart'; import 'package:dynamite_runtime/http_client.dart'; +import 'package:universal_io/io.dart'; export 'package:dynamite_runtime/http_client.dart'; @@ -32,15 +33,25 @@ class NextcloudApiException extends DynamiteApiException { super.body, ); - factory NextcloudApiException.fromResponse(final RawResponse response) => NextcloudApiException( - response.statusCode, - response.headers, - response.body, - ); + static Future fromResponse(final HttpClientResponse response) async { + final data = await response.bodyBytes; + + String body; + try { + body = utf8.decode(data); + } on FormatException { + body = 'binary'; + } + + return NextcloudApiException( + response.statusCode, + response.responseHeaders, + body, + ); + } @override - String toString() => - 'NextcloudApiException(statusCode: ${super.statusCode}, headers: ${super.headers}, body: ${utf8.decode(super.body)})'; + String toString() => 'NextcloudApiException(statusCode: $statusCode, headers: $headers, body: $body)'; } class NextcloudHttpBasicAuthentication extends DynamiteAuthentication { @@ -100,11 +111,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreServerStatus), )! as NextcloudCoreServerStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getCapabilities() async { @@ -127,11 +138,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreServerCapabilities), )! as NextcloudCoreServerCapabilities; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getNavigationApps() async { @@ -154,11 +165,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreNavigationApps), )! as NextcloudCoreNavigationApps; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future initLoginFlow() async { @@ -176,11 +187,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreLoginFlowInit), )! as NextcloudCoreLoginFlowInit; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getLoginFlowResult({required final String token}) async { @@ -199,11 +210,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreLoginFlowResult), )! as NextcloudCoreLoginFlowResult; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getPreview({ @@ -250,9 +261,9 @@ class NextcloudCoreClient { body, ); if (response.statusCode == 200) { - return response.body; + return response.bodyBytes; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getDarkAvatar({ @@ -279,9 +290,9 @@ class NextcloudCoreClient { body, ); if (response.statusCode == 200) { - return response.body; + return response.bodyBytes; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getAvatar({ @@ -308,9 +319,9 @@ class NextcloudCoreClient { body, ); if (response.statusCode == 200) { - return response.body; + return response.bodyBytes; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future autocomplete({ @@ -350,11 +361,11 @@ class NextcloudCoreClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudCoreAutocompleteResult), )! as NextcloudCoreAutocompleteResult; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteAppPassword() async { @@ -376,9 +387,9 @@ class NextcloudCoreClient { body, ); if (response.statusCode == 200) { - return JsonObject(utf8.decode(response.body)); + return JsonObject(await response.body); } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -407,11 +418,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsSupportedAPIVersions), )! as NextcloudNewsSupportedAPIVersions; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future listFolders() async { @@ -434,11 +445,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListFolders), )! as NextcloudNewsListFolders; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future createFolder({required final String name}) async { @@ -462,11 +473,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListFolders), )! as NextcloudNewsListFolders; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future renameFolder({ @@ -493,7 +504,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteFolder({required final int folderId}) async { @@ -516,7 +527,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future markFolderAsRead({ @@ -543,7 +554,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future listFeeds() async { @@ -566,11 +577,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListFeeds), )! as NextcloudNewsListFeeds; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future addFeed({ @@ -600,11 +611,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListFeeds), )! as NextcloudNewsListFeeds; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteFeed({required final int feedId}) async { @@ -627,7 +638,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future moveFeed({ @@ -656,7 +667,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future renameFeed({ @@ -683,7 +694,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future markFeedAsRead({ @@ -710,7 +721,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future listArticles({ @@ -758,11 +769,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListArticles), )! as NextcloudNewsListArticles; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future listUpdatedArticles({ @@ -798,11 +809,11 @@ class NextcloudNewsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNewsListArticles), )! as NextcloudNewsListArticles; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future markArticleAsRead({required final int itemId}) async { @@ -825,7 +836,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future markArticleAsUnread({required final int itemId}) async { @@ -848,7 +859,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future starArticle({required final int itemId}) async { @@ -871,7 +882,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future unstarArticle({required final int itemId}) async { @@ -894,7 +905,7 @@ class NextcloudNewsClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -948,11 +959,11 @@ class NextcloudNotesClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(BuiltList, [FullType(NextcloudNotesNote)]), )! as BuiltList; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future createNote({ @@ -995,12 +1006,10 @@ class NextcloudNotesClient { body, ); if (response.statusCode == 200) { - return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), - specifiedType: const FullType(NextcloudNotesNote), - )! as NextcloudNotesNote; + return jsonSerializers.deserialize(await response.jsonBody, specifiedType: const FullType(NextcloudNotesNote))! + as NextcloudNotesNote; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getNote({ @@ -1033,12 +1042,10 @@ class NextcloudNotesClient { body, ); if (response.statusCode == 200) { - return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), - specifiedType: const FullType(NextcloudNotesNote), - )! as NextcloudNotesNote; + return jsonSerializers.deserialize(await response.jsonBody, specifiedType: const FullType(NextcloudNotesNote))! + as NextcloudNotesNote; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future updateNote({ @@ -1087,12 +1094,10 @@ class NextcloudNotesClient { body, ); if (response.statusCode == 200) { - return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), - specifiedType: const FullType(NextcloudNotesNote), - )! as NextcloudNotesNote; + return jsonSerializers.deserialize(await response.jsonBody, specifiedType: const FullType(NextcloudNotesNote))! + as NextcloudNotesNote; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteNote({required final int id}) async { @@ -1115,9 +1120,9 @@ class NextcloudNotesClient { body, ); if (response.statusCode == 200) { - return utf8.decode(response.body); + return response.body; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getSettings() async { @@ -1140,11 +1145,11 @@ class NextcloudNotesClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNotesSettings), )! as NextcloudNotesSettings; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future updateSettings({required final NextcloudNotesSettings notesSettings}) async { @@ -1173,11 +1178,11 @@ class NextcloudNotesClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNotesSettings), )! as NextcloudNotesSettings; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -1206,11 +1211,11 @@ class NextcloudNotificationsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNotificationsListNotifications), )! as NextcloudNotificationsListNotifications; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteAllNotifications() async { @@ -1232,9 +1237,9 @@ class NextcloudNotificationsClient { body, ); if (response.statusCode == 200) { - return utf8.decode(response.body); + return response.body; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getNotification({required final int id}) async { @@ -1258,11 +1263,11 @@ class NextcloudNotificationsClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNotificationsGetNotification), )! as NextcloudNotificationsGetNotification; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future deleteNotification({required final int id}) async { @@ -1285,12 +1290,10 @@ class NextcloudNotificationsClient { body, ); if (response.statusCode == 200) { - return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), - specifiedType: const FullType(NextcloudEmptyOCS), - )! as NextcloudEmptyOCS; + return jsonSerializers.deserialize(await response.jsonBody, specifiedType: const FullType(NextcloudEmptyOCS))! + as NextcloudEmptyOCS; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future registerDevice({ @@ -1320,11 +1323,11 @@ class NextcloudNotificationsClient { ); if (response.statusCode == 201) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudNotificationsPushServerRegistration), )! as NextcloudNotificationsPushServerRegistration; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future removeDevice() async { @@ -1346,9 +1349,9 @@ class NextcloudNotificationsClient { body, ); if (response.statusCode == 202) { - return utf8.decode(response.body); + return response.body; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future sendAdminNotification({ @@ -1379,12 +1382,10 @@ class NextcloudNotificationsClient { body, ); if (response.statusCode == 200) { - return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), - specifiedType: const FullType(NextcloudEmptyOCS), - )! as NextcloudEmptyOCS; + return jsonSerializers.deserialize(await response.jsonBody, specifiedType: const FullType(NextcloudEmptyOCS))! + as NextcloudEmptyOCS; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -1413,11 +1414,11 @@ class NextcloudProvisioningApiClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudProvisioningApiUser), )! as NextcloudProvisioningApiUser; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getUser({required final String userId}) async { @@ -1441,11 +1442,11 @@ class NextcloudProvisioningApiClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudProvisioningApiUser), )! as NextcloudProvisioningApiUser; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -1475,11 +1476,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderCheckResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderCheckResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Set keepalive interval @@ -1508,11 +1509,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderSetKeepaliveResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderSetKeepaliveResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Request to create a new deviceId @@ -1539,11 +1540,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderCreateDeviceResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderCreateDeviceResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Request to get push messages @@ -1572,11 +1573,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 401) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderSyncDeviceResponse401ApplicationJson), )! as NextcloudUnifiedPushProviderSyncDeviceResponse401ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Delete a device @@ -1603,11 +1604,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderDeleteDeviceResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderDeleteDeviceResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Create an authorization token for a new 3rd party service @@ -1636,11 +1637,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderCreateAppResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderCreateAppResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Delete an authorization token @@ -1667,11 +1668,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderDeleteAppResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderDeleteAppResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Unifiedpush discovery Following specifications @@ -1698,11 +1699,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderUnifiedpushDiscoveryResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderUnifiedpushDiscoveryResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Receive notifications from 3rd parties @@ -1727,11 +1728,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 201) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderPushResponse201ApplicationJson), )! as NextcloudUnifiedPushProviderPushResponse201ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Matrix Gateway discovery @@ -1755,11 +1756,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderGatewayMatrixDiscoveryResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderGatewayMatrixDiscoveryResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } /// Matrix Gateway @@ -1783,11 +1784,11 @@ class NextcloudUnifiedPushProviderClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUnifiedPushProviderGatewayMatrixResponse200ApplicationJson), )! as NextcloudUnifiedPushProviderGatewayMatrixResponse200ApplicationJson; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } @@ -1816,11 +1817,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetPublicStatuses), )! as NextcloudUserStatusGetPublicStatuses; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getPublicStatus({required final String userId}) async { @@ -1844,11 +1845,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetPublicStatus), )! as NextcloudUserStatusGetPublicStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getStatus() async { @@ -1871,11 +1872,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetStatus), )! as NextcloudUserStatusGetStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future setStatus({required final NextcloudUserStatusType statusType}) async { @@ -1899,11 +1900,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetStatus), )! as NextcloudUserStatusGetStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future setPredefinedMessage({ @@ -1933,11 +1934,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetStatus), )! as NextcloudUserStatusGetStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future setCustomMessage({ @@ -1973,11 +1974,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusGetStatus), )! as NextcloudUserStatusGetStatus; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future clearMessage() async { @@ -1999,7 +2000,7 @@ class NextcloudUserStatusClient { if (response.statusCode == 200) { return; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future getPredefinedStatuses() async { @@ -2022,11 +2023,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusPredefinedStatuses), )! as NextcloudUserStatusPredefinedStatuses; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } Future heartbeat({required final NextcloudUserStatusType status}) async { @@ -2050,11 +2051,11 @@ class NextcloudUserStatusClient { ); if (response.statusCode == 200) { return jsonSerializers.deserialize( - json.decode(utf8.decode(response.body)), + await response.jsonBody, specifiedType: const FullType(NextcloudUserStatusHeartbeat), )! as NextcloudUserStatusHeartbeat; } - throw NextcloudApiException.fromResponse(response); // coverage:ignore-line + throw await NextcloudApiException.fromResponse(response); // coverage:ignore-line } } diff --git a/packages/nextcloud/lib/src/webdav/client.dart b/packages/nextcloud/lib/src/webdav/client.dart index d1aa4952..f7558019 100644 --- a/packages/nextcloud/lib/src/webdav/client.dart +++ b/packages/nextcloud/lib/src/webdav/client.dart @@ -29,7 +29,7 @@ class WebDavClient { ..persistentConnection = true; for (final header in { HttpHeaders.contentTypeHeader: 'application/xml', - ...rootClient.baseHeaders, + ...?rootClient.baseHeaders, if (headers != null) ...headers, if (rootClient.authentications.isNotEmpty) ...rootClient.authentications.first.headers, }.entries) { @@ -43,11 +43,7 @@ class WebDavClient { final response = await request.close(); if (!expectedCodes.contains(response.statusCode)) { - throw NextcloudApiException( - response.statusCode, - {}, // TODO - await response.bodyBytes, - ); + throw await NextcloudApiException.fromResponse(response); } return response;