Union type introspection fixed
This commit is contained in:
parent
61ee37b4d9
commit
59be67391d
3 changed files with 64 additions and 40 deletions
|
@ -1,22 +1,25 @@
|
|||
part of graphql_schema.src.schema;
|
||||
|
||||
class GraphQLUnionType<Value, Serialized> extends GraphQLType<Value, Serialized>
|
||||
with _NonNullableMixin<Value, Serialized> {
|
||||
final List<GraphQLType<Value, Serialized>> possibleTypes;
|
||||
final String description;
|
||||
class GraphQLUnionType
|
||||
extends GraphQLType<Map<String, dynamic>, Map<String, dynamic>>
|
||||
with _NonNullableMixin<Map<String, dynamic>, Map<String, dynamic>> {
|
||||
final String name;
|
||||
final List<GraphQLObjectType> possibleTypes = [];
|
||||
|
||||
GraphQLUnionType(this.possibleTypes, {this.description}) {
|
||||
assert(possibleTypes.every((t) => t is GraphQLUnionType),
|
||||
'The member types of a Union type must all be Object base types; Scalar, Interface and Union types may not be member types of a Union. Similarly, wrapping types may not be member types of a Union');
|
||||
GraphQLUnionType(
|
||||
this.name,
|
||||
Iterable<GraphQLObjectType> possibleTypes,
|
||||
) {
|
||||
assert(possibleTypes.isNotEmpty,
|
||||
'A Union type must define one or more member types');
|
||||
'A Union type must define one or more member types.');
|
||||
this.possibleTypes.addAll(possibleTypes.toSet());
|
||||
}
|
||||
|
||||
@override
|
||||
String get name => possibleTypes.map((t) => t.name).join(' | ');
|
||||
String get description => possibleTypes.map((t) => t.name).join(' | ');
|
||||
|
||||
@override
|
||||
Serialized serialize(Value value) {
|
||||
Map<String, dynamic> serialize(Map<String, dynamic> value) {
|
||||
for (var type in possibleTypes) {
|
||||
try {
|
||||
return type.serialize(value);
|
||||
|
@ -27,7 +30,7 @@ class GraphQLUnionType<Value, Serialized> extends GraphQLType<Value, Serialized>
|
|||
}
|
||||
|
||||
@override
|
||||
Value deserialize(Serialized serialized) {
|
||||
Map<String, dynamic> deserialize(Map<String, dynamic> serialized) {
|
||||
for (var type in possibleTypes) {
|
||||
try {
|
||||
return type.deserialize(serialized);
|
||||
|
@ -38,7 +41,8 @@ class GraphQLUnionType<Value, Serialized> extends GraphQLType<Value, Serialized>
|
|||
}
|
||||
|
||||
@override
|
||||
ValidationResult<Serialized> validate(String key, Serialized input) {
|
||||
ValidationResult<Map<String, dynamic>> validate(
|
||||
String key, Map<String, dynamic> input) {
|
||||
List<String> errors = [];
|
||||
|
||||
for (var type in possibleTypes) {
|
||||
|
@ -51,6 +55,6 @@ class GraphQLUnionType<Value, Serialized> extends GraphQLType<Value, Serialized>
|
|||
}
|
||||
}
|
||||
|
||||
return new ValidationResult._failure(errors);
|
||||
return new ValidationResult<Map<String, dynamic>>._failure(errors);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,22 +6,31 @@ import 'package:graphql_schema/graphql_schema.dart';
|
|||
import 'introspection.dart';
|
||||
|
||||
class GraphQL {
|
||||
final Map<String, GraphQLType> customTypes = {};
|
||||
final List<GraphQLType> customTypes = [];
|
||||
GraphQLSchema _schema;
|
||||
|
||||
GraphQL(GraphQLSchema schema, {bool introspect: true}) : _schema = schema {
|
||||
GraphQL(GraphQLSchema schema,
|
||||
{bool introspect: true,
|
||||
List<GraphQLType> customTypes = const <GraphQLType>[]})
|
||||
: _schema = schema {
|
||||
if (customTypes?.isNotEmpty == true) {
|
||||
this.customTypes.addAll(customTypes);
|
||||
}
|
||||
|
||||
if (introspect) {
|
||||
var allTypes = <GraphQLType>[];
|
||||
allTypes.addAll(this.customTypes);
|
||||
_schema = reflectSchema(_schema, allTypes);
|
||||
|
||||
for (var type in allTypes) {
|
||||
customTypes[type.name] = type;
|
||||
if (!this.customTypes.contains(type)) {
|
||||
this.customTypes.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_schema.query != null) customTypes[_schema.query.name] = _schema.query;
|
||||
if (_schema.mutation != null)
|
||||
customTypes[_schema.mutation.name] = _schema.mutation;
|
||||
if (_schema.query != null) this.customTypes.add(_schema.query);
|
||||
if (_schema.mutation != null) this.customTypes.add(_schema.mutation);
|
||||
}
|
||||
|
||||
GraphQLType convertType(TypeContext ctx) {
|
||||
|
@ -43,11 +52,9 @@ class GraphQL {
|
|||
case 'DateTime':
|
||||
return graphQLDate;
|
||||
default:
|
||||
if (customTypes.containsKey(ctx.typeName.name))
|
||||
return customTypes[ctx.typeName.name];
|
||||
throw new ArgumentError(
|
||||
'Unknown GraphQL type: "${ctx.typeName.name}"');
|
||||
break;
|
||||
return customTypes.firstWhere((t) => t.name == ctx.typeName.name,
|
||||
orElse: () => throw new ArgumentError(
|
||||
'Unknown GraphQL type: "${ctx.typeName.name}"'));
|
||||
}
|
||||
} else {
|
||||
throw new ArgumentError('Invalid GraphQL type: "${ctx.span.text}"');
|
||||
|
@ -435,7 +442,8 @@ class GraphQL {
|
|||
|
||||
var vname = vv.variable.name;
|
||||
if (!variableValues.containsKey(vname))
|
||||
throw new GraphQLException.fromSourceSpan('Unknown variable: "$vname"', vv.span);
|
||||
throw new GraphQLException.fromSourceSpan(
|
||||
'Unknown variable: "$vname"', vv.span);
|
||||
|
||||
return variableValues[vname];
|
||||
}
|
||||
|
|
|
@ -3,6 +3,16 @@ import 'package:graphql_schema/graphql_schema.dart';
|
|||
|
||||
// TODO: How to handle custom types???
|
||||
GraphQLSchema reflectSchema(GraphQLSchema schema, List<GraphQLType> allTypes) {
|
||||
for (var type in allTypes.toList()) {
|
||||
var custom = _fetchAllTypesFromType(type);
|
||||
|
||||
for (var t in custom) {
|
||||
if (!allTypes.contains(t)) {
|
||||
allTypes.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var objectTypes = fetchAllTypes(schema, allTypes);
|
||||
var typeType = _reflectSchemaTypes();
|
||||
var directiveType = _reflectDirectiveType();
|
||||
|
@ -210,8 +220,7 @@ GraphQLObjectType _createTypeType() {
|
|||
else if (t is GraphQLUnionType)
|
||||
return 'UNION';
|
||||
else
|
||||
throw new UnsupportedError(
|
||||
'Cannot get the kind of $t.');
|
||||
throw new UnsupportedError('Cannot get the kind of $t.');
|
||||
},
|
||||
),
|
||||
field(
|
||||
|
@ -395,25 +404,28 @@ GraphQLObjectType _reflectEnumValueType() {
|
|||
);
|
||||
}
|
||||
|
||||
List<GraphQLObjectType> fetchAllTypes(
|
||||
List<GraphQLType> fetchAllTypes(
|
||||
GraphQLSchema schema, List<GraphQLType> allTypes) {
|
||||
var typess = <GraphQLType>[];
|
||||
typess.addAll(_fetchAllTypesFromObject(schema.query));
|
||||
var types = <GraphQLType>[];
|
||||
|
||||
types.addAll(_fetchAllTypesFromObject(schema.query));
|
||||
|
||||
if (schema.mutation != null) {
|
||||
typess.addAll(_fetchAllTypesFromObject(schema.mutation)
|
||||
types.addAll(_fetchAllTypesFromObject(schema.mutation)
|
||||
.where((t) => t is GraphQLObjectType));
|
||||
}
|
||||
|
||||
var types = <GraphQLObjectType>[];
|
||||
return types;
|
||||
|
||||
for (var type in typess) {
|
||||
if (type is GraphQLObjectType)
|
||||
types.add(type);
|
||||
else if (!allTypes.contains(type)) allTypes.add(type);
|
||||
}
|
||||
|
||||
return types.toSet().toList();
|
||||
// var types = <GraphQLObjectType>[];
|
||||
//
|
||||
// for (var type in typess) {
|
||||
// if (type is GraphQLObjectType)
|
||||
// types.add(type);
|
||||
// else if (!allTypes.contains(type)) allTypes.add(type);
|
||||
// }
|
||||
//
|
||||
// return types.toSet().toList();
|
||||
}
|
||||
|
||||
List<GraphQLType> _fetchAllTypesFromObject(GraphQLObjectType objectType) {
|
||||
|
@ -449,7 +461,7 @@ Iterable<GraphQLType> _fetchAllTypesFromType(GraphQLType type) {
|
|||
types.addAll(_fetchAllTypesFromObject(type));
|
||||
} else if (type is GraphQLEnumType) {
|
||||
types.add(type);
|
||||
} else if ( type is GraphQLUnionType) {
|
||||
} else if (type is GraphQLUnionType) {
|
||||
for (var t in type.possibleTypes) {
|
||||
types.addAll(_fetchAllTypesFromType(t));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue