From 1b77ed152065aee6e792f1448406774628c5c8bb Mon Sep 17 00:00:00 2001 From: Denis Averin <59285247+Denis-Averin@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:08:44 +0500 Subject: [PATCH] Add documentation for Dart (#98) --- codegen/Templates/dart/api.mustache | 14 ++++---- codegen/Templates/dart/api_client.mustache | 34 ++++++++++++------- codegen/Templates/dart/api_exception.mustache | 15 ++++---- codegen/Templates/dart/api_helper.mustache | 18 ++++------ .../dart/auth/authentication.mustache | 4 +++ codegen/Templates/dart/auth/oauth.mustache | 14 ++++++-- codegen/Templates/dart/class.mustache | 19 ++++++----- codegen/Templates/dart/enum.mustache | 30 +++++++++------- 8 files changed, 89 insertions(+), 59 deletions(-) diff --git a/codegen/Templates/dart/api.mustache b/codegen/Templates/dart/api.mustache index 5eb4deb..3fc11b3 100644 --- a/codegen/Templates/dart/api.mustache +++ b/codegen/Templates/dart/api.mustache @@ -7,10 +7,12 @@ import '../api_helper.dart'; {{#operations}} +/// {{classname}} class {{classname}} { - {{classname}}(this.apiClient) {} + /// Constructor + {{classname}}(this._apiClient) {} - final ApiClient apiClient; + final ApiClient _apiClient; {{#operation}} /// @@ -77,7 +79,7 @@ class {{classname}} { } {{/hasFormParams}} - final response = await apiClient.invokeAPI(requestPath, + final response = await _apiClient.invokeAPI(requestPath, '{{httpMethod}}', queryParams, postBody, @@ -91,18 +93,18 @@ class {{classname}} { } else { return {{#isListContainer}} - {{#returnType}}(apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();{{/returnType}} + {{#returnType}}(_apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();{{/returnType}} {{/isListContainer}} {{^isListContainer}} {{#isMapContainer}} - {{#returnType}}{{{returnType}}}.from(apiClient.deserialize(response.body, '{{{returnType}}}')) {{/returnType}}; + {{#returnType}}{{{returnType}}}.from(_apiClient.deserialize(response.body, '{{{returnType}}}')) {{/returnType}}; {{/isMapContainer}} {{^isMapContainer}} {{#isResponseFile}} response.bodyBytes; {{/isResponseFile}} {{^isResponseFile}} - {{#returnType}}apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}} {{/returnType}}; + {{#returnType}}_apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}} {{/returnType}}; {{/isResponseFile}} {{/isMapContainer}} {{/isListContainer}} diff --git a/codegen/Templates/dart/api_client.mustache b/codegen/Templates/dart/api_client.mustache index 8ec01d0..ed56bca 100644 --- a/codegen/Templates/dart/api_client.mustache +++ b/codegen/Templates/dart/api_client.mustache @@ -8,15 +8,20 @@ import '../aspose_barcode_cloud.dart'; import 'api_helper.dart'; import 'auth/authentication.dart'; +/// Current SDK Version const SDK_VERSION = "{{pubVersion}}"; +/// ApiClient is responsible for making HTTP requests to the API. class ApiClient { - late final String basePath; - final httpClient = Http.Client(); + late final String _basePath; + final _httpClient = Http.Client(); + /// SDK header name static const String API_SDK_HEADER = "x-aspose-client"; + /// SDK name static const String SDK_NAME = "dart sdk"; + /// Aspose client version header name static const String API_CLIENT_VERSION_HEADER = "x-aspose-client-version"; Map _defaultHeaderMap = { @@ -29,8 +34,9 @@ class ApiClient { final _regList = RegExp(r'^List<(.*)>$'); final _regMap = RegExp(r'^Map$'); + /// Constructor ApiClient(Configuration config) { - this.basePath = config.basePath; + this._basePath = config.basePath; _authentication = OAuth( clientId: config.clientId, clientSecret: config.clientSecret, @@ -38,6 +44,7 @@ class ApiClient { tokenUrl: config.tokenUrl); } + /// Add default header value by key void addDefaultHeader(String key, String value) { _defaultHeaderMap[key] = value; } @@ -85,6 +92,7 @@ class ApiClient { throw ApiException(0, 'Could not find a suitable class for deserialization'); } + /// Deserialize the response into the target type. dynamic deserialize(String jsonVal, String targetType) { // Remove all spaces. Necessary for reg expressions as well. targetType = targetType.replaceAll(' ', ''); @@ -97,6 +105,7 @@ class ApiClient { return _deserialize(decodedJson, targetType); } + /// Serialize the object into a JSON string. String serialize(Object? obj) { String serialized = ''; if (obj == null) { @@ -107,8 +116,9 @@ class ApiClient { return serialized; } - // We don't use a Map for queryParams. - // If collectionFormat is 'multi' a key might appear multiple times. + /// Invoke HTTP request + /// We don't use a Map for queryParams. + /// If collectionFormat is 'multi' a key might appear multiple times. Future invokeAPI(String path, String method, List queryParams, @@ -125,7 +135,7 @@ class ApiClient { '?' + ps.join('&') : ''; - final String url = basePath + path + queryString; + final String url = _basePath + path + queryString; headerParams.addAll(_defaultHeaderMap); headerParams['Content-Type'] = contentType; @@ -136,21 +146,21 @@ class ApiClient { request.files.addAll(body.files); request.headers.addAll(body.headers); request.headers.addAll(headerParams); - final response = await httpClient.send(request); + final response = await _httpClient.send(request); return Http.Response.fromStream(response); } else { final msgBody = contentType == "application/x-www-form-urlencoded" ? formParams : serialize(body); switch(method) { case "POST": - return httpClient.post(Uri.parse(url), headers: headerParams, body: msgBody); + return _httpClient.post(Uri.parse(url), headers: headerParams, body: msgBody); case "PUT": - return httpClient.put(Uri.parse(url), headers: headerParams, body: msgBody); + return _httpClient.put(Uri.parse(url), headers: headerParams, body: msgBody); case "DELETE": - return httpClient.delete(Uri.parse(url), headers: headerParams); + return _httpClient.delete(Uri.parse(url), headers: headerParams); case "PATCH": - return httpClient.patch(Uri.parse(url), headers: headerParams, body: msgBody); + return _httpClient.patch(Uri.parse(url), headers: headerParams, body: msgBody); default: - return httpClient.get(Uri.parse(url), headers: headerParams); + return _httpClient.get(Uri.parse(url), headers: headerParams); } } } diff --git a/codegen/Templates/dart/api_exception.mustache b/codegen/Templates/dart/api_exception.mustache index 027c8b5..97161ee 100644 --- a/codegen/Templates/dart/api_exception.mustache +++ b/codegen/Templates/dart/api_exception.mustache @@ -1,18 +1,21 @@ +/// Represents an exception that is thrown when an error occurs in the API. class ApiException implements Exception { - int code = 0; - String? message; + /// The error code. + final int code; + /// The error message + final String message; + /// The inner exception Exception? innerException; + /// The stack trace StackTrace? stackTrace; + /// Constructor ApiException(this.code, this.message); + /// Constructor with inner exception ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace); String toString() { - if (message == null) { - return "ApiException"; - } - if (innerException == null) { return "ApiException $code: $message"; } diff --git a/codegen/Templates/dart/api_helper.mustache b/codegen/Templates/dart/api_helper.mustache index 7c2f998..493f044 100644 --- a/codegen/Templates/dart/api_helper.mustache +++ b/codegen/Templates/dart/api_helper.mustache @@ -2,14 +2,18 @@ import '../aspose_barcode_cloud.dart'; const _delimiters = const {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'}; +/// Represents a query parameter. class QueryParam { - String name; - String value; + /// The name of the parameter. + final String name; + /// The value of the parameter. + final String value; + /// Constructor QueryParam(this.name, this.value); } -// port from Java version +/// port from Java version Iterable convertParametersForCollectionFormat( String collectionFormat, String name, dynamic value) { final params = []; @@ -45,14 +49,6 @@ String parameterToString(dynamic value) { return ''; } else if (value is DateTime) { return value.toUtc().toIso8601String(); - {{#models}} - {{#model}} - {{#isEnum}} - } else if (value is {{classname}}) { - return {{classname}}.encode(value).toString(); - {{/isEnum}} - {{/model}} - {{/models}} } else { return value.toString(); } diff --git a/codegen/Templates/dart/auth/authentication.mustache b/codegen/Templates/dart/auth/authentication.mustache index 8867e52..f5d9fd4 100644 --- a/codegen/Templates/dart/auth/authentication.mustache +++ b/codegen/Templates/dart/auth/authentication.mustache @@ -1,5 +1,9 @@ import '../api_helper.dart'; +/// The base class for all authentications. +/// +/// To use this class, extend it and implement the `applyToParams` method. +/// This method will be called before every HTTP request to apply the authentication settings. abstract class Authentication { /// Apply authentication settings to header and query params. diff --git a/codegen/Templates/dart/auth/oauth.mustache b/codegen/Templates/dart/auth/oauth.mustache index 0447039..f60b580 100644 --- a/codegen/Templates/dart/auth/oauth.mustache +++ b/codegen/Templates/dart/auth/oauth.mustache @@ -6,13 +6,20 @@ import '../api_exception.dart'; import '../api_helper.dart'; import 'authentication.dart'; +/// OAuth 2.0 authentication class OAuth implements Authentication { - String? clientId; - String? clientSecret; - String tokenUrl; + /// Client Id from https://dashboard.aspose.cloud/applications + final String? clientId; + /// Client Secret from https://dashboard.aspose.cloud/applications + final String? clientSecret; + /// URL to get the token + final String tokenUrl; + /// Access token value String? accessToken; + /// Token expiration date DateTime? tokenExpiration; + /// Constructor OAuth( {this.clientId, this.clientSecret, @@ -41,6 +48,7 @@ class OAuth implements Authentication { headerParams["Authorization"] = "Bearer " + accessToken!; } + /// Fetches the token from the OAuth server Future fetchToken() async { final request = MultipartRequest('POST', Uri.parse(tokenUrl)) ..fields['grant_type'] = 'client_credentials' diff --git a/codegen/Templates/dart/class.mustache b/codegen/Templates/dart/class.mustache index d1e4be2..ccc4e78 100644 --- a/codegen/Templates/dart/class.mustache +++ b/codegen/Templates/dart/class.mustache @@ -2,11 +2,14 @@ // ignore_for_file: deprecated_member_use_from_same_package import '../../aspose_barcode_cloud.dart'; +/// {{#description}}{{{description}}}{{/description}}{{^description}}{{{classname}}}{{/description}} class {{classname}} { - {{#vars}}{{#description}}/* {{{description}}} */{{/description}} + {{#vars}} + /// {{#description}}{{{description}}}{{/description}}{{^description}}{{{name}}}{{/description}} {{{datatype}}}? {{name}} = {{{defaultValue}}}; {{#allowableValues}}{{#min}} // range from {{min}} to {{max}}{{/min}}//{{^min}}enum {{name}}Enum { {{#values}} {{.}}, {{/values}} };{{/min}}{{/allowableValues}} {{/vars}} + /// Constructor {{classname}}(); @override @@ -14,6 +17,7 @@ class {{classname}} { return '{{classname}}[{{#vars}}{{name}}=${{name}}, {{/vars}}]'; } + /// Creates a {{classname}} instance from a JSON representation. {{classname}}.fromJson(Map json) { {{#vars}} {{#isDateTime}} @@ -43,6 +47,7 @@ class {{classname}} { {{/vars}} } + /// Returns a JSON representation of {{classname}}. Map toJson() { return { {{#vars}} @@ -51,15 +56,11 @@ class {{classname}} { }; } + /// Converts a list of JSON objects to a list of {{classname}} instances. + /// + /// @param json The list of JSON objects to convert. + /// @return A list of {{classname}} instances. static List<{{classname}}> listFromJson(List json) { return json.map((value) => {{classname}}.fromJson(value)).toList(); } - - static Map mapFromJson(Map> json) { - final map = Map(); - if (json.isNotEmpty) { - json.forEach((String key, Map value) => map[key] = {{classname}}.fromJson(value)); - } - return map; - } } diff --git a/codegen/Templates/dart/enum.mustache b/codegen/Templates/dart/enum.mustache index b489d7e..ab3112f 100644 --- a/codegen/Templates/dart/enum.mustache +++ b/codegen/Templates/dart/enum.mustache @@ -1,8 +1,10 @@ +/// {{{description}}} +/// {{classname}}: {{#allowableValues}}{{values}}{{/allowableValues}} class {{classname}} { - /// The underlying value of this enum member. - {{dataType}}? value; + /// The underlying value of {{classname}} enum. + late final {{dataType}} _value; - {{classname}}._internal(this.value); + {{classname}}._internal(this._value); {{#allowableValues}} {{#enumVars}} @@ -13,31 +15,35 @@ class {{classname}} { {{/enumVars}} {{/allowableValues}} + /// Creates a {{classname}} instance from a JSON representation. {{classname}}.fromJson(dynamic data) { switch (data) { {{#allowableValues}} {{#enumVars}} - case {{{value}}}: value = data; break; + case {{{value}}}: {{/enumVars}} + _value = data; + break; {{/allowableValues}} default: throw Exception('Unknown enum value to decode: $data'); } } - static dynamic encode({{classname}} data) { - return data.value; - } - + /// Returns a JSON representation of {{classname}}. {{dataType}}? toJson() { - return value; + return _value; } @override String toString() { - return value == null ? "null" : value.toString(); + return _value.toString(); } - static List<{{classname}}> listFromJson(List json) { + /// Converts a list of JSON objects to a list of {{classname}} instances. + /// + /// @param json The list of JSON objects to convert. + /// @return A list of {{classname}} instances. + static List<{{classname}}> listFromJson(List json) { return json.map((value) => {{classname}}.fromJson(value)).toList(); - } + } }