diff --git a/packages/dynamite/lib/src/models/discriminator.dart b/packages/dynamite/lib/src/models/discriminator.dart new file mode 100644 index 00000000..5968aeb6 --- /dev/null +++ b/packages/dynamite/lib/src/models/discriminator.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'discriminator.g.dart'; + +@JsonSerializable() +class Discriminator { + Discriminator({ + required this.propertyName, + this.mapping, + }); + + factory Discriminator.fromJson(final Map json) => _$DiscriminatorFromJson(json); + Map toJson() => _$DiscriminatorToJson(this); + + final String propertyName; + + final Map? mapping; +} diff --git a/packages/dynamite/lib/src/models/discriminator.g.dart b/packages/dynamite/lib/src/models/discriminator.g.dart new file mode 100644 index 00000000..26d90580 --- /dev/null +++ b/packages/dynamite/lib/src/models/discriminator.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'discriminator.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Discriminator _$DiscriminatorFromJson(Map json) { + $checkKeys( + json, + allowedKeys: const ['propertyName', 'mapping'], + ); + return Discriminator( + propertyName: json['propertyName'] as String, + mapping: (json['mapping'] as Map?)?.map( + (k, e) => MapEntry(k, e as String), + ), + ); +} + +Map _$DiscriminatorToJson(Discriminator instance) { + final val = { + 'propertyName': instance.propertyName, + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('mapping', instance.mapping); + return val; +} diff --git a/packages/dynamite/lib/src/models/schema.dart b/packages/dynamite/lib/src/models/schema.dart index fc59f41f..bd424564 100644 --- a/packages/dynamite/lib/src/models/schema.dart +++ b/packages/dynamite/lib/src/models/schema.dart @@ -1,3 +1,4 @@ +import 'package:dynamite/src/models/discriminator.dart'; import 'package:json_annotation/json_annotation.dart'; part 'schema.g.dart'; @@ -21,6 +22,7 @@ class Schema { this.additionalProperties, this.contentMediaType, this.contentSchema, + this.discriminator, }); factory Schema.fromJson(final Map json) => _$SchemaFromJson(json); @@ -63,5 +65,7 @@ class Schema { final Schema? contentSchema; + final Discriminator? discriminator; + bool get isJsonString => type == 'string' && contentMediaType == 'application/json' && contentSchema != null; } diff --git a/packages/dynamite/lib/src/models/schema.g.dart b/packages/dynamite/lib/src/models/schema.g.dart index 1afeb5be..a2e7b0cb 100644 --- a/packages/dynamite/lib/src/models/schema.g.dart +++ b/packages/dynamite/lib/src/models/schema.g.dart @@ -25,7 +25,8 @@ Schema _$SchemaFromJson(Map json) { 'items', 'additionalProperties', 'contentMediaType', - 'contentSchema' + 'contentSchema', + 'discriminator' ], ); return Schema( @@ -48,6 +49,8 @@ Schema _$SchemaFromJson(Map json) { contentMediaType: json['contentMediaType'] as String?, contentSchema: json['contentSchema'] == null ? null : Schema.fromJson(json['contentSchema'] as Map), + discriminator: + json['discriminator'] == null ? null : Discriminator.fromJson(json['discriminator'] as Map), ); } @@ -76,5 +79,6 @@ Map _$SchemaToJson(Schema instance) { writeNotNull('additionalProperties', instance.additionalProperties); writeNotNull('contentMediaType', instance.contentMediaType); writeNotNull('contentSchema', instance.contentSchema?.toJson()); + writeNotNull('discriminator', instance.discriminator?.toJson()); return val; } diff --git a/packages/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/lib/src/openapi_builder.dart index a6088b06..9dbf7642 100644 --- a/packages/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/lib/src/openapi_builder.dart @@ -1278,10 +1278,30 @@ TypeResult resolveType( [ for (final result in results) ...[ '${result.name}? ${fields[result.name]!};', + ], + for (final result in results) ...[ + if (schema.discriminator != null) ...[ + "if (data['${schema.discriminator!.propertyName}'] == '${result.name}'", + if (schema.discriminator!.mapping != null && + schema.discriminator!.mapping!.isNotEmpty) ...[ + for (final key in schema.discriminator!.mapping!.entries + .where((final entry) => entry.value.endsWith('/${result.name}')) + .map((final entry) => entry.key)) ...[ + " || data['${schema.discriminator!.propertyName}'] == '$key'", + ], + ], + ') {', + ], 'try {', '${fields[result.name]!} = ${result.deserialize('data')};', '} catch (_) {', + if (schema.discriminator != null) ...[ + 'rethrow;', + ], '}', + if (schema.discriminator != null) ...[ + '}', + ], ], if (schema.oneOf != null) ...[ "assert([${fields.values.join(',')}].where((final x) => x != null).length == 1, 'Need oneOf for \$data');", @@ -1299,8 +1319,24 @@ TypeResult resolveType( ); }, ), + Constructor( + (final b) { + b + ..factory = true + ..lambda = true + ..name = 'fromJsonString' + ..requiredParameters.add( + Parameter( + (final b) => b + ..name = 'data' + ..type = refer('String'), + ), + ) + ..body = Code('$identifier.fromJson(json.decode(data))'); + }, + ), ]) - ..methods.add( + ..methods.addAll([ Method( (final b) => b ..name = 'toJson' @@ -1308,7 +1344,22 @@ TypeResult resolveType( ..lambda = true ..body = const Code('_data'), ), - ); + Method( + (final b) => b + ..name = 'toJsonString' + ..returns = refer('String') + ..lambda = true + ..static = true + ..requiredParameters.add( + Parameter( + (final b) => b + ..name = 'data' + ..type = refer('dynamic'), + ), + ) + ..body = const Code('json.encode(data)'), + ), + ]); }, ), ); diff --git a/packages/dynamite/lib/src/type_result/base.dart b/packages/dynamite/lib/src/type_result/base.dart index d477af21..101f5630 100644 --- a/packages/dynamite/lib/src/type_result/base.dart +++ b/packages/dynamite/lib/src/type_result/base.dart @@ -1,7 +1,7 @@ part of '../../dynamite.dart'; class TypeResultBase extends TypeResult { - TypeResultBase(super.typeName); + TypeResultBase(super.name); @override String serialize(final String object) => object; diff --git a/packages/dynamite/lib/src/type_result/enum.dart b/packages/dynamite/lib/src/type_result/enum.dart index ec56a90c..af9a9b94 100644 --- a/packages/dynamite/lib/src/type_result/enum.dart +++ b/packages/dynamite/lib/src/type_result/enum.dart @@ -2,7 +2,7 @@ part of '../../dynamite.dart'; class TypeResultEnum extends TypeResult { TypeResultEnum( - super.typeName, + super.name, this.subType, ); diff --git a/packages/dynamite/lib/src/type_result/list.dart b/packages/dynamite/lib/src/type_result/list.dart index a547a76e..a48efb1f 100644 --- a/packages/dynamite/lib/src/type_result/list.dart +++ b/packages/dynamite/lib/src/type_result/list.dart @@ -2,7 +2,7 @@ part of '../../dynamite.dart'; class TypeResultList extends TypeResult { TypeResultList( - super.typeName, + super.name, this.subType, ); diff --git a/packages/dynamite/lib/src/type_result/map.dart b/packages/dynamite/lib/src/type_result/map.dart index db5a56ef..884e8d27 100644 --- a/packages/dynamite/lib/src/type_result/map.dart +++ b/packages/dynamite/lib/src/type_result/map.dart @@ -2,7 +2,7 @@ part of '../../dynamite.dart'; class TypeResultMap extends TypeResult { TypeResultMap( - super.typeName, + super.name, this.subType, ); diff --git a/packages/dynamite/lib/src/type_result/object.dart b/packages/dynamite/lib/src/type_result/object.dart index df66cba9..7509849d 100644 --- a/packages/dynamite/lib/src/type_result/object.dart +++ b/packages/dynamite/lib/src/type_result/object.dart @@ -2,7 +2,7 @@ part of '../../dynamite.dart'; class TypeResultObject extends TypeResult { TypeResultObject( - super.typeName, { + super.name, { this.fromJsonString = false, }); diff --git a/packages/nextcloud/lib/src/nextcloud.openapi.dart b/packages/nextcloud/lib/src/nextcloud.openapi.dart index 44a267c5..f27fa3ee 100644 --- a/packages/nextcloud/lib/src/nextcloud.openapi.dart +++ b/packages/nextcloud/lib/src/nextcloud.openapi.dart @@ -2814,10 +2814,10 @@ class CoreNavigationApps_Ocs_Data_Order { factory CoreNavigationApps_Ocs_Data_Order.fromJson(dynamic data) { int? $int; + String? string; try { $int = (data as int); } catch (_) {} - String? string; try { string = (data as String); } catch (_) {} @@ -2829,6 +2829,9 @@ class CoreNavigationApps_Ocs_Data_Order { ); } + factory CoreNavigationApps_Ocs_Data_Order.fromJsonString(String data) => + CoreNavigationApps_Ocs_Data_Order.fromJson(json.decode(data)); + final dynamic _data; final int? $int; @@ -2838,6 +2841,8 @@ class CoreNavigationApps_Ocs_Data_Order { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -3348,6 +3353,9 @@ class NotificationsNotification_SubjectRichParameters { ); } + factory NotificationsNotification_SubjectRichParameters.fromJsonString(String data) => + NotificationsNotification_SubjectRichParameters.fromJson(json.decode(data)); + final dynamic _data; final Map? mapStringDynamic; @@ -3355,6 +3363,8 @@ class NotificationsNotification_SubjectRichParameters { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } class NotificationsNotification_MessageRichParameters { @@ -3374,6 +3384,9 @@ class NotificationsNotification_MessageRichParameters { ); } + factory NotificationsNotification_MessageRichParameters.fromJsonString(String data) => + NotificationsNotification_MessageRichParameters.fromJson(json.decode(data)); + final dynamic _data; final Map? mapStringDynamic; @@ -3381,6 +3394,8 @@ class NotificationsNotification_MessageRichParameters { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -3961,10 +3976,10 @@ class UserStatusClearAt_Time { factory UserStatusClearAt_Time.fromJson(dynamic data) { UserStatusClearAt_Time0? userStatusClearAtTime0; + int? $int; try { userStatusClearAtTime0 = UserStatusClearAt_Time0.fromValue(data as String); } catch (_) {} - int? $int; try { $int = (data as int); } catch (_) {} @@ -3976,6 +3991,8 @@ class UserStatusClearAt_Time { ); } + factory UserStatusClearAt_Time.fromJsonString(String data) => UserStatusClearAt_Time.fromJson(json.decode(data)); + final dynamic _data; final UserStatusClearAt_Time0? userStatusClearAtTime0; @@ -3986,6 +4003,8 @@ class UserStatusClearAt_Time { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -4020,10 +4039,10 @@ class UserStatusPublicUserStatus_ClearAt { factory UserStatusPublicUserStatus_ClearAt.fromJson(dynamic data) { UserStatusClearAt? userStatusClearAt; + int? $int; try { userStatusClearAt = UserStatusClearAt.fromJson(data as Map); } catch (_) {} - int? $int; try { $int = (data as int); } catch (_) {} @@ -4034,6 +4053,9 @@ class UserStatusPublicUserStatus_ClearAt { ); } + factory UserStatusPublicUserStatus_ClearAt.fromJsonString(String data) => + UserStatusPublicUserStatus_ClearAt.fromJson(json.decode(data)); + final dynamic _data; final UserStatusClearAt? userStatusClearAt; @@ -4044,6 +4066,8 @@ class UserStatusPublicUserStatus_ClearAt { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } enum UserStatusType { @@ -4166,6 +4190,9 @@ class UserStatusFindStatus_Ocs_Data { ); } + factory UserStatusFindStatus_Ocs_Data.fromJsonString(String data) => + UserStatusFindStatus_Ocs_Data.fromJson(json.decode(data)); + final dynamic _data; final UserStatusPublicUserStatus? userStatusPublicUserStatus; @@ -4173,6 +4200,8 @@ class UserStatusFindStatus_Ocs_Data { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -4225,10 +4254,10 @@ class UserStatus_ClearAt { factory UserStatus_ClearAt.fromJson(dynamic data) { UserStatusClearAt? userStatusClearAt; + int? $int; try { userStatusClearAt = UserStatusClearAt.fromJson(data as Map); } catch (_) {} - int? $int; try { $int = (data as int); } catch (_) {} @@ -4239,6 +4268,8 @@ class UserStatus_ClearAt { ); } + factory UserStatus_ClearAt.fromJsonString(String data) => UserStatus_ClearAt.fromJson(json.decode(data)); + final dynamic _data; final UserStatusClearAt? userStatusClearAt; @@ -4249,6 +4280,8 @@ class UserStatus_ClearAt { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -4308,6 +4341,9 @@ class UserStatusGetUserStatus_Ocs_Data { ); } + factory UserStatusGetUserStatus_Ocs_Data.fromJsonString(String data) => + UserStatusGetUserStatus_Ocs_Data.fromJson(json.decode(data)); + final dynamic _data; final UserStatus? userStatus; @@ -4315,6 +4351,8 @@ class UserStatusGetUserStatus_Ocs_Data { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable() @@ -4368,10 +4406,10 @@ class UserStatusPredefinedStatus_ClearAt { factory UserStatusPredefinedStatus_ClearAt.fromJson(dynamic data) { UserStatusClearAt? userStatusClearAt; + int? $int; try { userStatusClearAt = UserStatusClearAt.fromJson(data as Map); } catch (_) {} - int? $int; try { $int = (data as int); } catch (_) {} @@ -4382,6 +4420,9 @@ class UserStatusPredefinedStatus_ClearAt { ); } + factory UserStatusPredefinedStatus_ClearAt.fromJsonString(String data) => + UserStatusPredefinedStatus_ClearAt.fromJson(json.decode(data)); + final dynamic _data; final UserStatusClearAt? userStatusClearAt; @@ -4392,6 +4433,8 @@ class UserStatusPredefinedStatus_ClearAt { // coverage:ignore-start dynamic toJson() => _data; // coverage:ignore-end + + static String toJsonString(dynamic data) => json.encode(data); } @JsonSerializable()