Union type introspection fixed

This commit is contained in:
Tobe O 2018-08-03 20:57:38 -04:00
parent 61ee37b4d9
commit 59be67391d
3 changed files with 64 additions and 40 deletions

View file

@ -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);
}
}

View file

@ -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];
}

View file

@ -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));
}