Add interface type

This commit is contained in:
Tobe O 2018-08-03 19:43:00 -04:00
parent c4c3ddff78
commit a43893bde9
3 changed files with 55 additions and 17 deletions

View file

@ -2,11 +2,20 @@ part of graphql_schema.src.schema;
GraphQLObjectType objectType(String name, GraphQLObjectType objectType(String name,
{String description, {String description,
bool isInterface: false,
Iterable<GraphQLField> fields = const [], Iterable<GraphQLField> fields = const [],
Iterable<GraphQLObjectType> interfaces = const []}) => Iterable<GraphQLObjectType> interfaces = const []}) {
new GraphQLObjectType(name, description) var obj = new GraphQLObjectType(name, description, isInterface: isInterface)
..fields.addAll(fields ?? []) ..fields.addAll(fields ?? []);
..interfaces.addAll(interfaces ?? []);
if (interfaces?.isNotEmpty == true) {
for (var i in interfaces) {
obj.inheritFrom(i);
}
}
return obj;
}
GraphQLField<T, Serialized> field<T, Serialized>(String name, GraphQLField<T, Serialized> field<T, Serialized>(String name,
{Iterable<GraphQLFieldArgument<T, Serialized>> arguments: const [], {Iterable<GraphQLFieldArgument<T, Serialized>> arguments: const [],

View file

@ -6,11 +6,27 @@ class GraphQLObjectType
final String name; final String name;
final String description; final String description;
final List<GraphQLField> fields = []; final List<GraphQLField> fields = [];
final bool isInterface;
final List<GraphQLObjectType> _interfaces = [];
final List<GraphQLObjectType> _possibleTypes = [];
/// A list of other types that this object type is known to implement. /// A list of other types that this object type is known to implement.
final List<GraphQLObjectType> interfaces = []; List<GraphQLObjectType> get interfaces => new List<GraphQLObjectType>.unmodifiable(_interfaces);
GraphQLObjectType(this.name, this.description); /// A list of other types that implement this interface.
List<GraphQLObjectType> get possibleTypes => new List<GraphQLObjectType>.unmodifiable(_possibleTypes);
GraphQLObjectType(this.name, this.description, {this.isInterface: false});
void inheritFrom(GraphQLObjectType other) {
if (!_interfaces.contains(other)) {
_interfaces.add(other);
other._possibleTypes.add(this);
other._interfaces.forEach(inheritFrom);
}
}
@override @override
ValidationResult<Map<String, dynamic>> validate(String key, Map input) { ValidationResult<Map<String, dynamic>> validate(String key, Map input) {
@ -23,7 +39,8 @@ class GraphQLObjectType
for (var field in fields) { for (var field in fields) {
if (field.type is GraphQLNonNullableType) { if (field.type is GraphQLNonNullableType) {
if (!input.containsKey(field.name) || input[field.name] == null) { if (!input.containsKey(field.name) || input[field.name] == null) {
errors.add('Field "${field.name}, of type ${field.type} cannot be null."'); errors.add(
'Field "${field.name}, of type ${field.type} cannot be null."');
} }
} }
} }
@ -56,7 +73,8 @@ class GraphQLObjectType
return value.keys.fold<Map<String, dynamic>>({}, (out, k) { return value.keys.fold<Map<String, dynamic>>({}, (out, k) {
var field = fields.firstWhere((f) => f.name == k, orElse: () => null); var field = fields.firstWhere((f) => f.name == k, orElse: () => null);
if (field == null) if (field == null)
throw new UnsupportedError('Cannot serialize field "$k", which was not defined in the schema.'); throw new UnsupportedError(
'Cannot serialize field "$k", which was not defined in the schema.');
return out..[k.toString()] = field.serialize(value[k]); return out..[k.toString()] = field.serialize(value[k]);
}); });
} }

View file

@ -120,8 +120,11 @@ GraphQLObjectType _reflectSchemaTypes() {
'possibleTypes', 'possibleTypes',
type: listType(_reflectSchemaTypes().nonNullable()), type: listType(_reflectSchemaTypes().nonNullable()),
resolve: (type, _) { resolve: (type, _) {
// TODO: Interface and union types if (type is GraphQLObjectType && type.isInterface) {
return <GraphQLType>[]; return type.possibleTypes;
} else {
return null;
}
}, },
), ),
); );
@ -195,7 +198,7 @@ GraphQLObjectType _createTypeType() {
if (t is GraphQLScalarType) if (t is GraphQLScalarType)
return 'SCALAR'; return 'SCALAR';
else if (t is GraphQLObjectType) else if (t is GraphQLObjectType)
return 'OBJECT'; return t.isInterface ? 'INTERFACE' : 'OBJECT';
else if (t is GraphQLListType) else if (t is GraphQLListType)
return 'LIST'; return 'LIST';
else if (t is GraphQLNonNullableType) else if (t is GraphQLNonNullableType)
@ -204,7 +207,7 @@ GraphQLObjectType _createTypeType() {
return 'ENUM'; return 'ENUM';
else else
throw new UnsupportedError( throw new UnsupportedError(
'Cannot get the kind of $t.'); // TODO: Interface + union 'Cannot get the kind of $t.'); // TODO: union
}, },
), ),
field( field(
@ -424,6 +427,14 @@ List<GraphQLType> _fetchAllTypesFromObject(GraphQLObjectType objectType) {
} }
} }
for (var type in objectType.interfaces) {
types.addAll(_fetchAllTypesFromObject(type));
}
for (var type in objectType.possibleTypes) {
types.addAll(_fetchAllTypesFromObject(type));
}
return types; return types;
} }
@ -440,6 +451,6 @@ Iterable<GraphQLType> _fetchAllTypesFromType(GraphQLType type) {
types.add(type); types.add(type);
} }
// TODO: Interface, union // TODO: union
return types; return types;
} }