diff --git a/packages/dynamite/lib/src/models/schema.dart b/packages/dynamite/lib/src/models/schema.dart index fb94b4c5..6ee10557 100644 --- a/packages/dynamite/lib/src/models/schema.dart +++ b/packages/dynamite/lib/src/models/schema.dart @@ -60,7 +60,10 @@ class Schema { final Schema? items; - final bool? additionalProperties; + @JsonKey( + fromJson: _parseAdditionalProperties, + ) + final Schema? additionalProperties; final String? contentMediaType; @@ -72,3 +75,21 @@ class Schema { bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null; } + +class EmptySchema extends Schema {} + +Schema? _parseAdditionalProperties(final dynamic data) { + if (data == null) { + return null; + } + + if (data is bool) { + return data ? EmptySchema() : null; + } + + if (data is Map) { + return Schema.fromJson(data); + } + + throw Exception('Can not parse additionalProperties from $data'); +} diff --git a/packages/dynamite/lib/src/models/schema.g.dart b/packages/dynamite/lib/src/models/schema.g.dart index afd37486..ce6a33cc 100644 --- a/packages/dynamite/lib/src/models/schema.g.dart +++ b/packages/dynamite/lib/src/models/schema.g.dart @@ -46,7 +46,7 @@ Schema _$SchemaFromJson(Map json) { ), required: (json['required'] as List?)?.map((e) => e as String).toList(), items: json['items'] == null ? null : Schema.fromJson(json['items'] as Map), - additionalProperties: json['additionalProperties'] as bool?, + additionalProperties: _parseAdditionalProperties(json['additionalProperties']), contentMediaType: json['contentMediaType'] as String?, contentSchema: json['contentSchema'] == null ? null : Schema.fromJson(json['contentSchema'] as Map), @@ -78,7 +78,7 @@ Map _$SchemaToJson(Schema instance) { writeNotNull('properties', instance.properties?.map((k, e) => MapEntry(k, e.toJson()))); writeNotNull('required', instance.required); writeNotNull('items', instance.items?.toJson()); - writeNotNull('additionalProperties', instance.additionalProperties); + writeNotNull('additionalProperties', instance.additionalProperties?.toJson()); writeNotNull('contentMediaType', instance.contentMediaType); writeNotNull('contentSchema', instance.contentSchema?.toJson()); writeNotNull('discriminator', instance.discriminator?.toJson()); diff --git a/packages/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/lib/src/openapi_builder.dart index c2c04f89..57e2ff1d 100644 --- a/packages/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/lib/src/openapi_builder.dart @@ -1082,7 +1082,7 @@ TypeResult resolveObject( refer('JsonSerializable').call( [], { - if (schema.additionalProperties ?? false) ...{ + if (schema.additionalProperties != null) ...{ 'disallowUnrecognizedKeys': refer('false'), }, if (extraJsonSerializableValues != null) ...{ @@ -1543,11 +1543,25 @@ TypeResult resolveType( break; case 'object': if (schema.properties == null) { - if (schema.additionalProperties ?? false) { - result = TypeResultMap( - 'Map', - TypeResultBase('dynamic'), - ); + if (schema.additionalProperties != null) { + if (schema.additionalProperties is EmptySchema) { + result = TypeResultMap( + 'Map', + TypeResultBase('dynamic'), + ); + } else { + final subResult = resolveType( + spec, + state, + identifier, + schema.additionalProperties!, + extraJsonSerializableValues: extraJsonSerializableValues, + ); + result = TypeResultMap( + 'Map', + TypeResultBase('dynamic'), + ); + } break; } result = TypeResultBase('dynamic');