@@ -811,9 +811,13 @@ class JsonEnum extends JsonSchema {
811811 @override
812812 final dynamic defaultValue;
813813
814+ /// The canonical values accepted by this enum schema.
815+ List <dynamic > get normalizedValues =>
816+ values.map ((value) => _normalizeEntry (value).value).toList ();
817+
814818 factory JsonEnum .fromJson (Map <String , dynamic > json) {
815819 return JsonEnum (
816- json[ 'values' ] as List < dynamic > ? ?? json[ 'enum' ] as List < dynamic > ? ?? [] ,
820+ _parseValues ( json) ,
817821 title: json['title' ] as String ? ,
818822 description: json['description' ] as String ? ,
819823 defaultValue: json['default' ],
@@ -822,12 +826,88 @@ class JsonEnum extends JsonSchema {
822826
823827 @override
824828 Map <String , dynamic > toJson () {
829+ final normalizedEntries =
830+ values.map ((value) => _normalizeEntry (value)).toList (growable: false );
831+ final hasTitles = normalizedEntries.any ((entry) => entry.title != null );
832+ final allStrings =
833+ normalizedEntries.every ((entry) => entry.value is String );
834+
825835 return {
826836 if (title != null ) 'title' : title,
827837 if (description != null ) 'description' : description,
828838 if (defaultValue != null ) 'default' : defaultValue,
829- 'type' : 'enum' ,
830- 'values' : values,
839+ if (allStrings) 'type' : 'string' ,
840+ if (allStrings)
841+ 'enum' : normalizedEntries.map ((entry) => entry.value as String ).toList ()
842+ else if (! hasTitles)
843+ 'enum' : normalizedEntries.map ((entry) => entry.value).toList ()
844+ else
845+ 'oneOf' : normalizedEntries
846+ .map (
847+ (entry) => {
848+ 'const' : entry.value,
849+ if (entry.title != null ) 'title' : entry.title,
850+ },
851+ )
852+ .toList (),
853+ if (allStrings && hasTitles)
854+ 'enumNames' : normalizedEntries
855+ .map ((entry) => entry.title ?? entry.value as String )
856+ .toList (),
831857 };
832858 }
859+
860+ static List <dynamic > _parseValues (Map <String , dynamic > json) {
861+ final legacyValues = json['values' ];
862+ if (legacyValues is List ) {
863+ return List <dynamic >.from (legacyValues);
864+ }
865+
866+ final enumValues = json['enum' ];
867+ if (enumValues is List ) {
868+ final enumNames = json['enumNames' ];
869+ if (enumNames is List && enumNames.length == enumValues.length) {
870+ return List <dynamic >.generate (enumValues.length, (index) {
871+ final value = enumValues[index];
872+ final title = enumNames[index];
873+ if (title is String && title != '$value ' ) {
874+ return {'value' : value, 'title' : title};
875+ }
876+ return value;
877+ });
878+ }
879+
880+ return List <dynamic >.from (enumValues);
881+ }
882+
883+ final oneOfValues = json['oneOf' ];
884+ if (oneOfValues is List ) {
885+ return oneOfValues.map ((entry) {
886+ if (entry is Map && entry.containsKey ('const' )) {
887+ final value = entry['const' ];
888+ final title = entry['title' ];
889+ if (title is String && title != '$value ' ) {
890+ return {'value' : value, 'title' : title};
891+ }
892+ return value;
893+ }
894+
895+ return entry;
896+ }).toList ();
897+ }
898+
899+ return const [];
900+ }
901+
902+ static ({dynamic value, String ? title}) _normalizeEntry (dynamic entry) {
903+ if (entry is Map && entry.containsKey ('value' )) {
904+ final title = entry['title' ];
905+ return (
906+ value: entry['value' ],
907+ title: title is String ? title : null ,
908+ );
909+ }
910+
911+ return (value: entry, title: null );
912+ }
833913}
0 commit comments