diff --git a/packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart b/packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart index 977111da303..9915777bcb7 100644 --- a/packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart +++ b/packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart @@ -15,18 +15,43 @@ String toDartName( } } - if (_dartKeywords.contains(result) || RegExp(r'^[0-9]+$', multiLine: true).hasMatch(result)) { + if (_reservedNames.contains(result) || RegExp(r'^[0-9]+$', multiLine: true).hasMatch(result)) { return '\$$result'; } return result; } -final _dartKeywords = [ +/// Helper methods to work with strings. +extension StringUtils on String { + /// Capitalizes this string. + /// + /// ```dart + /// ''.capitalize(); // '' + /// ' '.capitalize(); // '' + /// 'testValue'.capitalize(); // 'TestValue' + /// 'TestValue'.capitalize(); // 'TestValue' + /// + /// ``` + String capitalize() { + final trimmed = trimLeft(); + + if (trimmed.isEmpty) { + return this; + } + + final capitalChar = trimmed[0].toUpperCase(); + return trimmed.replaceRange(0, 1, capitalChar); + } +} + +/// A list of dart keywords and type names that need to be escaped. +const _reservedNames = [ 'abstract', 'as', 'assert', 'async', + 'bool', 'break', 'case', 'catch', @@ -37,6 +62,7 @@ final _dartKeywords = [ 'default', 'deferred', 'do', + 'double', 'dynamic', 'else', 'enum', @@ -56,12 +82,17 @@ final _dartKeywords = [ 'implements', 'import', 'in', + 'int', 'interface', 'is', 'library', + 'List', + 'Map', 'mixin', 'new', 'null', + 'num', + 'Object', 'on', 'operator', 'part', @@ -70,6 +101,7 @@ final _dartKeywords = [ 'set', 'show', 'static', + 'String', 'super', 'switch', 'sync', @@ -78,6 +110,8 @@ final _dartKeywords = [ 'true', 'try', 'typedef', + 'Uint8List', + 'Uri', 'var', 'void', 'while', diff --git a/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart b/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart index e174c4fe54a..3b5ea740390 100644 --- a/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart +++ b/packages/dynamite/dynamite/lib/src/models/type_result/some_of.dart @@ -50,12 +50,12 @@ abstract class TypeResultSomeOf extends TypeResult { late final String typeName = _typeName; String get _typeName { - final buffer = StringBuffer(r'$'); + final buffer = StringBuffer(); for (final type in optimizedSubTypes) { - buffer.write(toDartName(type.className, uppercaseFirstCharacter: true)); + buffer.write(type.className.capitalize()); } - return buffer.toString(); + return '\$${toDartName(buffer.toString(), uppercaseFirstCharacter: true)}'; } BuiltList get _optimizedSubTypes { diff --git a/packages/dynamite/dynamite/test/dart_helpers_test.dart b/packages/dynamite/dynamite/test/dart_helpers_test.dart index 521e7fd05c9..5d5f69130a3 100644 --- a/packages/dynamite/dynamite/test/dart_helpers_test.dart +++ b/packages/dynamite/dynamite/test/dart_helpers_test.dart @@ -23,5 +23,12 @@ void main() { expect(toDartName(value.$1, uppercaseFirstCharacter: true), value.$3); } }); + + test('capitalize', () { + expect(''.capitalize(), ''); + expect(' '.capitalize(), ' '); + expect('testValue'.capitalize(), 'TestValue'); + expect('TestValue'.capitalize(), 'TestValue'); + }); }); } diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.dart b/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.dart index d919d747136..86a86d41831 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.dart +++ b/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.dart @@ -40,6 +40,13 @@ class Client extends DynamiteClient { /// Parameters: /// * [contentString] /// * [contentParameter] + /// * [array] + /// * [$bool] + /// * [string] + /// * [stringBinary] + /// * [$int] + /// * [$double] + /// * [$num] /// /// Status codes: /// * 200 @@ -49,10 +56,24 @@ class Client extends DynamiteClient { Future> $get({ final ContentString>? contentString, final ContentString>? contentParameter, + final List? array, + final bool? $bool, + final String? string, + final Uint8List? stringBinary, + final int? $int, + final double? $double, + final num? $num, }) async { final rawResponse = $getRaw( contentString: contentString, contentParameter: contentParameter, + array: array, + $bool: $bool, + string: string, + stringBinary: stringBinary, + $int: $int, + $double: $double, + $num: $num, ); return rawResponse.future; @@ -66,6 +87,13 @@ class Client extends DynamiteClient { /// Parameters: /// * [contentString] /// * [contentParameter] + /// * [array] + /// * [$bool] + /// * [string] + /// * [stringBinary] + /// * [$int] + /// * [$double] + /// * [$num] /// /// Status codes: /// * 200 @@ -76,6 +104,13 @@ class Client extends DynamiteClient { DynamiteRawResponse $getRaw({ final ContentString>? contentString, final ContentString>? contentParameter, + final List? array, + final bool? $bool, + final String? string, + final Uint8List? stringBinary, + final int? $int, + final double? $double, + final num? $num, }) { final pathParameters = {}; final queryParameters = {}; @@ -100,6 +135,27 @@ class Client extends DynamiteClient { ]), ); } + if (array != null) { + queryParameters['array'] = array.map((final e) => e.toString()); + } + if ($bool != null) { + queryParameters['bool'] = $bool.toString(); + } + if (string != null) { + queryParameters['string'] = string; + } + if (stringBinary != null) { + queryParameters['string_binary'] = stringBinary.toString(); + } + if ($int != null) { + queryParameters['int'] = $int.toString(); + } + if ($double != null) { + queryParameters['double'] = $double.toString(); + } + if ($num != null) { + queryParameters['num'] = $num.toString(); + } var uri = Uri.parse(UriTemplate('/').expand(pathParameters)); if (queryParameters.isNotEmpty) { uri = uri.replace(queryParameters: queryParameters); @@ -188,7 +244,8 @@ final Serializers serializers = (Serializers().toBuilder() ]), ContentStringBuilder>.new, ) - ..add(ContentString.serializer)) + ..add(ContentString.serializer) + ..addBuilderFactory(const FullType(BuiltList, [FullType(JsonObject)]), ListBuilder.new)) .build(); @visibleForTesting diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.json b/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.json index ecf3fd6713c..6bcaf849472 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.json +++ b/packages/dynamite/dynamite_end_to_end_test/lib/parameters.openapi.json @@ -31,6 +31,57 @@ } } } + }, + { + "name": "array", + "in": "query", + "schema": { + "type": "array" + } + }, + { + "name": "bool", + "in": "query", + "schema": { + "type": "boolean" + } + }, + { + "name": "string", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "string_binary", + "in": "query", + "schema": { + "type": "string", + "format": "binary" + } + }, + { + "name": "int", + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "double", + "in": "query", + "schema": { + "type": "number", + "format": "float" + } + }, + { + "name": "num", + "in": "query", + "schema": { + "type": "number" + } } ], "responses": { diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.dart b/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.dart index bd102c92737..c58949a595f 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.dart +++ b/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.dart @@ -36,6 +36,18 @@ class Client extends DynamiteClient { ); } +typedef $Object = dynamic; + +typedef $String = dynamic; + +typedef $Uri = dynamic; + +typedef $Uint8List = dynamic; + +typedef $List = dynamic; + +typedef $Map = dynamic; + @BuiltValue(instantiable: false) abstract interface class $BaseInterface { @BuiltValueField(wireName: 'bool') diff --git a/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.json b/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.json index 47b500be45c..5f2954fcb3b 100644 --- a/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.json +++ b/packages/dynamite/dynamite_end_to_end_test/lib/types.openapi.json @@ -51,6 +51,24 @@ } } } + }, + "Object": { + "type": "object" + }, + "String": { + "type": "object" + }, + "Uri": { + "type": "object" + }, + "Uint8List": { + "type": "object" + }, + "List": { + "type": "object" + }, + "Map": { + "type": "object" } } }, diff --git a/packages/dynamite/dynamite_end_to_end_test/test/typestest.dart b/packages/dynamite/dynamite_end_to_end_test/test/types_test.dart similarity index 100% rename from packages/dynamite/dynamite_end_to_end_test/test/typestest.dart rename to packages/dynamite/dynamite_end_to_end_test/test/types_test.dart