From 7d357f4ef474091aeac12c48790a4dc20a479f65 Mon Sep 17 00:00:00 2001 From: Muhammad Mohiuddin Date: Mon, 30 Sep 2024 00:17:55 +0200 Subject: [PATCH] Read nullable property from anyOf types (#261) --- .../src/parser/parser/open_api_parser.dart | 15 ++++++++++- .../expected_files/models/one_of_element.dart | 5 ++-- .../of_like_class.3.1/of_like_class.3.1.json | 11 ++++++++ .../models/class_with_nullable_types.dart | 3 +++ .../e2e/tests/nullable_types/openapi.yaml | 26 +++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/swagger_parser/lib/src/parser/parser/open_api_parser.dart b/swagger_parser/lib/src/parser/parser/open_api_parser.dart index 24776f9e..ba4ddf64 100644 --- a/swagger_parser/lib/src/parser/parser/open_api_parser.dart +++ b/swagger_parser/lib/src/parser/parser/open_api_parser.dart @@ -679,7 +679,20 @@ class OpenApiParser { final propertyValue = props[propertyName] as Map; final nullablePropertyValue = propertyValue[_nullableConst].toString().toBool(); - final isNullable = nullablePropertyValue ?? false; + + final isNullable = nullablePropertyValue ?? + switch (propertyValue) { + {_anyOfConst: final List anyOf} => anyOf.any( + (e) => e is Map && e['type'] == 'null', + ), + {_oneOfConst: final List oneOf} => oneOf.any( + (e) => e is Map && e['type'] == 'null', + ), + {_allOfConst: final List allOf} => allOf.any( + (e) => e is Map && e['type'] == 'null', + ), + _ => false, + }; final isRequired = requiredParameters.contains(propertyName); final typeWithImport = _findType( diff --git a/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/expected_files/models/one_of_element.dart b/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/expected_files/models/one_of_element.dart index 4a66ad6e..3e7e5d1c 100644 --- a/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/expected_files/models/one_of_element.dart +++ b/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/expected_files/models/one_of_element.dart @@ -16,10 +16,11 @@ class OneOfElement with _$OneOfElement { required EnumClass oneClass, required int allType, required DateTime anyType, - required EnumClass? nullableClass, + required EnumClass? nullableButRequiredClass, + @Default([]) List? nullableType, + EnumClass? nullableClass, @Default(EnumClass.value1) EnumClass anyClass, @Default([]) List oneType, - @Default([]) List? nullableType, }) = _OneOfElement; factory OneOfElement.fromJson(Map json) => diff --git a/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/of_like_class.3.1.json b/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/of_like_class.3.1.json index f96759ad..2b13aa3e 100644 --- a/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/of_like_class.3.1.json +++ b/swagger_parser/test/e2e/tests/basic/of_like_class.3.1/of_like_class.3.1.json @@ -5,6 +5,7 @@ "schemas": { "OneOfElement": { "type": "object", + "required": ["nullableButRequiredClass"], "properties": { "allClass": { "allOf": [ @@ -54,6 +55,16 @@ ], "default": "[]" }, + "nullableButRequiredClass": { + "anyOf": [ + { + "$ref": "#/components/schemas/EnumClass" + }, + { + "type": "null" + } + ] + }, "nullableClass": { "anyOf": [ { diff --git a/swagger_parser/test/e2e/tests/nullable_types/expected_files/models/class_with_nullable_types.dart b/swagger_parser/test/e2e/tests/nullable_types/expected_files/models/class_with_nullable_types.dart index d54fd46d..cc7639f6 100644 --- a/swagger_parser/test/e2e/tests/nullable_types/expected_files/models/class_with_nullable_types.dart +++ b/swagger_parser/test/e2e/tests/nullable_types/expected_files/models/class_with_nullable_types.dart @@ -26,6 +26,8 @@ class ClassWithNullableTypes with _$ClassWithNullableTypes { @JsonKey(name: 'p1_list') required String? p1List, @JsonKey(name: 'p2_list') required List? p2List, @JsonKey(name: 'p3_list') required Object1? p3List, + @JsonKey(name: 'nonNull_anyOf') required dynamic nonNullAnyOf, + @JsonKey(name: 'required_null_anyOf') required String? requiredNullAnyOf, @JsonKey(name: 'p1_anyOf') required String? p1AnyOf, @JsonKey(name: 'p2_anyOf') required List? p2AnyOf, @JsonKey(name: 'p3_anyOf') required Object2? p3AnyOf, @@ -38,6 +40,7 @@ class ClassWithNullableTypes with _$ClassWithNullableTypes { @JsonKey(name: 'p1_n') String? p1N, @JsonKey(name: 'p2_n') List? p2N, @JsonKey(name: 'p3_n') P3n? p3N, + @JsonKey(name: 'optional_null_anyOf') String? optionalNullAnyOf, }) = _ClassWithNullableTypes; factory ClassWithNullableTypes.fromJson(Map json) => diff --git a/swagger_parser/test/e2e/tests/nullable_types/openapi.yaml b/swagger_parser/test/e2e/tests/nullable_types/openapi.yaml index 1a5b8e71..ddfe0b6e 100644 --- a/swagger_parser/test/e2e/tests/nullable_types/openapi.yaml +++ b/swagger_parser/test/e2e/tests/nullable_types/openapi.yaml @@ -70,6 +70,16 @@ components: - p2_null_item - p2_null_all - p3 + - required_null_anyOf + - p1_anyOf + - p2_anyOf + - p3_anyOf + - p1_oneOf + - p2_oneOf + - p3_oneOf + - p1_allOf + - p2_allOf + - p3_allOf properties: p1: type: string @@ -168,6 +178,19 @@ components: - string - null + nonNull_anyOf: + anyOf: + - type: string + - type: int + optional_null_anyOf: + anyOf: + - type: string + - type: null + required_null_anyOf: + anyOf: + - type: string + - type: null + p1_anyOf: anyOf: - type: string @@ -253,6 +276,9 @@ components: allOf: - type: object - type: null + required: + - p1 + - p2 properties: p1: allOf: