diff --git a/CHANGELOG.md b/CHANGELOG.md index 65d48a3..26ab982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.5.14 + +* Handle union types for array and map items schemas + ## 0.5.13 * Fix static analysis warning in generated files diff --git a/lib/src/generators/schema.dart b/lib/src/generators/schema.dart index faf9b86..63e6b16 100644 --- a/lib/src/generators/schema.dart +++ b/lib/src/generators/schema.dart @@ -529,7 +529,7 @@ class SchemaGenerator extends BaseGenerator { orElse: () => p, ); var (c, nullable) = propHeader(p.defaultValue, p.description); - var itemType = p.items.toDartType(); + var itemType = p.items.toDartType(unions: _unions); c += "List<$itemType> ${nullable ? '?' : ''} $name,\n\n"; file.writeAsStringSync(c, mode: FileMode.append); }, @@ -657,21 +657,38 @@ class SchemaGenerator extends BaseGenerator { } } - // Check for unions in component schemas - for (final s in (spec.components?.schemas?.keys ?? [])) { - spec.components?.schemas?[s]?.mapOrNull( + void recursiveSchemaSearch(Schema? schema) { + if (schema == null) { + return; + } + schema.mapOrNull( object: (o) { final props = o.properties; final propNames = props?.keys.toList() ?? []; + checkAnyOf(o.anyOf); for (final pName in propNames) { o.properties![pName]?.mapOrNull( - object: (p) => checkAnyOf(p.anyOf), + object: (p) { + checkAnyOf(p.anyOf); + recursiveSchemaSearch(p); + }, + array: (a) => recursiveSchemaSearch( + a.items.mapOrNull(object: (o) => o), + ), + map: (m) => recursiveSchemaSearch( + m.valueSchema?.mapOrNull(object: (o) => o), + ), ); } }, ); } + // Check for unions in component schemas + for (final s in (spec.components?.schemas?.keys ?? [])) { + recursiveSchemaSearch(spec.components?.schemas?[s]); + } + // Check for unions in component responses for (final key in (spec.components?.responses?.keys ?? [])) { final r = spec.components?.responses?[key]; @@ -692,7 +709,7 @@ class SchemaGenerator extends BaseGenerator { } } - // Check for unions in path rquests/responses + // Check for unions in path requests/responses for (final p in (spec.paths?.values ?? [])) { // Responses p.get?.responses?.forEach((_, r) { diff --git a/lib/src/open_api/index.dart b/lib/src/open_api/index.dart index 169409c..9d39bd4 100644 --- a/lib/src/open_api/index.dart +++ b/lib/src/open_api/index.dart @@ -3,6 +3,7 @@ library openapi_models; import 'dart:convert'; import 'dart:io'; import 'dart:isolate'; +import 'package:collection/collection.dart'; import 'package:recase/recase.dart'; import 'package:yaml/yaml.dart' as yaml; import 'package:path/path.dart' as p; diff --git a/lib/src/open_api/schema.dart b/lib/src/open_api/schema.dart index c86a48a..fca1fb5 100644 --- a/lib/src/open_api/schema.dart +++ b/lib/src/open_api/schema.dart @@ -281,10 +281,9 @@ class Schema with _$Schema { object: (s) { if (s.anyOf != null && unions != null) { final subSchemas = s.anyOf!.map((e) => e.toDartType()).toList(); + final leq = ListEquality(); for (final e in unions.entries) { - if (subSchemas.any((s) => !e.value.contains(s))) { - continue; - } else { + if (leq.equals(subSchemas, e.value)) { final type = e.key.pascalCase; if (s.nullable == true) { return '$type?'; diff --git a/pubspec.yaml b/pubspec.yaml index 7992826..7fbe650 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: openapi_spec description: OpenAPI Specification generator using native Dart code, as well as an all-in-one parser of existing specifications. -version: 0.5.13 +version: 0.5.14 maintainer: Taza Technology LLC repository: https://github.com/tazatechnology/openapi_spec issue_tracker: https://github.com/tazatechnology/openapi_spec/issues