From 59be67391df3c27b69fcacf109cb2ae1b1ad7ca0 Mon Sep 17 00:00:00 2001 From: Tobe O Date: Fri, 3 Aug 2018 20:57:38 -0400 Subject: [PATCH] Union type introspection fixed --- graphql_schema/lib/src/union.dart | 30 ++++++++++-------- graphql_server/lib/graphql_server.dart | 32 ++++++++++++-------- graphql_server/lib/introspection.dart | 42 +++++++++++++++++--------- 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/graphql_schema/lib/src/union.dart b/graphql_schema/lib/src/union.dart index ed7f9a4e..2d7b0360 100644 --- a/graphql_schema/lib/src/union.dart +++ b/graphql_schema/lib/src/union.dart @@ -1,22 +1,25 @@ part of graphql_schema.src.schema; -class GraphQLUnionType extends GraphQLType - with _NonNullableMixin { - final List> possibleTypes; - final String description; +class GraphQLUnionType + extends GraphQLType, Map> + with _NonNullableMixin, Map> { + final String name; + final List 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 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 serialize(Map value) { for (var type in possibleTypes) { try { return type.serialize(value); @@ -27,7 +30,7 @@ class GraphQLUnionType extends GraphQLType } @override - Value deserialize(Serialized serialized) { + Map deserialize(Map serialized) { for (var type in possibleTypes) { try { return type.deserialize(serialized); @@ -38,7 +41,8 @@ class GraphQLUnionType extends GraphQLType } @override - ValidationResult validate(String key, Serialized input) { + ValidationResult> validate( + String key, Map input) { List errors = []; for (var type in possibleTypes) { @@ -51,6 +55,6 @@ class GraphQLUnionType extends GraphQLType } } - return new ValidationResult._failure(errors); + return new ValidationResult>._failure(errors); } } diff --git a/graphql_server/lib/graphql_server.dart b/graphql_server/lib/graphql_server.dart index 01cab90a..8410a12a 100644 --- a/graphql_server/lib/graphql_server.dart +++ b/graphql_server/lib/graphql_server.dart @@ -6,22 +6,31 @@ import 'package:graphql_schema/graphql_schema.dart'; import 'introspection.dart'; class GraphQL { - final Map customTypes = {}; + final List customTypes = []; GraphQLSchema _schema; - GraphQL(GraphQLSchema schema, {bool introspect: true}) : _schema = schema { + GraphQL(GraphQLSchema schema, + {bool introspect: true, + List customTypes = const []}) + : _schema = schema { + if (customTypes?.isNotEmpty == true) { + this.customTypes.addAll(customTypes); + } + if (introspect) { var allTypes = []; + 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]; } diff --git a/graphql_server/lib/introspection.dart b/graphql_server/lib/introspection.dart index 4f3148fb..921d2707 100644 --- a/graphql_server/lib/introspection.dart +++ b/graphql_server/lib/introspection.dart @@ -3,6 +3,16 @@ import 'package:graphql_schema/graphql_schema.dart'; // TODO: How to handle custom types??? GraphQLSchema reflectSchema(GraphQLSchema schema, List 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 fetchAllTypes( +List fetchAllTypes( GraphQLSchema schema, List allTypes) { - var typess = []; - typess.addAll(_fetchAllTypesFromObject(schema.query)); + var types = []; + + 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 = []; + 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 = []; +// +// 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 _fetchAllTypesFromObject(GraphQLObjectType objectType) { @@ -449,7 +461,7 @@ Iterable _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)); }