From a785dfbbdf99e340ba9e676bf09a3d33b560c90c Mon Sep 17 00:00:00 2001 From: XuanTung95 Date: Sat, 3 Feb 2024 22:20:23 +0700 Subject: [PATCH] feat: Add support @Extras() (#648) * fear: Add support @Extras() * Fix dependencies error and update version. * remove path dependency --------- Co-authored-by: Xuan Tung Co-authored-by: Trevor Wang --- generator/CHANGELOG.md | 10 +++++ generator/lib/src/generator.dart | 47 ++++++++++++++++++- generator/pubspec.yaml | 4 +- generator/test/src/generator_test_src.dart | 52 ++++++++++++++++++++-- retrofit/CHANGELOG.md | 11 +++++ retrofit/lib/dio.dart | 12 +++++ retrofit/pubspec.yaml | 2 +- 7 files changed, 130 insertions(+), 8 deletions(-) diff --git a/generator/CHANGELOG.md b/generator/CHANGELOG.md index a2f60a135..8ed7a4283 100644 --- a/generator/CHANGELOG.md +++ b/generator/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 8.1.0 + +- Added `@Extras` to pass extra options to dio requests, response, transformer and interceptors. + + Example : + ```dart + @http.POST('/path/') + Future myMethod(@Extras() Map extras); + ``` + ## 8.0.6 - @useResult diff --git a/generator/lib/src/generator.dart b/generator/lib/src/generator.dart index cf3c4a709..45ce0d071 100644 --- a/generator/lib/src/generator.dart +++ b/generator/lib/src/generator.dart @@ -2159,7 +2159,7 @@ ${bodyName.displayName} == null String localExtraVar, ) { blocks.add( - declareConst(localExtraVar) + declareFinal(localExtraVar) .assign( literalMap( _getMethodAnnotations(m, retrofit.Extra) @@ -2195,6 +2195,51 @@ ${bodyName.displayName} == null ) .statement, ); + + final extraMap = _getAnnotations(m, retrofit.Extras); + for (final p in extraMap.keys) { + final type = p.type; + final displayName = p.displayName; + final Expression value; + if (_isBasicType(type) || type.isDartCoreList || type.isDartCoreMap) { + value = refer(displayName); + } else if (_typeChecker(ProtobufEnum).isSuperTypeOf(type)) { + value = type.nullabilitySuffix == NullabilitySuffix.question + ? refer(p.displayName).nullSafeProperty('value') + : refer(p.displayName).property('value'); + } else { + switch (clientAnnotation.parser) { + case retrofit.Parser.JsonSerializable: + value = p.type.nullabilitySuffix == NullabilitySuffix.question + ? refer(displayName).nullSafeProperty('toJson').call([]) + : refer(displayName).property('toJson').call([]); + break; + case retrofit.Parser.MapSerializable: + value = p.type.nullabilitySuffix == NullabilitySuffix.question + ? refer(displayName).nullSafeProperty('toMap').call([]) + : refer(displayName).property('toMap').call([]); + break; + case retrofit.Parser.DartJsonMapper: + value = refer(displayName); + break; + case retrofit.Parser.FlutterCompute: + value = refer( + 'await compute(serialize${_displayString(p.type)}, ${p.displayName})', + ); + break; + } + } + + final emitter = DartEmitter(useNullSafetySyntax: true); + final buffer = StringBuffer(); + value.accept(emitter, buffer); + if (type.nullabilitySuffix == NullabilitySuffix.question) { + refer('?? {}').accept(emitter, buffer); + } + final expression = refer(buffer.toString()); + + blocks.add(refer('$localExtraVar.addAll').call([expression]).statement); + } } bool _missingToJson(ClassElement ele) { diff --git a/generator/pubspec.yaml b/generator/pubspec.yaml index 0b6a222bb..156e128b8 100644 --- a/generator/pubspec.yaml +++ b/generator/pubspec.yaml @@ -6,7 +6,7 @@ topics: - build-runner - codegen - api -version: 8.0.3 +version: 8.1.0 environment: sdk: '>=2.19.0 <4.0.0' @@ -17,7 +17,7 @@ dependencies: code_builder: ^4.4.0 dart_style: ^2.3.0 dio: ^5.0.0 - retrofit: ^4.0.2 + retrofit: ^4.1.0 source_gen: ^1.3.0 tuple: ^2.0.1 protobuf: ^3.1.0 diff --git a/generator/test/src/generator_test_src.dart b/generator/test/src/generator_test_src.dart index 0556770e0..5c81e47ab 100644 --- a/generator/test/src/generator_test_src.dart +++ b/generator/test/src/generator_test_src.dart @@ -46,7 +46,7 @@ abstract class BaseUrl {} @ShouldGenerate( ''' - const _extra = {}; + final _extra = {}; ''', contains: true, ) @@ -59,7 +59,7 @@ abstract class EmptyExtras { @ShouldGenerate( ''' - const _extra = {'key': 'value'}; + final _extra = {'key': 'value'}; ''', contains: true, ) @@ -72,7 +72,7 @@ abstract class ExtrasWithPrimitiveValues { @ShouldGenerate( ''' - const _extra = { + final _extra = { 'key': 'value', 'key2': 'value2', }; @@ -89,7 +89,7 @@ abstract class MultipleExtrasWithPrimitiveValues { @ShouldGenerate( ''' - const _extra = {'key': CustomConstant()}; + final _extra = {'key': CustomConstant()}; ''', contains: true, ) @@ -100,6 +100,50 @@ abstract class ExtrasWithCustomConstant { Future list(); } +@ShouldGenerate( + ''' + final _extra = {}; + _extra.addAll(extras ?? {}); +''', + contains: true, +) +@RestApi() +abstract class TestExtrasWithNullable { + @GET('/list/') + Future list(@Extras() Map? extras); +} + +@ShouldGenerate( + ''' + final _extra = {'key': 'value'}; + _extra.addAll(extras); + ''', + contains: true, +) +@RestApi() +abstract class TestExtrasWithMap { + @GET('/list/') + @Extra({'key': 'value'}) + Future list( + @Extras() Map extras, + ); +} + +@ShouldGenerate( + ''' + final _extra = {}; + _extra.addAll(u.toJson()); + ''', + contains: true, +) +@RestApi() +abstract class TestExtrasWithObject { + @GET('/list/') + Future list( + @Extras() User u, + ); +} + class CustomConstant { const CustomConstant(); } diff --git a/retrofit/CHANGELOG.md b/retrofit/CHANGELOG.md index ad0a4f98a..0faf5b1ac 100644 --- a/retrofit/CHANGELOG.md +++ b/retrofit/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 4.1.0 + +- Added `@Extras` to pass extra options to dio requests, response, transformer and interceptors. + + Example : + + ```dart + @http.POST('/path/') + Future myMethod(@Extras() Map extras); + ``` + ## 4.0.0 - Update dio to ^5.0.0 diff --git a/retrofit/lib/dio.dart b/retrofit/lib/dio.dart index ae63ca272..35c1e2a46 100644 --- a/retrofit/lib/dio.dart +++ b/retrofit/lib/dio.dart @@ -10,6 +10,18 @@ class Extra { const Extra(this.data); } +/// Extra data that will be passed to dio's request, response, transformer and interceptors. +/// Simple Example: +/// +///``` +/// @GET("/get") +/// Future foo(@Extras() Map extras) +///``` +@immutable +class Extras { + const Extras(); +} + @immutable class CancelRequest { const CancelRequest(); diff --git a/retrofit/pubspec.yaml b/retrofit/pubspec.yaml index f6458ac6d..1b6e29964 100644 --- a/retrofit/pubspec.yaml +++ b/retrofit/pubspec.yaml @@ -2,7 +2,7 @@ name: retrofit description: retrofit.dart is an dio client generator using source_gen and inspired by Chopper and Retrofit. homepage: https://mings.in/retrofit.dart/ repository: https://github.com/trevorwang/retrofit.dart/ -version: 4.0.2 +version: 4.1.0 environment: sdk: '>=2.17.0 <4.0.0'