Browse Source

fix(dynamite): re introduce generation of top level non object schemas

Signed-off-by: Nikolas Rimikis <leptopoda@users.noreply.github.com>
pull/1061/head
Nikolas Rimikis 1 year ago
parent
commit
cc79f07052
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 13
      packages/dynamite/dynamite/lib/src/builder/generate_schemas.dart
  2. 4
      packages/dynamite/dynamite/lib/src/builder/resolve_type.dart
  3. 1
      packages/dynamite/dynamite/lib/src/models/type_result/base.dart
  4. 1
      packages/dynamite/dynamite/lib/src/models/type_result/enum.dart
  5. 1
      packages/dynamite/dynamite/lib/src/models/type_result/list.dart
  6. 1
      packages/dynamite/dynamite/lib/src/models/type_result/map.dart
  7. 1
      packages/dynamite/dynamite/lib/src/models/type_result/object.dart
  8. 46
      packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart

13
packages/dynamite/dynamite/lib/src/builder/generate_schemas.dart

@ -3,6 +3,7 @@ import 'package:dynamite/src/builder/resolve_type.dart';
import 'package:dynamite/src/builder/state.dart'; import 'package:dynamite/src/builder/state.dart';
import 'package:dynamite/src/helpers/dart_helpers.dart'; import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/models/openapi.dart' as openapi; import 'package:dynamite/src/models/openapi.dart' as openapi;
import 'package:dynamite/src/models/type_result.dart';
Iterable<Spec> generateSchemas( Iterable<Spec> generateSchemas(
final openapi.OpenAPI spec, final openapi.OpenAPI spec,
@ -11,13 +12,21 @@ Iterable<Spec> generateSchemas(
if (spec.components?.schemas != null) { if (spec.components?.schemas != null) {
for (final schema in spec.components!.schemas!.entries) { for (final schema in spec.components!.schemas!.entries) {
final identifier = toDartName(schema.key, uppercaseFirstCharacter: true); final identifier = toDartName(schema.key, uppercaseFirstCharacter: true);
final result = resolveType(
resolveType(
spec, spec,
state, state,
identifier, identifier,
schema.value, schema.value,
); );
// TypeDefs should only be generated for top level schemas.
if (result is TypeResultBase || result.isTypeDef) {
yield TypeDef(
(final b) => b
..name = identifier
..definition = refer(result.name),
);
}
} }
} }

4
packages/dynamite/dynamite/lib/src/builder/resolve_type.dart

@ -22,13 +22,15 @@ TypeResult resolveType(
} }
if (schema.ref != null) { if (schema.ref != null) {
final name = schema.ref!.split('/').last; final name = schema.ref!.split('/').last;
result = resolveType( final subResult = resolveType(
spec, spec,
state, state,
name, name,
spec.components!.schemas![name]!, spec.components!.schemas![name]!,
nullable: nullable, nullable: nullable,
); );
result = subResult.asTypeDef;
} else if (schema.allOf != null) { } else if (schema.allOf != null) {
result = resolveAllOf( result = resolveAllOf(
spec, spec,

1
packages/dynamite/dynamite/lib/src/models/type_result/base.dart

@ -5,6 +5,7 @@ class TypeResultBase extends TypeResult {
TypeResultBase( TypeResultBase(
super.className, { super.className, {
super.nullable, super.nullable,
super.isTypeDef,
}); });
@override @override

1
packages/dynamite/dynamite/lib/src/models/type_result/enum.dart

@ -6,6 +6,7 @@ class TypeResultEnum extends TypeResult {
super.className, super.className,
this.subType, { this.subType, {
super.nullable, super.nullable,
super.isTypeDef,
}); });
final TypeResult subType; final TypeResult subType;

1
packages/dynamite/dynamite/lib/src/models/type_result/list.dart

@ -6,6 +6,7 @@ class TypeResultList extends TypeResult {
super.className, super.className,
final TypeResult subType, { final TypeResult subType, {
super.nullable, super.nullable,
super.isTypeDef,
}) : super(generics: [subType]); }) : super(generics: [subType]);
TypeResult get subType => generics.first; TypeResult get subType => generics.first;

1
packages/dynamite/dynamite/lib/src/models/type_result/map.dart

@ -6,6 +6,7 @@ class TypeResultMap extends TypeResult {
super.className, super.className,
final TypeResult subType, { final TypeResult subType, {
super.nullable, super.nullable,
super.isTypeDef,
}) : super(generics: [TypeResultBase('String'), subType]); }) : super(generics: [TypeResultBase('String'), subType]);
TypeResult get subType => generics[1]; TypeResult get subType => generics[1];

1
packages/dynamite/dynamite/lib/src/models/type_result/object.dart

@ -8,6 +8,7 @@ class TypeResultObject extends TypeResult {
super.className, { super.className, {
super.generics, super.generics,
super.nullable, super.nullable,
super.isTypeDef,
}) : assert( }) : assert(
className != 'JsonObject' && className != 'Object' && className != 'dynamic', className != 'JsonObject' && className != 'Object' && className != 'dynamic',
'Use TypeResultBase instead', 'Use TypeResultBase instead',

46
packages/dynamite/dynamite/lib/src/models/type_result/type_result.dart

@ -13,6 +13,7 @@ sealed class TypeResult {
this.className, { this.className, {
this.generics = const [], this.generics = const [],
this.nullable = false, this.nullable = false,
this.isTypeDef = false,
}) : assert(!className.contains('<'), 'Specify generics in the generics parameter.'), }) : assert(!className.contains('<'), 'Specify generics in the generics parameter.'),
assert(!className.contains('?'), 'Nullability should not be specified in the type.'); assert(!className.contains('?'), 'Nullability should not be specified in the type.');
@ -20,6 +21,9 @@ sealed class TypeResult {
final List<TypeResult> generics; final List<TypeResult> generics;
final bool nullable; final bool nullable;
/// Whether this type should be represented as a typedef.
final bool isTypeDef;
String get name { String get name {
if (generics.isNotEmpty) { if (generics.isNotEmpty) {
final buffer = StringBuffer('$className<') final buffer = StringBuffer('$className<')
@ -44,6 +48,10 @@ sealed class TypeResult {
} }
Iterable<String> get serializers sync* { Iterable<String> get serializers sync* {
if (isTypeDef) {
return;
}
for (final class_ in generics) { for (final class_ in generics) {
yield* class_.serializers; yield* class_.serializers;
} }
@ -104,6 +112,44 @@ sealed class TypeResult {
// ignore: avoid_returning_this // ignore: avoid_returning_this
TypeResult get dartType => this; TypeResult get dartType => this;
/// Returns `this` with a `true` value for [isTypeDef].
TypeResult get asTypeDef {
final $this = this;
// We need to preserve the original runtime type.
return switch ($this) {
TypeResultBase() => TypeResultBase(
className,
nullable: nullable,
isTypeDef: true,
),
TypeResultEnum() => TypeResultEnum(
className,
$this.subType,
nullable: nullable,
isTypeDef: true,
),
TypeResultList() => TypeResultList(
className,
$this.subType,
nullable: nullable,
isTypeDef: true,
),
TypeResultMap() => TypeResultMap(
className,
$this.subType,
nullable: nullable,
isTypeDef: true,
),
TypeResultObject() => TypeResultObject(
className,
generics: generics,
nullable: nullable,
isTypeDef: true,
),
};
}
@override @override
bool operator ==(final Object other) => bool operator ==(final Object other) =>
other is TypeResult && other.className == className && other.generics == generics; other is TypeResult && other.className == className && other.generics == generics;

Loading…
Cancel
Save