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

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

View file

@ -6,11 +6,27 @@ class GraphQLObjectType
final String name;
final String description;
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.
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
ValidationResult<Map<String, dynamic>> validate(String key, Map input) {
@ -23,7 +39,8 @@ class GraphQLObjectType
for (var field in fields) {
if (field.type is GraphQLNonNullableType) {
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) {
var field = fields.firstWhere((f) => f.name == k, orElse: () => 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]);
});
}
@ -76,5 +94,5 @@ Map<String, dynamic> _foldToStringDynamic(Map map) {
return map == null
? null
: map.keys.fold<Map<String, dynamic>>(
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
}

View file

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