Finished coerceArgumentValues
This commit is contained in:
parent
cd4a2233de
commit
4f91c0b6a8
4 changed files with 57 additions and 16 deletions
|
@ -4,5 +4,10 @@ class GraphQLFieldArgument<Value, Serialized> {
|
||||||
final String name;
|
final String name;
|
||||||
final GraphQLType<Value, Serialized> type;
|
final GraphQLType<Value, Serialized> type;
|
||||||
final Value defaultValue;
|
final Value defaultValue;
|
||||||
GraphQLFieldArgument(this.name, this.type, {this.defaultValue});
|
|
||||||
|
/// If [defaultValue] is `null`, and `null` is a valid value for this argument, set this to `true`.
|
||||||
|
final bool defaultsToNull;
|
||||||
|
|
||||||
|
GraphQLFieldArgument(this.name, this.type,
|
||||||
|
{this.defaultValue, this.defaultsToNull: false});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,17 @@ typedef FutureOr<Value> GraphQLFieldResolver<Value, Serialized>(
|
||||||
Serialized serialized);
|
Serialized serialized);
|
||||||
|
|
||||||
class GraphQLField<Value, Serialized> {
|
class GraphQLField<Value, Serialized> {
|
||||||
|
final List<GraphQLFieldArgument> arguments = <GraphQLFieldArgument>[];
|
||||||
final String name;
|
final String name;
|
||||||
final GraphQLFieldArgument argument;
|
|
||||||
final GraphQLFieldResolver<Value, Serialized> resolve;
|
final GraphQLFieldResolver<Value, Serialized> resolve;
|
||||||
final GraphQLType<Value, Serialized> type;
|
final GraphQLType<Value, Serialized> type;
|
||||||
|
|
||||||
GraphQLField(this.name, {this.argument, this.resolve, this.type});
|
GraphQLField(this.name,
|
||||||
|
{Iterable<GraphQLFieldArgument> arguments: const <GraphQLFieldArgument>[],
|
||||||
|
this.resolve,
|
||||||
|
this.type}) {
|
||||||
|
this.arguments.addAll(arguments ?? <GraphQLFieldArgument>[]);
|
||||||
|
}
|
||||||
|
|
||||||
FutureOr<Serialized> serialize(Value value) {
|
FutureOr<Serialized> serialize(Value value) {
|
||||||
return type.serialize(value);
|
return type.serialize(value);
|
||||||
|
|
|
@ -5,6 +5,8 @@ abstract class GraphQLType<Value, Serialized> {
|
||||||
Value deserialize(Serialized serialized);
|
Value deserialize(Serialized serialized);
|
||||||
ValidationResult<Serialized> validate(String key, Serialized input);
|
ValidationResult<Serialized> validate(String key, Serialized input);
|
||||||
GraphQLType<Value, Serialized> nonNullable();
|
GraphQLType<Value, Serialized> nonNullable();
|
||||||
|
|
||||||
|
bool get isNullable => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shorthand to create a [GraphQLListType].
|
/// Shorthand to create a [GraphQLListType].
|
||||||
|
@ -64,6 +66,9 @@ class _GraphQLNonNullableType<Value, Serialized>
|
||||||
final GraphQLType<Value, Serialized> type;
|
final GraphQLType<Value, Serialized> type;
|
||||||
_GraphQLNonNullableType._(this.type);
|
_GraphQLNonNullableType._(this.type);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isNullable => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
GraphQLType<Value, Serialized> nonNullable() {
|
GraphQLType<Value, Serialized> nonNullable() {
|
||||||
throw new UnsupportedError(
|
throw new UnsupportedError(
|
||||||
|
|
|
@ -33,8 +33,7 @@ class GraphQL {
|
||||||
if (customTypes.containsKey(ctx.typeName.name))
|
if (customTypes.containsKey(ctx.typeName.name))
|
||||||
return customTypes[ctx.typeName.name];
|
return customTypes[ctx.typeName.name];
|
||||||
throw new ArgumentError(
|
throw new ArgumentError(
|
||||||
'Unknown GraphQL type: "${ctx.typeName.name}"\n${ctx.span
|
'Unknown GraphQL type: "${ctx.typeName.name}"\n${ctx.span.highlight()}');
|
||||||
.highlight()}');
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +47,7 @@ class GraphQL {
|
||||||
{Map<String, dynamic> variableValues: const {}, initialValue}) {
|
{Map<String, dynamic> variableValues: const {}, initialValue}) {
|
||||||
var operation = getOperation(document, operationName);
|
var operation = getOperation(document, operationName);
|
||||||
var coercedVariableValues =
|
var coercedVariableValues =
|
||||||
coerceVariableValues(schema, operation, variableValues ?? {});
|
coerceVariableValues(schema, operation, variableValues ?? {});
|
||||||
if (operation.isQuery)
|
if (operation.isQuery)
|
||||||
return executeQuery(
|
return executeQuery(
|
||||||
document, operation, schema, coercedVariableValues, initialValue);
|
document, operation, schema, coercedVariableValues, initialValue);
|
||||||
|
@ -65,7 +64,7 @@ class GraphQL {
|
||||||
return ops.length == 1
|
return ops.length == 1
|
||||||
? ops.first
|
? ops.first
|
||||||
: throw new GraphQLException(
|
: throw new GraphQLException(
|
||||||
'Missing required operation "$operationName".');
|
'Missing required operation "$operationName".');
|
||||||
} else {
|
} else {
|
||||||
return ops.firstWhere((d) => d.name == operationName,
|
return ops.firstWhere((d) => d.name == operationName,
|
||||||
orElse: () => throw new GraphQLException(
|
orElse: () => throw new GraphQLException(
|
||||||
|
@ -128,7 +127,7 @@ class GraphQL {
|
||||||
objectValue,
|
objectValue,
|
||||||
Map<String, dynamic> variableValues) {
|
Map<String, dynamic> variableValues) {
|
||||||
var groupedFieldSet =
|
var groupedFieldSet =
|
||||||
collectFields(document, objectType, selectionSet, variableValues);
|
collectFields(document, objectType, selectionSet, variableValues);
|
||||||
var resultMap = <String, dynamic>{};
|
var resultMap = <String, dynamic>{};
|
||||||
|
|
||||||
for (var responseKey in groupedFieldSet.keys) {
|
for (var responseKey in groupedFieldSet.keys) {
|
||||||
|
@ -156,7 +155,7 @@ class GraphQL {
|
||||||
Map<String, dynamic> variableValues) {
|
Map<String, dynamic> variableValues) {
|
||||||
var field = fields[0];
|
var field = fields[0];
|
||||||
var argumentValues =
|
var argumentValues =
|
||||||
coerceArgumentValues(objectType, field, variableValues);
|
coerceArgumentValues(objectType, field, variableValues);
|
||||||
var resolvedValue = resolveFieldValue(
|
var resolvedValue = resolveFieldValue(
|
||||||
objectType, objectValue, field.field.fieldName.name, argumentValues);
|
objectType, objectValue, field.field.fieldName.name, argumentValues);
|
||||||
return completeValue(fieldType, fields, resolvedValue, variableValues);
|
return completeValue(fieldType, fields, resolvedValue, variableValues);
|
||||||
|
@ -168,9 +167,36 @@ class GraphQL {
|
||||||
var argumentValues = field.field.arguments;
|
var argumentValues = field.field.arguments;
|
||||||
var fieldName = field.field.fieldName.name;
|
var fieldName = field.field.fieldName.name;
|
||||||
var desiredField = objectType.fields.firstWhere((f) => f.name == fieldName);
|
var desiredField = objectType.fields.firstWhere((f) => f.name == fieldName);
|
||||||
|
var argumentDefinitions = desiredField.arguments;
|
||||||
|
|
||||||
// TODO: Multiple arguments?
|
for (var argumentDefinition in argumentDefinitions) {
|
||||||
var argumentDefinitions = desiredField.argument;
|
var argumentName = argumentDefinition.name;
|
||||||
|
var argumentType = argumentDefinition.type;
|
||||||
|
var defaultValue = argumentDefinition.defaultValue;
|
||||||
|
var value = argumentValues.firstWhere((a) => a.name == argumentName,
|
||||||
|
orElse: () => null);
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
var variableName = value.name;
|
||||||
|
var variableValue = variableValues[variableName];
|
||||||
|
|
||||||
|
if (variableValues.containsKey(variableName)) {
|
||||||
|
coercedValues[argumentName] = variableValue;
|
||||||
|
} else if (defaultValue != null || argumentDefinition.defaultsToNull) {
|
||||||
|
coercedValues[argumentName] = defaultValue;
|
||||||
|
} else if (!argumentType.isNullable) {
|
||||||
|
throw new GraphQLException(
|
||||||
|
'Missing value for argument "$argumentName".');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (defaultValue != null || argumentDefinition.defaultsToNull) {
|
||||||
|
coercedValues[argumentName] = defaultValue;
|
||||||
|
} else if (!argumentType.isNullable) {
|
||||||
|
throw new GraphQLException(
|
||||||
|
'Missing value for argument "$argumentName".');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return coercedValues;
|
return coercedValues;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +218,7 @@ class GraphQL {
|
||||||
if (selection.field != null) {
|
if (selection.field != null) {
|
||||||
var responseKey = selection.field.fieldName.name;
|
var responseKey = selection.field.fieldName.name;
|
||||||
var groupForResponseKey =
|
var groupForResponseKey =
|
||||||
groupedFields.putIfAbsent(responseKey, () => []);
|
groupedFields.putIfAbsent(responseKey, () => []);
|
||||||
groupForResponseKey.add(selection);
|
groupForResponseKey.add(selection);
|
||||||
} else if (selection.fragmentSpread != null) {
|
} else if (selection.fragmentSpread != null) {
|
||||||
var fragmentSpreadName = selection.fragmentSpread.name;
|
var fragmentSpreadName = selection.fragmentSpread.name;
|
||||||
|
@ -201,7 +227,7 @@ class GraphQL {
|
||||||
var fragment = document.definitions
|
var fragment = document.definitions
|
||||||
.whereType<FragmentDefinitionContext>()
|
.whereType<FragmentDefinitionContext>()
|
||||||
.firstWhere((f) => f.name == fragmentSpreadName,
|
.firstWhere((f) => f.name == fragmentSpreadName,
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
|
|
||||||
if (fragment == null) continue;
|
if (fragment == null) continue;
|
||||||
var fragmentType = fragment.typeCondition;
|
var fragmentType = fragment.typeCondition;
|
||||||
|
@ -213,7 +239,7 @@ class GraphQL {
|
||||||
for (var responseKey in fragmentGroupFieldSet.keys) {
|
for (var responseKey in fragmentGroupFieldSet.keys) {
|
||||||
var fragmentGroup = fragmentGroupFieldSet[responseKey];
|
var fragmentGroup = fragmentGroupFieldSet[responseKey];
|
||||||
var groupForResponseKey =
|
var groupForResponseKey =
|
||||||
groupedFields.putIfAbsent(responseKey, () => []);
|
groupedFields.putIfAbsent(responseKey, () => []);
|
||||||
groupForResponseKey.addAll(fragmentGroup);
|
groupForResponseKey.addAll(fragmentGroup);
|
||||||
}
|
}
|
||||||
} else if (selection.inlineFragment != null) {
|
} else if (selection.inlineFragment != null) {
|
||||||
|
@ -227,7 +253,7 @@ class GraphQL {
|
||||||
for (var responseKey in fragmentGroupFieldSet.keys) {
|
for (var responseKey in fragmentGroupFieldSet.keys) {
|
||||||
var fragmentGroup = fragmentGroupFieldSet[responseKey];
|
var fragmentGroup = fragmentGroupFieldSet[responseKey];
|
||||||
var groupForResponseKey =
|
var groupForResponseKey =
|
||||||
groupedFields.putIfAbsent(responseKey, () => []);
|
groupedFields.putIfAbsent(responseKey, () => []);
|
||||||
groupForResponseKey.addAll(fragmentGroup);
|
groupForResponseKey.addAll(fragmentGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,4 +304,4 @@ class GraphQL {
|
||||||
|
|
||||||
class GraphQLException extends FormatException {
|
class GraphQLException extends FormatException {
|
||||||
GraphQLException(String message) : super(message);
|
GraphQLException(String message) : super(message);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue