From a56a15e5cb9673b6070f1fd410f9df1d2bea776d Mon Sep 17 00:00:00 2001 From: uladzimir_paliukhovich <> Date: Mon, 23 Aug 2021 15:16:02 +0300 Subject: [PATCH 1/6] Added dollars to all generated classes like mappings and jsonSerializable converter --- CHANGELOG.md | 4 ++++ .../swagger_additions_generator.dart | 18 +++++++++--------- pubspec.yaml | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a95c29..be236f29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0-prerelease.6 + +* **BREAKING**: Added dollar signs to generated converter and mappings + # 2.1.0-prerelease.5 * Fixed Issue ([#212](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/212)) diff --git a/lib/src/code_generators/swagger_additions_generator.dart b/lib/src/code_generators/swagger_additions_generator.dart index efca9da4..affd4a11 100644 --- a/lib/src/code_generators/swagger_additions_generator.dart +++ b/lib/src/code_generators/swagger_additions_generator.dart @@ -134,12 +134,12 @@ String? _dateToJson(DateTime? date) { return ''; } return ''' -typedef JsonFactory = T Function(Map json); +typedef \$JsonFactory = T Function(Map json); -class CustomJsonDecoder { - CustomJsonDecoder(this.factories); +class \$CustomJsonDecoder { + \$CustomJsonDecoder(this.factories); - final Map factories; + final Map factories; dynamic decode(dynamic entity) { if (entity is Iterable) { @@ -159,7 +159,7 @@ class CustomJsonDecoder { T _decodeMap(Map values) { final jsonFactory = factories[T]; - if (jsonFactory == null || jsonFactory is! JsonFactory) { + if (jsonFactory == null || jsonFactory is! \$JsonFactory) { return throw "Could not find factory for type \$T. Is '\$T: \$T.fromJsonFactory' included in the CustomJsonDecoder instance creation in bootstrapper.dart?"; } @@ -170,7 +170,7 @@ class CustomJsonDecoder { values.where((v) => v != null).map((v) => decode(v) as T).toList(); } -class JsonSerializableConverter extends chopper.JsonConverter { +class \$JsonSerializableConverter extends chopper.JsonConverter { @override chopper.Response convertResponse(chopper.Response response) { if (response.bodyString.isEmpty) { @@ -181,11 +181,11 @@ class JsonSerializableConverter extends chopper.JsonConverter { final jsonRes = super.convertResponse(response); return jsonRes.copyWith( - body: jsonDecoder.decode(jsonRes.body) as ResultType); + body: \$jsonDecoder.decode(jsonRes.body) as ResultType); } } -final jsonDecoder = CustomJsonDecoder(${fileName.pascalCase}JsonDecoderMappings); +final \$jsonDecoder = \$CustomJsonDecoder(${fileName.pascalCase}JsonDecoderMappings); '''; } @@ -200,7 +200,7 @@ final jsonDecoder = CustomJsonDecoder(${fileName.pascalCase}JsonDecoderMappings) : '/*baseUrl: YOUR_BASE_URL*/'; final converterString = options.withConverter - ? 'converter: JsonSerializableConverter(),' + ? 'converter: \$JsonSerializableConverter(),' : 'converter: chopper.JsonConverter(),'; final chopperClientBody = ''' diff --git a/pubspec.yaml b/pubspec.yaml index 9175b809..4f63f89d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: swagger_dart_code_generator -version: 2.1.0-prerelease.5 +version: 2.1.0-prerelease.6 homepage: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator repository: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator From d31e62e3f777b01cab1b1975af90cf251f257b36 Mon Sep 17 00:00:00 2001 From: uladzimir_paliukhovich <> Date: Mon, 23 Aug 2021 18:11:18 +0300 Subject: [PATCH 2/6] Fixed some things --- lib/src/code_generators/constants.dart | 2 ++ .../swagger_models_generator.dart | 30 +++++++++---------- .../swagger_requests_generator.dart | 8 +---- lib/src/models/generator_options.dart | 4 --- lib/src/models/generator_options.g2.dart | 3 -- 5 files changed, 17 insertions(+), 30 deletions(-) diff --git a/lib/src/code_generators/constants.dart b/lib/src/code_generators/constants.dart index d7c8b9cc..298d87fd 100644 --- a/lib/src/code_generators/constants.dart +++ b/lib/src/code_generators/constants.dart @@ -53,6 +53,8 @@ const kArray = 'array'; const kEnum = 'enum'; const kBody = 'body'; +const kDynamic = 'dynamic'; + const kServiceHeader = ''' // ************************************************************************** // SwaggerChopperGenerator diff --git a/lib/src/code_generators/swagger_models_generator.dart b/lib/src/code_generators/swagger_models_generator.dart index 360cab4f..bd57003d 100644 --- a/lib/src/code_generators/swagger_models_generator.dart +++ b/lib/src/code_generators/swagger_models_generator.dart @@ -146,16 +146,8 @@ abstract class SwaggerModelsGenerator { neededResponse['schema']['properties'] != null) { final pathText = path.split('/').map((e) => e.pascalCase).join(); final requestText = request.pascalCase; - final operationId = requestValue['operationId'] as String? ?? ''; - - if (options.usePathForRequestNames || operationId.isEmpty) { - results['$pathText$requestText\$Response'] = - neededResponse['schema']; - } else { - results['${SwaggerModelsGenerator.getValidatedClassName(operationId)}\$Response'] = - neededResponse['schema']; - } - //results['$pathText$requestText\$Response'] = neededResponse['schema']; + + results['$pathText$requestText\$Response'] = neededResponse['schema']; } }); }); @@ -393,7 +385,7 @@ abstract class SwaggerModelsGenerator { } if (typeName.isEmpty) { - typeName = 'dynamic'; + typeName = kDynamic; } final unknownEnumValue = generateUnknownEnumValue( @@ -403,9 +395,13 @@ abstract class SwaggerModelsGenerator { final includeIfNullString = generateIncludeIfNullString(options); + if (typeName != kDynamic) { + typeName += '?'; + } + final jsonKeyContent = "@JsonKey(name: '$propertyName'$includeIfNullString$dateToJsonValue$unknownEnumValue)\n"; - return '\t$jsonKeyContent\tfinal $typeName? ${SwaggerModelsGenerator.generateFieldName(propertyName)};'; + return '\t$jsonKeyContent\tfinal $typeName ${SwaggerModelsGenerator.generateFieldName(propertyName)};'; } String generateUnknownEnumValue(List allEnumNames, @@ -586,7 +582,7 @@ abstract class SwaggerModelsGenerator { if (basicTypesMap.containsKey(typeName)) { typeName = basicTypesMap[typeName]!; - } else if (typeName != 'dynamic') { + } else if (typeName != kDynamic) { typeName = typeName.pascalCase; } } else if (!allEnumNames.contains('enums.$typeName') && @@ -624,8 +620,6 @@ abstract class SwaggerModelsGenerator { final includeIfNullString = generateIncludeIfNullString(options); - //typeName = SwaggerModelsGenerator.getValidatedClassName(typeName); - String jsonKeyContent; if (unknownEnumValue.isEmpty) { jsonKeyContent = @@ -694,7 +688,11 @@ abstract class SwaggerModelsGenerator { jsonKeyContent += ')\n'; } - return ''' $jsonKeyContent final $typeName? ${SwaggerModelsGenerator.generateFieldName(propertyName)};'''; + if (typeName != kDynamic) { + typeName += '?'; + } + + return ''' $jsonKeyContent final $typeName ${SwaggerModelsGenerator.generateFieldName(propertyName)};'''; } String generatePropertyContentByType( diff --git a/lib/src/code_generators/swagger_requests_generator.dart b/lib/src/code_generators/swagger_requests_generator.dart index 5fe0283c..abd68313 100644 --- a/lib/src/code_generators/swagger_requests_generator.dart +++ b/lib/src/code_generators/swagger_requests_generator.dart @@ -553,13 +553,7 @@ class SwaggerRequestsGenerator { required String path, required String requestType, }) { - if (options.usePathForRequestNames || swaggerRequest.operationId.isEmpty) { - return SwaggerModelsGenerator.generateRequestName(path, requestType); - } else { - return SwaggerModelsGenerator.getValidatedClassName( - swaggerRequest.operationId) - .camelCase; - } + return SwaggerModelsGenerator.generateRequestName(path, requestType); } static SwaggerResponse? getSuccessedResponse({ diff --git a/lib/src/models/generator_options.dart b/lib/src/models/generator_options.dart index 00a257dc..8b35677e 100644 --- a/lib/src/models/generator_options.dart +++ b/lib/src/models/generator_options.dart @@ -17,7 +17,6 @@ class GeneratorOptions { required this.inputFolder, required this.outputFolder, this.enumsCaseSensitive = true, - this.usePathForRequestNames = false, this.useRequiredAttributeForHeaders = true, this.useInheritance = true, this.includeIfNull, @@ -48,9 +47,6 @@ class GeneratorOptions { @JsonKey(defaultValue: false) final bool enumsCaseSensitive; - @JsonKey(defaultValue: false) - final bool usePathForRequestNames; - @JsonKey(defaultValue: null) final bool? includeIfNull; diff --git a/lib/src/models/generator_options.g2.dart b/lib/src/models/generator_options.g2.dart index b6ae47c4..31ddcc38 100644 --- a/lib/src/models/generator_options.g2.dart +++ b/lib/src/models/generator_options.g2.dart @@ -34,8 +34,6 @@ GeneratorOptions _$GeneratorOptionsFromJson(Map json) { inputFolder: json['input_folder'] as String? ?? '', outputFolder: json['output_folder'] as String? ?? '', enumsCaseSensitive: json['enums_case_sensitive'] as bool? ?? false, - usePathForRequestNames: - json['use_path_for_request_names'] as bool? ?? false, useRequiredAttributeForHeaders: json['use_required_attribute_for_headers'] as bool? ?? true, useInheritance: json['use_inheritance'] as bool? ?? true, @@ -61,7 +59,6 @@ Map _$GeneratorOptionsToJson(GeneratorOptions instance) => 'ignore_headers': instance.ignoreHeaders, 'use_inheritance': instance.useInheritance, 'enums_case_sensitive': instance.enumsCaseSensitive, - 'use_path_for_request_names': instance.usePathForRequestNames, 'include_if_null': instance.includeIfNull, 'input_folder': instance.inputFolder, 'output_folder': instance.outputFolder, From 70554d3948c9ff173d775e5d38a5a79acee8dcf3 Mon Sep 17 00:00:00 2001 From: uladzimir_paliukhovich <> Date: Mon, 23 Aug 2021 18:14:25 +0300 Subject: [PATCH 3/6] Updated changelog and pubspec --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be236f29..792011be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.1.0-prerelease.7 + +* Fixed Issue ([#186](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/186)) +* Fixed Issue ([#204](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/204)) + # 2.1.0-prerelease.6 * **BREAKING**: Added dollar signs to generated converter and mappings diff --git a/pubspec.yaml b/pubspec.yaml index 4f63f89d..f94b7395 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: swagger_dart_code_generator -version: 2.1.0-prerelease.6 +version: 2.1.0-prerelease.7 homepage: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator repository: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator From bfad252c603221a44633001c7d4783c2805d40c8 Mon Sep 17 00:00:00 2001 From: uladzimir_paliukhovich <> Date: Wed, 25 Aug 2021 14:43:11 +0300 Subject: [PATCH 4/6] Added example Added generation of get hashCode --- CHANGELOG.md | 6 + example/lib/example_swagger.swagger | 113 ++++++++ .../swagger_generated_code/client_index.dart | 1 + .../client_mapping.dart | 5 + .../example_swagger.swagger.chopper2.dart | 33 +++ .../example_swagger.swagger.dart | 256 ++++++++++++++++++ .../example_swagger.swagger.g2.dart | 66 +++++ .../swagger_additions_generator.dart | 3 - .../swagger_models_generator.dart | 46 ++++ lib/src/swagger_models/swagger_root.dart | 6 +- lib/src/swagger_models/swagger_root.g2.dart | 2 +- pubspec.yaml | 2 +- 12 files changed, 533 insertions(+), 6 deletions(-) create mode 100644 example/lib/example_swagger.swagger create mode 100644 example/lib/swagger_generated_code/client_index.dart create mode 100644 example/lib/swagger_generated_code/client_mapping.dart create mode 100644 example/lib/swagger_generated_code/example_swagger.swagger.chopper2.dart create mode 100644 example/lib/swagger_generated_code/example_swagger.swagger.dart create mode 100644 example/lib/swagger_generated_code/example_swagger.swagger.g2.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 792011be..d07efb62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 2.1.0-prerelease.8 + +* Fixed Issue ([#221](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/221)) +* Added generation of int get hashCode +* Added example + # 2.1.0-prerelease.7 * Fixed Issue ([#186](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/186)) diff --git a/example/lib/example_swagger.swagger b/example/lib/example_swagger.swagger new file mode 100644 index 00000000..e47a0b40 --- /dev/null +++ b/example/lib/example_swagger.swagger @@ -0,0 +1,113 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Generated API", + "version": "1.0" + }, + "tags": [ + { + "name": "tag1" + }, + { + "name": "tag2" + } + ], + "paths": { + "/rooms": { + "get": { + "operationId": "getRooms", + "parameters": [ + { + "type": "string", + "description": "Rooms owner", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "Loaded rooms", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/room" + } + } + } + } + } + }, + "/api/item/all": { + "get": { + "tags": [ + "tag1" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListCustomItem" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "room": { + "type": "object", + "properties": { + "author": { + "description": "UUIDv4 of author of last message", + "type": "string" + }, + "avatar": { + "description": "UUIDv4 of fake user as avatar of room", + "type": "string" + }, + "id": { + "description": "UUIDv4 of room", + "type": "string" + }, + "lastMessage": { + "description": "Last message payload", + "type": "string" + }, + "name": { + "description": "Fake user name as room name", + "type": "string" + } + } + }, + "CustomItem": { + "type": "object", + "properties": { + "available": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "ListCustomItem": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CustomItem" + } + } + } + } +} \ No newline at end of file diff --git a/example/lib/swagger_generated_code/client_index.dart b/example/lib/swagger_generated_code/client_index.dart new file mode 100644 index 00000000..08d3fe96 --- /dev/null +++ b/example/lib/swagger_generated_code/client_index.dart @@ -0,0 +1 @@ +export 'example_swagger.swagger.dart' show ExampleSwagger; diff --git a/example/lib/swagger_generated_code/client_mapping.dart b/example/lib/swagger_generated_code/client_mapping.dart new file mode 100644 index 00000000..efc9ccdb --- /dev/null +++ b/example/lib/swagger_generated_code/client_mapping.dart @@ -0,0 +1,5 @@ +import 'example_swagger.swagger.dart'; + +final Map)> generatedMapping = { + ...ExampleSwaggerJsonDecoderMappings, +}; diff --git a/example/lib/swagger_generated_code/example_swagger.swagger.chopper2.dart b/example/lib/swagger_generated_code/example_swagger.swagger.chopper2.dart new file mode 100644 index 00000000..ed1578b4 --- /dev/null +++ b/example/lib/swagger_generated_code/example_swagger.swagger.chopper2.dart @@ -0,0 +1,33 @@ +//Generated code + +part of 'example_swagger.swagger.dart'; + +// ************************************************************************** +// ChopperGenerator +// ************************************************************************** + +// ignore_for_file: always_put_control_body_on_new_line, always_specify_types, prefer_const_declarations +class _$ExampleSwagger extends ExampleSwagger { + _$ExampleSwagger([ChopperClient? client]) { + if (client == null) return; + this.client = client; + } + + @override + final definitionType = ExampleSwagger; + + @override + Future>> roomsGet({required String? id}) { + final $url = '/rooms'; + final $params = {'id': id}; + final $request = Request('GET', $url, client.baseUrl, parameters: $params); + return client.send, Room>($request); + } + + @override + Future> apiItemAllGet() { + final $url = '/api/item/all'; + final $request = Request('GET', $url, client.baseUrl); + return client.send($request); + } +} diff --git a/example/lib/swagger_generated_code/example_swagger.swagger.dart b/example/lib/swagger_generated_code/example_swagger.swagger.dart new file mode 100644 index 00000000..dc5a923e --- /dev/null +++ b/example/lib/swagger_generated_code/example_swagger.swagger.dart @@ -0,0 +1,256 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:collection/collection.dart'; + +import 'package:chopper/chopper.dart'; +import 'package:chopper/chopper.dart' as chopper; + +part 'example_swagger.swagger.chopper2.dart'; +part 'example_swagger.swagger.g2.dart'; + +// ************************************************************************** +// SwaggerChopperGenerator +// ************************************************************************** + +@ChopperApi() +abstract class ExampleSwagger extends ChopperService { + static ExampleSwagger create([ChopperClient? client]) { + if (client != null) { + return _$ExampleSwagger(client); + } + + final newClient = ChopperClient( + services: [_$ExampleSwagger()], + converter: $JsonSerializableConverter(), + /*baseUrl: YOUR_BASE_URL*/ + ); + return _$ExampleSwagger(newClient); + } + + /// + ///@param id Rooms owner + @Get(path: '/rooms') + Future>> roomsGet( + {@Query('id') required String? id}); + + /// + @Get(path: '/api/item/all') + Future> apiItemAllGet(); +} + +final Map)> + ExampleSwaggerJsonDecoderMappings = { + Room: Room.fromJsonFactory, + CustomItem: CustomItem.fromJsonFactory, + ListCustomItem: ListCustomItem.fromJsonFactory, +}; + +@JsonSerializable(explicitToJson: true) +class Room { + Room({ + this.author, + this.avatar, + this.id, + this.lastMessage, + this.name, + }); + + factory Room.fromJson(Map json) => _$RoomFromJson(json); + + @JsonKey(name: 'author', includeIfNull: false, defaultValue: '') + final String? author; + @JsonKey(name: 'avatar', includeIfNull: false, defaultValue: '') + final String? avatar; + @JsonKey(name: 'id', includeIfNull: false, defaultValue: '') + final String? id; + @JsonKey(name: 'lastMessage', includeIfNull: false, defaultValue: '') + final String? lastMessage; + @JsonKey(name: 'name', includeIfNull: false, defaultValue: '') + final String? name; + static const fromJsonFactory = _$RoomFromJson; + static const toJsonFactory = _$RoomToJson; + Map toJson() => _$RoomToJson(this); + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is Room && + (identical(other.author, author) || + const DeepCollectionEquality().equals(other.author, author)) && + (identical(other.avatar, avatar) || + const DeepCollectionEquality().equals(other.avatar, avatar)) && + (identical(other.id, id) || + const DeepCollectionEquality().equals(other.id, id)) && + (identical(other.lastMessage, lastMessage) || + const DeepCollectionEquality() + .equals(other.lastMessage, lastMessage)) && + (identical(other.name, name) || + const DeepCollectionEquality().equals(other.name, name))); + } + + @override + int get hashCode => + const DeepCollectionEquality().hash(author) ^ + const DeepCollectionEquality().hash(avatar) ^ + const DeepCollectionEquality().hash(id) ^ + const DeepCollectionEquality().hash(lastMessage) ^ + const DeepCollectionEquality().hash(name) ^ + runtimeType.hashCode; +} + +extension $RoomExtension on Room { + Room copyWith( + {String? author, + String? avatar, + String? id, + String? lastMessage, + String? name}) { + return Room( + author: author ?? this.author, + avatar: avatar ?? this.avatar, + id: id ?? this.id, + lastMessage: lastMessage ?? this.lastMessage, + name: name ?? this.name); + } +} + +@JsonSerializable(explicitToJson: true) +class CustomItem { + CustomItem({ + this.available, + this.description, + this.id, + this.name, + }); + + factory CustomItem.fromJson(Map json) => + _$CustomItemFromJson(json); + + @JsonKey(name: 'available', includeIfNull: false) + final bool? available; + @JsonKey(name: 'description', includeIfNull: false, defaultValue: '') + final String? description; + @JsonKey(name: 'id', includeIfNull: false, defaultValue: '') + final String? id; + @JsonKey(name: 'name', includeIfNull: false, defaultValue: '') + final String? name; + static const fromJsonFactory = _$CustomItemFromJson; + static const toJsonFactory = _$CustomItemToJson; + Map toJson() => _$CustomItemToJson(this); + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other is CustomItem && + (identical(other.available, available) || + const DeepCollectionEquality() + .equals(other.available, available)) && + (identical(other.description, description) || + const DeepCollectionEquality() + .equals(other.description, description)) && + (identical(other.id, id) || + const DeepCollectionEquality().equals(other.id, id)) && + (identical(other.name, name) || + const DeepCollectionEquality().equals(other.name, name))); + } + + @override + int get hashCode => + const DeepCollectionEquality().hash(available) ^ + const DeepCollectionEquality().hash(description) ^ + const DeepCollectionEquality().hash(id) ^ + const DeepCollectionEquality().hash(name) ^ + runtimeType.hashCode; +} + +extension $CustomItemExtension on CustomItem { + CustomItem copyWith( + {bool? available, String? description, String? id, String? name}) { + return CustomItem( + available: available ?? this.available, + description: description ?? this.description, + id: id ?? this.id, + name: name ?? this.name); + } +} + +@JsonSerializable(explicitToJson: true) +class ListCustomItem { + ListCustomItem(); + + factory ListCustomItem.fromJson(Map json) => + _$ListCustomItemFromJson(json); + + static const fromJsonFactory = _$ListCustomItemFromJson; + static const toJsonFactory = _$ListCustomItemToJson; + Map toJson() => _$ListCustomItemToJson(this); + + @override + int get hashCode => runtimeType.hashCode; +} + +typedef $JsonFactory = T Function(Map json); + +class $CustomJsonDecoder { + $CustomJsonDecoder(this.factories); + + final Map factories; + + dynamic decode(dynamic entity) { + if (entity is Iterable) { + return _decodeList(entity); + } + + if (entity is T) { + return entity; + } + + if (entity is Map) { + return _decodeMap(entity); + } + + return entity; + } + + T _decodeMap(Map values) { + final jsonFactory = factories[T]; + if (jsonFactory == null || jsonFactory is! $JsonFactory) { + return throw "Could not find factory for type $T. Is '$T: $T.fromJsonFactory' included in the CustomJsonDecoder instance creation in bootstrapper.dart?"; + } + + return jsonFactory(values); + } + + List _decodeList(Iterable values) => + values.where((v) => v != null).map((v) => decode(v) as T).toList(); +} + +class $JsonSerializableConverter extends chopper.JsonConverter { + @override + chopper.Response convertResponse( + chopper.Response response) { + if (response.bodyString.isEmpty) { + // In rare cases, when let's say 204 (no content) is returned - + // we cannot decode the missing json with the result type specified + return chopper.Response(response.base, null, error: response.error); + } + + final jsonRes = super.convertResponse(response); + return jsonRes.copyWith( + body: $jsonDecoder.decode(jsonRes.body) as ResultType); + } +} + +final $jsonDecoder = $CustomJsonDecoder(ExampleSwaggerJsonDecoderMappings); + +// ignore: unused_element +String? _dateToJson(DateTime? date) { + if (date == null) { + return null; + } + + final year = date.year.toString(); + final month = date.month < 10 ? '0${date.month}' : date.month.toString(); + final day = date.day < 10 ? '0${date.day}' : date.day.toString(); + + return '$year-$month-$day'; +} diff --git a/example/lib/swagger_generated_code/example_swagger.swagger.g2.dart b/example/lib/swagger_generated_code/example_swagger.swagger.g2.dart new file mode 100644 index 00000000..ad0b80b6 --- /dev/null +++ b/example/lib/swagger_generated_code/example_swagger.swagger.g2.dart @@ -0,0 +1,66 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'example_swagger.swagger.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Room _$RoomFromJson(Map json) { + return Room( + author: json['author'] as String? ?? '', + avatar: json['avatar'] as String? ?? '', + id: json['id'] as String? ?? '', + lastMessage: json['lastMessage'] as String? ?? '', + name: json['name'] as String? ?? '', + ); +} + +Map _$RoomToJson(Room instance) { + final val = {}; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('author', instance.author); + writeNotNull('avatar', instance.avatar); + writeNotNull('id', instance.id); + writeNotNull('lastMessage', instance.lastMessage); + writeNotNull('name', instance.name); + return val; +} + +CustomItem _$CustomItemFromJson(Map json) { + return CustomItem( + available: json['available'] as bool?, + description: json['description'] as String? ?? '', + id: json['id'] as String? ?? '', + name: json['name'] as String? ?? '', + ); +} + +Map _$CustomItemToJson(CustomItem instance) { + final val = {}; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('available', instance.available); + writeNotNull('description', instance.description); + writeNotNull('id', instance.id); + writeNotNull('name', instance.name); + return val; +} + +ListCustomItem _$ListCustomItemFromJson(Map json) { + return ListCustomItem(); +} + +Map _$ListCustomItemToJson(ListCustomItem instance) => + {}; diff --git a/lib/src/code_generators/swagger_additions_generator.dart b/lib/src/code_generators/swagger_additions_generator.dart index affd4a11..60482189 100644 --- a/lib/src/code_generators/swagger_additions_generator.dart +++ b/lib/src/code_generators/swagger_additions_generator.dart @@ -75,9 +75,6 @@ import 'package:chopper/chopper.dart' as chopper;'''; final enumsExport = hasEnums ? "export '$swaggerFileName.enums.swagger.dart';" : ''; - result.writeln(""" -import 'package:json_annotation/json_annotation.dart';"""); - if (hasModels) { result.writeln(""" import 'package:json_annotation/json_annotation.dart'; diff --git a/lib/src/code_generators/swagger_models_generator.dart b/lib/src/code_generators/swagger_models_generator.dart index bd57003d..9066dd83 100644 --- a/lib/src/code_generators/swagger_models_generator.dart +++ b/lib/src/code_generators/swagger_models_generator.dart @@ -996,6 +996,9 @@ List ${neededName.camelCase}ListFromJson( final copyWithMethod = generateCopyWithContent(generatedProperties, validatedClassName); + final getHashContent = + generateGetHashContent(generatedProperties, validatedClassName); + final equalsOverride = generateEqualsOverride(generatedProperties, validatedClassName); @@ -1010,6 +1013,8 @@ $generatedProperties \tMap toJson() => _\$${validatedClassName}ToJson(this); $equalsOverride + +$getHashContent } $copyWithMethod '''; @@ -1073,4 +1078,45 @@ $copyWithMethod return 'extension \$${validatedClassName}Extension on $validatedClassName { $validatedClassName copyWith({$spittedPropertiesJoined}) { return $validatedClassName($splittedPropertiesNamesContent);}}'; } + + String generateGetHashContent( + String generatedProperties, String validatedClassName) { + final propertiesHash = generatedProperties + .split(';') + .where((element) => element.isNotEmpty) + .map((e) => e.substring(e.indexOf('final ') + 6)) + .map((e) => e.substring(e.indexOf(' ') + 1)) + .map((e) => 'const DeepCollectionEquality().hash($e)') + .toList(); + + final allHashComponents = + [...propertiesHash, 'runtimeType.hashCode'].join(' ^\n'); + + return ''' +@override +int get hashCode => +$allHashComponents; +'''; + } } + +// @override +// int get hashCode => +// runtimeType.hashCode ^ +// const DeepCollectionEquality().hash(itemId) ^ +// const DeepCollectionEquality().hash(resolution) ^ +// const DeepCollectionEquality().hash(watchlistItemType) ^ +// const DeepCollectionEquality().hash(sourceOrInstance) ^ +// const DeepCollectionEquality().hash(duration) ^ +// const DeepCollectionEquality().hash(bookmark) ^ +// const DeepCollectionEquality().hash(isAdult) ^ +// const DeepCollectionEquality().hash(ageRating) ^ +// const DeepCollectionEquality().hash(model) ^ +// const DeepCollectionEquality().hash(showId) ^ +// const DeepCollectionEquality().hash(brandingProviderId) ^ +// const DeepCollectionEquality().hash(seasonId) ^ +// const DeepCollectionEquality().hash(instanceId) ^ +// const DeepCollectionEquality().hash(mergedId) ^ +// const DeepCollectionEquality().hash(title) ^ +// const DeepCollectionEquality().hash(sources) ^ +// const DeepCollectionEquality().hash(isAboutThisSeriesAvailable); diff --git a/lib/src/swagger_models/swagger_root.dart b/lib/src/swagger_models/swagger_root.dart index f16d7ee8..a0aeec70 100644 --- a/lib/src/swagger_models/swagger_root.dart +++ b/lib/src/swagger_models/swagger_root.dart @@ -56,7 +56,11 @@ class SwaggerRoot { _$SwaggerRootFromJson(json); } -Map _mapPaths(Map paths) { +Map _mapPaths(Map? paths) { + if (paths == null) { + return {}; + } + return paths.map((path, pathValue) { final value = pathValue as Map; final parameters = value['parameters'] as List?; diff --git a/lib/src/swagger_models/swagger_root.g2.dart b/lib/src/swagger_models/swagger_root.g2.dart index 6aaead08..2e492d8e 100644 --- a/lib/src/swagger_models/swagger_root.g2.dart +++ b/lib/src/swagger_models/swagger_root.g2.dart @@ -17,7 +17,7 @@ SwaggerRoot _$SwaggerRootFromJson(Map json) { ? null : SwaggerInfo.fromJson(json['info'] as Map), host: json['host'] as String? ?? '', - paths: _mapPaths(json['paths'] as Map) ?? {}, + paths: _mapPaths(json['paths'] as Map?) ?? {}, tags: (json['tags'] as List?) ?.map((e) => SwaggerTag.fromJson(e as Map)) .toList() ?? diff --git a/pubspec.yaml b/pubspec.yaml index f94b7395..cf7f8ccb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: swagger_dart_code_generator -version: 2.1.0-prerelease.7 +version: 2.1.0-prerelease.8 homepage: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator repository: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator From ce6e1502fc5a1639d71ad9029cd11459f0697255 Mon Sep 17 00:00:00 2001 From: VOVANELLA Date: Thu, 26 Aug 2021 17:55:22 +0300 Subject: [PATCH 5/6] Removed build_only_models parameter --- CHANGELOG.md | 4 ++++ .../swagger_additions_generator.dart | 21 +++++++------------ lib/src/models/generator_options.dart | 4 ---- lib/src/models/generator_options.g2.dart | 2 -- lib/src/swagger_code_generator.dart | 6 +++--- lib/swagger_dart_code_generator.dart | 10 +++------ pubspec.yaml | 2 +- .../additions_generator_test.dart | 8 +++---- 8 files changed, 23 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d07efb62..712d5044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0-prerelease.9 + +**BREAKING**: Removed build_only_models_parameter. Now it's always false + # 2.1.0-prerelease.8 * Fixed Issue ([#221](https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/221)) diff --git a/lib/src/code_generators/swagger_additions_generator.dart b/lib/src/code_generators/swagger_additions_generator.dart index 60482189..43c5b366 100644 --- a/lib/src/code_generators/swagger_additions_generator.dart +++ b/lib/src/code_generators/swagger_additions_generator.dart @@ -56,16 +56,13 @@ $maps}; } ///Generated imports for concrete service - String generateImportsContent(String swaggerFileName, bool hasModels, - bool buildOnlyModels, bool hasEnums) { + String generateImportsContent( + String swaggerFileName, bool hasModels, bool hasEnums) { final result = StringBuffer(); - final chopperPartImport = - buildOnlyModels ? '' : "part '$swaggerFileName.swagger.chopper.dart';"; + final chopperPartImport = "part '$swaggerFileName.swagger.chopper.dart';"; - final chopperImports = buildOnlyModels - ? '' - : '''import 'package:chopper/chopper.dart'; + final chopperImports = '''import 'package:chopper/chopper.dart'; import 'package:chopper/chopper.dart' as chopper;'''; final enumsImport = hasEnums @@ -82,9 +79,8 @@ import 'package:collection/collection.dart'; """); } - if (chopperImports.isNotEmpty) { - result.write(chopperImports); - } + result.write(chopperImports); + if (enumsImport.isNotEmpty) { result.write(enumsImport); } @@ -95,9 +91,8 @@ import 'package:collection/collection.dart'; result.write('\n\n'); - if (chopperPartImport.isNotEmpty) { - result.write(chopperPartImport); - } + result.write(chopperPartImport); + if (hasModels) { result.write("part '$swaggerFileName.swagger.g.dart';"); } diff --git a/lib/src/models/generator_options.dart b/lib/src/models/generator_options.dart index 8b35677e..84f9bd10 100644 --- a/lib/src/models/generator_options.dart +++ b/lib/src/models/generator_options.dart @@ -10,7 +10,6 @@ class GeneratorOptions { this.withConverter = true, this.ignoreHeaders = false, this.useDefaultNullForLists = false, - this.buildOnlyModels = false, this.defaultValuesMap = const [], this.defaultHeaderValuesMap = const [], this.responseOverrideValueMap = const [], @@ -59,9 +58,6 @@ class GeneratorOptions { @JsonKey(defaultValue: false) final bool useDefaultNullForLists; - @JsonKey(defaultValue: false) - final bool buildOnlyModels; - @JsonKey(defaultValue: '') final String modelPostfix; diff --git a/lib/src/models/generator_options.g2.dart b/lib/src/models/generator_options.g2.dart index 31ddcc38..c1bc9eca 100644 --- a/lib/src/models/generator_options.g2.dart +++ b/lib/src/models/generator_options.g2.dart @@ -13,7 +13,6 @@ GeneratorOptions _$GeneratorOptionsFromJson(Map json) { ignoreHeaders: json['ignore_headers'] as bool? ?? false, useDefaultNullForLists: json['use_default_null_for_lists'] as bool? ?? false, - buildOnlyModels: json['build_only_models'] as bool? ?? false, defaultValuesMap: (json['default_values_map'] as List?) ?.map((e) => DefaultValueMap.fromJson(Map.from(e as Map))) @@ -63,7 +62,6 @@ Map _$GeneratorOptionsToJson(GeneratorOptions instance) => 'input_folder': instance.inputFolder, 'output_folder': instance.outputFolder, 'use_default_null_for_lists': instance.useDefaultNullForLists, - 'build_only_models': instance.buildOnlyModels, 'model_postfix': instance.modelPostfix, 'default_values_map': instance.defaultValuesMap, 'default_header_values_map': instance.defaultHeaderValuesMap, diff --git a/lib/src/swagger_code_generator.dart b/lib/src/swagger_code_generator.dart index 82e61ea2..19113bb3 100644 --- a/lib/src/swagger_code_generator.dart +++ b/lib/src/swagger_code_generator.dart @@ -41,9 +41,9 @@ class SwaggerCodeGenerator { .generateConverterMappings(buildExtensions, hasModels); String generateImportsContent(String dartCode, String swaggerFileName, - bool hasModels, bool buildOnlyModels, bool hasEnums) => - _getSwaggerAdditionsGenerator(dartCode).generateImportsContent( - swaggerFileName, hasModels, buildOnlyModels, hasEnums); + bool hasModels, bool hasEnums) => + _getSwaggerAdditionsGenerator(dartCode) + .generateImportsContent(swaggerFileName, hasModels, hasEnums); String generateConverter( String dartCode, String fileName, GeneratorOptions options) => diff --git a/lib/swagger_dart_code_generator.dart b/lib/swagger_dart_code_generator.dart index 2148eed7..d0eb36aa 100644 --- a/lib/swagger_dart_code_generator.dart +++ b/lib/swagger_dart_code_generator.dart @@ -79,12 +79,8 @@ class SwaggerDartCodeGenerator implements Builder { final enums = codeGenerator.generateEnums( contents, getFileNameWithoutExtension(fileNameWithExtension)); - final imports = codeGenerator.generateImportsContent( - contents, - fileNameWithoutExtension, - models.isNotEmpty, - options.buildOnlyModels, - enums.isNotEmpty); + final imports = codeGenerator.generateImportsContent(contents, + fileNameWithoutExtension, models.isNotEmpty, enums.isNotEmpty); final converter = codeGenerator.generateConverter( contents, getFileNameWithoutExtension(fileNameWithExtension), options); @@ -137,7 +133,7 @@ class SwaggerDartCodeGenerator implements Builder { final result = """ $imports -${options.buildOnlyModels ? '' : requests} +$requests ${options.withConverter ? converter : ''} diff --git a/pubspec.yaml b/pubspec.yaml index cf7f8ccb..921c665f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: swagger_dart_code_generator -version: 2.1.0-prerelease.8 +version: 2.1.0-prerelease.9 homepage: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator repository: https://github.com/epam-cross-platform-lab/swagger-dart-code-generator diff --git a/test/generator_tests/additions_generator_test.dart b/test/generator_tests/additions_generator_test.dart index 37799f4a..46f4f070 100644 --- a/test/generator_tests/additions_generator_test.dart +++ b/test/generator_tests/additions_generator_test.dart @@ -17,16 +17,16 @@ void main() { }); test('Should generate correct imports', () { - final result = generator.generateImportsContent( - 'swagger.fileName', true, false, false); + final result = + generator.generateImportsContent('swagger.fileName', true, false); expect(result, contains("part 'swagger.fileName.swagger.chopper.dart';")); expect(result, contains("part 'swagger.fileName.swagger.g.dart';")); }); test('Should generate correct imports', () { - final result = generator.generateImportsContent( - 'swagger.fileName', true, false, true); + final result = + generator.generateImportsContent('swagger.fileName', true, false); expect(result, contains("import 'swagger.fileName.enums.swagger.dart' as enums;")); From 7f2e6eb774a3f1c4142e9b14cb591a92dab69446 Mon Sep 17 00:00:00 2001 From: VOVANELLA Date: Thu, 26 Aug 2021 17:58:24 +0300 Subject: [PATCH 6/6] Fixed tests --- test/generator_tests/additions_generator_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/generator_tests/additions_generator_test.dart b/test/generator_tests/additions_generator_test.dart index 46f4f070..41a6e27e 100644 --- a/test/generator_tests/additions_generator_test.dart +++ b/test/generator_tests/additions_generator_test.dart @@ -26,7 +26,7 @@ void main() { test('Should generate correct imports', () { final result = - generator.generateImportsContent('swagger.fileName', true, false); + generator.generateImportsContent('swagger.fileName', true, true); expect(result, contains("import 'swagger.fileName.enums.swagger.dart' as enums;"));