예제 #1
0
        /// <summary>
        /// Provided two composite types, determine if they "overlap". Two composite
        /// types overlap when the Sets of possible concrete types for each intersect.
        ///
        /// This is often used to determine if a fragment of a given type could possibly
        /// be visited in a context of another type.
        ///
        /// This function is commutative.
        /// </summary>
        public static bool DoTypesOverlap(this ISchema schema, GraphType typeA, GraphType typeB)
        {
            if (typeA.Equals(typeB))
            {
                return(true);
            }

            var a = typeA as GraphQLAbstractType;
            var b = typeB as GraphQLAbstractType;

            if (a != null)
            {
                if (b != null)
                {
                    return(a.PossibleTypes.Any(type => b.IsPossibleType(type)));
                }

                return(a.IsPossibleType(typeB));
            }

            if (b != null)
            {
                return(b.IsPossibleType(typeA));
            }

            return(false);
        }
예제 #2
0
        public Dictionary <string, Fields> CollectFields(ExecutionContext context, GraphType type, Selections selections, Dictionary <string, Fields> fields)
        {
            if (fields == null)
            {
                fields = new Dictionary <string, Fields>();
            }

            selections.Apply(selection =>
            {
                if (selection.Field != null)
                {
                    if (!ShouldIncludeNode(context, selection.Field.Directives))
                    {
                        return;
                    }

                    var name = selection.Field.Alias ?? selection.Field.Name;
                    if (!fields.ContainsKey(name))
                    {
                        fields[name] = new Fields();
                    }
                    fields[name].Add(selection.Field);
                }
                else if (selection.Fragment != null)
                {
                    if (selection.Fragment is FragmentSpread)
                    {
                        var spread = selection.Fragment as FragmentSpread;

                        if (!ShouldIncludeNode(context, spread.Directives))
                        {
                            return;
                        }

                        var fragment = context.Fragments.FindDefinition(spread.Name);
                        if (!ShouldIncludeNode(context, fragment.Directives) ||
                            !DoesFragmentConditionMatch(context, fragment, type))
                        {
                            return;
                        }

                        CollectFields(context, type, fragment.Selections, fields);
                    }
                    else if (selection.Fragment is InlineFragment)
                    {
                        var inline = selection.Fragment as InlineFragment;

                        if (!ShouldIncludeNode(context, inline.Directives) ||
                            !DoesFragmentConditionMatch(context, inline, type))
                        {
                            return;
                        }

                        CollectFields(context, type, inline.Selections, fields);
                    }
                }
            });

            return(fields);
        }
예제 #3
0
        public static bool IsInputType(this GraphType type, ISchema schema)
        {
            var namedType = type.GetNamedType(schema);

            return(namedType is ScalarGraphType ||
                   namedType is EnumerationGraphType ||
                   namedType is InputObjectGraphType);
        }
        public NonNullGraphType(GraphType type)
        {
            if (type.GetType() == typeof(NonNullGraphType))
            {
                throw new ArgumentException("Cannot nest NonNull inside NonNull.", "type");
            }

            Type = type;
        }
예제 #5
0
        public IValue AstFromValue(ISchema schema, object value, GraphType type)
        {
            if (type is NonNullGraphType)
            {
                var nonnull = (NonNullGraphType)type;
                return(AstFromValue(schema, value, schema.FindType(nonnull.Type)));
            }

            if (value is Dictionary <string, object> )
            {
                var dict = (Dictionary <string, object>)value;

                var fields = dict
                             .Select(pair => new ObjectField(pair.Key, AstFromValue(schema, pair.Value, null)))
                             .ToList();

                return(new ObjectValue(fields));
            }

            if (!(value is string) && value is IEnumerable)
            {
                GraphType itemType = null;

                var listType = type as ListGraphType;
                if (listType != null)
                {
                    itemType = schema.FindType(listType.Type);
                }

                var list   = (IEnumerable)value;
                var values = list.Map(item => AstFromValue(schema, item, itemType));
                return(new ListValue(values));
            }

            if (value is bool)
            {
                return(new BooleanValue((bool)value));
            }

            if (value is int)
            {
                return(new IntValue((int)value));
            }

            if (value is long)
            {
                return(new LongValue((long)value));
            }

            if (value is double)
            {
                return(new FloatValue((double)value));
            }

            return(new StringValue(value?.ToString()));
        }
예제 #6
0
        public bool IsValidValue(ISchema schema, GraphType type, object input)
        {
            if (type is NonNullGraphType)
            {
                if (input == null)
                {
                    return(false);
                }

                return(IsValidValue(schema, schema.FindType(((NonNullGraphType)type).Type), input));
            }

            if (input == null)
            {
                return(true);
            }

            if (type is ListGraphType)
            {
                var listType     = (ListGraphType)type;
                var listItemType = schema.FindType(listType.Type);
                var list         = input as IEnumerable;
                return(list != null && !(input is string)
                    ? list.All(item => IsValidValue(schema, listItemType, item))
                    : IsValidValue(schema, listItemType, input));
            }

            if (type is ObjectGraphType || type is InputObjectGraphType)
            {
                var dict = input as Dictionary <string, object>;
                if (dict == null)
                {
                    return(false);
                }

                // ensure every provided field is defined
                if (type is InputObjectGraphType &&
                    dict.Keys.Any(key => type.Fields.FirstOrDefault(field => field.Name == key) == null))
                {
                    return(false);
                }

                return(type.Fields.All(field =>
                                       IsValidValue(schema, schema.FindType(field.Type),
                                                    dict.ContainsKey(field.Name) ? dict[field.Name] : null)));
            }

            if (type is ScalarGraphType)
            {
                var scalar = (ScalarGraphType)type;
                return(scalar.Coerce(input) != null);
            }

            return(false);
        }
예제 #7
0
        /// <summary>
        /// Provided a type and a super type, return true if the first type is either
        /// equal or a subset of the second super type (covariant).
        /// </summary>
        public static bool IsSubtypeOf(this GraphType maybeSubType, GraphType superType, ISchema schema)
        {
            if (maybeSubType.Equals(superType))
            {
                return(true);
            }

            // If superType is non-null, maybeSubType must also be nullable.
            if (superType is NonNullGraphType)
            {
                if (maybeSubType is NonNullGraphType)
                {
                    var sub = (NonNullGraphType)maybeSubType;
                    var sup = (NonNullGraphType)superType;
                    return(IsSubtypeOf(schema.FindType(sub.Type), schema.FindType(sup.Type), schema));
                }

                return(false);
            }
            else if (maybeSubType is NonNullGraphType)
            {
                var sub = (NonNullGraphType)maybeSubType;
                return(IsSubtypeOf(schema.FindType(sub.Type), superType, schema));
            }

            // If superType type is a list, maybeSubType type must also be a list.
            if (superType is ListGraphType)
            {
                if (maybeSubType is ListGraphType)
                {
                    var sub = (ListGraphType)maybeSubType;
                    var sup = (ListGraphType)superType;
                    return(IsSubtypeOf(schema.FindType(sub.Type), schema.FindType(sup.Type), schema));
                }

                return(false);
            }
            else if (maybeSubType is ListGraphType)
            {
                // If superType is not a list, maybeSubType must also be not a list.
                return(false);
            }

            // If superType type is an abstract type, maybeSubType type may be a currently
            // possible object type.
            if (superType is GraphQLAbstractType &&
                maybeSubType is ObjectGraphType)
            {
                return(((GraphQLAbstractType)superType).IsPossibleType(maybeSubType));
            }

            return(false);
        }
        private void CollectTypes(GraphType type, GraphTypesLookup lookup)
        {
            if (type == null)
            {
                return;
            }

            lookup[type.Name] = type;

            type.Fields.Apply(field =>
            {
                CollectTypes(field.Type, lookup);
            });
        }
예제 #9
0
        // TODO: combine duplication with CoerceValue
        public object CoerceValueAst(Schema schema, GraphType type, object input, Variables variables)
        {
            if (type is NonNullGraphType)
            {
                var nonNull = type as NonNullGraphType;
                return(CoerceValueAst(schema, schema.FindType(nonNull.Type), input, variables));
            }

            if (input == null)
            {
                return(null);
            }

            if (input is Variable)
            {
                return(variables != null
                    ? variables.ValueFor(((Variable)input).Name)
                    : null);
            }

            if (type is ListGraphType)
            {
                var listType = type as ListGraphType;
                var list     = input as IEnumerable;
                return(list != null
                    ? list.Map(item => CoerceValueAst(schema, listType, item, variables))
                    : new[] { input });
            }

            if (type is ObjectGraphType)
            {
                var objType = type as ObjectGraphType;
                var obj     = new Dictionary <string, object>();
                var dict    = (Dictionary <string, object>)input;

                objType.Fields.Apply(field =>
                {
                    var fieldValue  = CoerceValueAst(schema, schema.FindType(field.Type), dict[field.Name], variables);
                    obj[field.Name] = fieldValue ?? field.DefaultValue;
                });
            }

            if (type is ScalarGraphType)
            {
                var scalarType = type as ScalarGraphType;
                return(scalarType.Coerce(input));
            }

            return(input);
        }
        public GraphType this[string typeName]
        {
            get
            {
                GraphType result = null;
                if (_types.ContainsKey(typeName))
                {
                    result = _types[typeName];
                }

                return(result);
            }
            set { _types[typeName] = value; }
        }
예제 #11
0
        public static GraphType GetNamedType(this GraphType type, ISchema schema)
        {
            GraphType unmodifiedType = type;

            if (type is NonNullGraphType)
            {
                var nonNull = (NonNullGraphType)type;
                return(GetNamedType(schema.FindType(nonNull.Type), schema));
            }

            if (type is ListGraphType)
            {
                var list = (ListGraphType)type;
                return(GetNamedType(schema.FindType(list.Type), schema));
            }

            return(unmodifiedType);
        }
예제 #12
0
        public bool IsValidValue(Schema schema, GraphType type, object input)
        {
            if (type is NonNullGraphType)
            {
                if (input == null)
                {
                    return(false);
                }

                return(IsValidValue(schema, schema.FindType(((NonNullGraphType)type).Type), input));
            }

            if (input == null)
            {
                return(true);
            }

            if (type is ListGraphType)
            {
                var listType = (ListGraphType)type;
                var list     = input as IEnumerable;
                return(list != null
                    ? list.All(item => IsValidValue(schema, type, item))
                    : IsValidValue(schema, listType, input));
            }

            if (type is ObjectGraphType)
            {
                var dict = input as Dictionary <string, object>;
                return(dict != null &&
                       type.Fields.All(field => IsValidValue(schema, schema.FindType(field.Type), dict[field.Name])));
            }

            if (type is ScalarGraphType)
            {
                var scalar = (ScalarGraphType)type;
                return(scalar.Coerce(input) != null);
            }

            return(false);
        }
        public Dictionary <string, Fields> CollectFields(ExecutionContext context, GraphType type, Selections selections, Dictionary <string, Fields> fields)
        {
            if (fields == null)
            {
                fields = new Dictionary <string, Fields>();
            }

            selections.Apply(selection =>
            {
                if (selection.Field != null)
                {
                    var name = selection.Field.Alias ?? selection.Field.Name;
                    if (!fields.ContainsKey(name))
                    {
                        fields[name] = new Fields();
                    }
                    fields[name].Add(selection.Field);
                }
            });

            return(fields);
        }
        public object CoerceValue(GraphType type, object input)
        {
            if (type is NonNullGraphType)
            {
                var nonNull = type as NonNullGraphType;
                return(CoerceValue(nonNull.Type, input));
            }

            if (type is ListGraphType)
            {
                var listType = type as ListGraphType;
                var list     = input as IEnumerable;
                return(list != null
                    ? list.Map(item => CoerceValue(listType, item))
                    : new[] { input });
            }

            if (type is ObjectGraphType)
            {
                var objType = type as ObjectGraphType;
                var obj     = new Dictionary <string, object>();

                objType.Fields.Apply(field =>
                {
                    var dict        = (Dictionary <string, object>)input;
                    var fieldValue  = CoerceValue(field.Type, dict[field.Name]);
                    obj[field.Name] = fieldValue ?? field.DefaultValue;
                });
            }

            if (type is ScalarGraphType)
            {
                var scalarType = type as ScalarGraphType;
                return(scalarType.Coerce(input));
            }

            return(null);
        }
예제 #15
0
        public async Task <object> CompleteValue(ExecutionContext context, GraphType fieldType, Fields fields, object result)
        {
            if (fieldType is NonNullGraphType)
            {
                var nonNullType = fieldType as NonNullGraphType;
                var completed   = await CompleteValue(context, context.Schema.FindType(nonNullType.Type), fields, result);

                if (completed == null)
                {
                    throw new ExecutionError("Cannot return null for non-null type. Field: {0}".ToFormat(nonNullType.Name));
                }

                return(completed);
            }

            if (result == null)
            {
                return(null);
            }

            if (fieldType is ScalarGraphType)
            {
                var scalarType   = fieldType as ScalarGraphType;
                var coercedValue = scalarType.Coerce(result);
                return(coercedValue);
            }

            if (fieldType is ListGraphType)
            {
                var list = result as IEnumerable;

                if (list == null)
                {
                    throw new ExecutionError("User error: expected an IEnumerable list though did not find one.");
                }

                var listType = fieldType as ListGraphType;
                var itemType = context.Schema.FindType(listType.Type);

                var results = await list.MapAsync(async item =>
                {
                    return(await CompleteValue(context, itemType, fields, item));
                });

                return(results);
            }

            var objectType = fieldType as ObjectGraphType;

            if (fieldType is InterfaceGraphType)
            {
                var interfaceType = fieldType as InterfaceGraphType;
                objectType = interfaceType.ResolveType(result);
            }

            if (objectType == null)
            {
                return(null);
            }

            var subFields = new Dictionary <string, Fields>();

            fields.Apply(field =>
            {
                subFields = CollectFields(context, objectType, field.Selections, subFields);
            });

            return(await ExecuteFields(context, objectType, result, subFields));
        }
예제 #16
0
        public static IEnumerable <string> IsValidLiteralValue(this GraphType type, IValue valueAst, ISchema schema)
        {
            if (type is NonNullGraphType)
            {
                var nonNull = (NonNullGraphType)type;
                var ofType  = schema.FindType(nonNull.Type);

                if (valueAst == null)
                {
                    if (ofType != null)
                    {
                        return(new[] { $"Expected \"{ofType.Name}!\", found null." });
                    }

                    return(new[] { "Expected non-null value, found null" });
                }

                return(IsValidLiteralValue(ofType, valueAst, schema));
            }

            if (valueAst == null)
            {
                return(new string[] {});
            }

            // This function only tests literals, and assumes variables will provide
            // values of the correct type.
            if (valueAst is VariableReference)
            {
                return(new string[] {});
            }

            if (type is ListGraphType)
            {
                var list   = (ListGraphType)type;
                var ofType = schema.FindType(list.Type);

                if (valueAst is ListValue)
                {
                    var index = 0;
                    return(((ListValue)valueAst).Values.Aggregate(new string[] {}, (acc, value) =>
                    {
                        var errors = IsValidLiteralValue(ofType, value, schema);
                        var result = acc.Concat(errors.Map(err => $"In element #{index}: {err}")).ToArray();
                        index++;
                        return result;
                    }));
                }

                return(IsValidLiteralValue(ofType, valueAst, schema));
            }

            if (type is InputObjectGraphType)
            {
                if (!(valueAst is ObjectValue))
                {
                    return(new[] { $"Expected \"{type.Name}\", found not an object." });
                }

                var inputType = (InputObjectGraphType)type;

                var fields    = inputType.Fields.ToList();
                var fieldAsts = ((ObjectValue)valueAst).ObjectFields.ToList();

                var errors = new List <string>();

                // ensure every provided field is defined
                fieldAsts.Apply(providedFieldAst =>
                {
                    var found = fields.FirstOrDefault(x => x.Name == providedFieldAst.Name);
                    if (found == null)
                    {
                        errors.Add($"In field \"{providedFieldAst.Name}\": Unknown field.");
                    }
                });

                // ensure every defined field is valid
                fields.Apply(field =>
                {
                    var fieldAst = fieldAsts.FirstOrDefault(x => x.Name == field.Name);
                    var result   = IsValidLiteralValue(schema.FindType(field.Type), fieldAst?.Value, schema);

                    errors.AddRange(result.Map(err => $"In field \"{field.Name}\": {err}"));
                });

                return(errors);
            }

            var scalar = (ScalarGraphType)type;

            var parseResult = scalar.ParseLiteral(valueAst);

            if (parseResult == null)
            {
                return(new [] { $"Expected type \"{type.Name}\", found {AstPrinter.Print(valueAst)}." });
            }

            return(new string[] {});
        }
 public object CoerceValueAst(GraphType type, object input)
 {
     return(input);
 }
예제 #18
0
 public static bool IsCompositeType(this GraphType type)
 {
     return(type is ObjectGraphType ||
            type is InterfaceGraphType ||
            type is UnionGraphType);
 }
예제 #19
0
        public bool DoesFragmentConditionMatch(ExecutionContext context, IHaveFragmentType fragment, GraphType type)
        {
            if (string.IsNullOrWhiteSpace(fragment.Type))
            {
                return(true);
            }

            var conditionalType = context.Schema.FindType(fragment.Type);

            if (conditionalType == null)
            {
                return(false);
            }

            if (conditionalType.Equals(type))
            {
                return(true);
            }

            if (conditionalType is GraphQLAbstractType)
            {
                var abstractType = (GraphQLAbstractType)conditionalType;
                return(abstractType.IsPossibleType(type));
            }

            return(false);
        }
예제 #20
0
        public bool IsValidValue(ISchema schema, GraphType type, IType astType, object input)
        {
            if (type is NonNullGraphType)
            {
                if (input == null)
                {
                    return(false);
                }

                var nonNullType = schema.FindType(((NonNullGraphType)type).Type);

                if (nonNullType is ScalarGraphType)
                {
                    var val = ValueFromScalar((ScalarGraphType)nonNullType, input);
                    return(val != null);
                }

                return(IsValidValue(schema, nonNullType, astType, input));
            }

            if (astType is NonNullType)
            {
                if (input == null)
                {
                    return(false);
                }

                if (type is ScalarGraphType)
                {
                    var val = ValueFromScalar((ScalarGraphType)type, input);
                    return(val != null);
                }
            }

            if (input == null)
            {
                return(true);
            }

            if (input is StringValue)
            {
                var stringVal = (StringValue)input;
                if (stringVal.Value == null)
                {
                    return(true);
                }
            }

            if (type is ListGraphType)
            {
                var listType     = (ListGraphType)type;
                var listItemType = schema.FindType(listType.Type);

                var list = input as IEnumerable;
                if (list != null && !(input is string))
                {
                    return(list.All(item => IsValidValue(schema, listItemType, astType, item)));
                }

                var listValue = input as ListValue;
                if (listValue != null)
                {
                    return(listValue.Values.All(item => IsValidValue(schema, listItemType, astType, item)));
                }

                return(IsValidValue(schema, listItemType, astType, input));
            }

            if (type is ObjectGraphType || type is InputObjectGraphType)
            {
                var dict = input as ObjectValue;
                if (dict == null)
                {
                    return(false);
                }

                // ensure every provided field is defined
                if (type is InputObjectGraphType &&
                    dict.FieldNames.Any(key => type.Fields.FirstOrDefault(field => field.Name == key) == null))
                {
                    return(false);
                }

                return(type.Fields.All(field =>
                                       IsValidValue(
                                           schema,
                                           schema.FindType(field.Type),
                                           astType,
                                           dict.Field(field.Name)?.Value)));
            }

            if (type is ScalarGraphType)
            {
                var scalar = (ScalarGraphType)type;
                var value  = ValueFromScalar(scalar, input);
                return(value != null);
            }

            return(false);
        }
예제 #21
0
        public object CoerceValue(ISchema schema, GraphType type, IValue input, Variables variables = null)
        {
            if (type is NonNullGraphType)
            {
                var nonNull = type as NonNullGraphType;
                return(CoerceValue(schema, schema.FindType(nonNull.Type), input, variables));
            }

            if (input == null)
            {
                return(null);
            }

            var variable = input as VariableReference;

            if (variable != null)
            {
                return(variables != null
                    ? variables.ValueFor(variable.Name)
                    : null);
            }

            if (type is ListGraphType)
            {
                var listType     = type as ListGraphType;
                var listItemType = schema.FindType(listType.Type);
                var list         = input as ListValue;
                return(list != null
                    ? list.Values.Map(item => CoerceValue(schema, listItemType, item, variables)).ToArray()
                    : new[] { CoerceValue(schema, listItemType, input, variables) });
            }

            if (type is ObjectGraphType || type is InputObjectGraphType)
            {
                var obj = new Dictionary <string, object>();

                var objectValue = input as ObjectValue;
                if (objectValue == null)
                {
                    return(null);
                }

                type.Fields.Apply(field =>
                {
                    var objectField = objectValue.Field(field.Name);
                    if (objectField != null)
                    {
                        var fieldValue = CoerceValue(schema, schema.FindType(field.Type), objectField.Value, variables);
                        fieldValue     = fieldValue ?? field.DefaultValue;

                        obj[field.Name] = fieldValue;
                    }
                });

                return(obj);
            }

            if (type is ScalarGraphType)
            {
                var scalarType = type as ScalarGraphType;
                return(scalarType.ParseLiteral(input));
            }

            return(null);
        }
예제 #22
0
        public async Task <object> CompleteValue(ExecutionContext context, GraphType fieldType, Fields fields, object result)
        {
            var nonNullType = fieldType as NonNullGraphType;

            if (nonNullType != null)
            {
                var type      = context.Schema.FindType(nonNullType.Type);
                var completed = await CompleteValue(context, type, fields, result);

                if (completed == null)
                {
                    var field = fields != null?fields.FirstOrDefault() : null;

                    var fieldName = field != null ? field.Name : null;
                    throw new ExecutionError("Cannot return null for non-null type. Field: {0}, Type: {1}!."
                                             .ToFormat(fieldName, type.Name));
                }

                return(completed);
            }

            if (result == null)
            {
                return(null);
            }

            if (fieldType is ScalarGraphType)
            {
                var scalarType   = fieldType as ScalarGraphType;
                var coercedValue = scalarType.Coerce(result);
                return(coercedValue);
            }

            if (fieldType is ListGraphType)
            {
                var list = result as IEnumerable;

                if (list == null)
                {
                    throw new ExecutionError("User error: expected an IEnumerable list though did not find one.");
                }

                var listType = fieldType as ListGraphType;
                var itemType = context.Schema.FindType(listType.Type);

                var results = await list.MapAsync(async item =>
                {
                    return(await CompleteValue(context, itemType, fields, item));
                });

                return(results);
            }

            var objectType = fieldType as ObjectGraphType;

            if (fieldType is GraphQLAbstractType)
            {
                var abstractType = fieldType as GraphQLAbstractType;
                objectType = abstractType.GetObjectType(result);

                if (objectType != null && !abstractType.IsPossibleType(objectType))
                {
                    throw new ExecutionError(
                              "Runtime Object type \"{0}\" is not a possible type for \"{1}\""
                              .ToFormat(objectType, abstractType));
                }
            }

            if (objectType == null)
            {
                return(null);
            }

            if (objectType.IsTypeOf != null && !objectType.IsTypeOf(result))
            {
                throw new ExecutionError(
                          "Expected value of type \"{0}\" but got: {1}."
                          .ToFormat(objectType, result));
            }

            var subFields        = new Dictionary <string, Fields>();
            var visitedFragments = new List <string>();

            fields.Apply(field =>
            {
                subFields = CollectFields(context, objectType, field.Selections, subFields, visitedFragments);
            });

            return(await ExecuteFields(context, objectType, result, subFields));
        }
예제 #23
0
        public Dictionary <string, Fields> CollectFields(
            ExecutionContext context,
            GraphType specificType,
            SelectionSet selectionSet,
            Dictionary <string, Fields> fields,
            List <string> visitedFragmentNames)
        {
            if (fields == null)
            {
                fields = new Dictionary <string, Fields>();
            }

            selectionSet.Selections.Apply(selection =>
            {
                if (selection is Field)
                {
                    var field = (Field)selection;
                    if (!ShouldIncludeNode(context, field.Directives))
                    {
                        return;
                    }

                    var name = field.Alias ?? field.Name;
                    if (!fields.ContainsKey(name))
                    {
                        fields[name] = new Fields();
                    }
                    fields[name].Add(field);
                }
                else if (selection is FragmentSpread)
                {
                    var spread = (FragmentSpread)selection;

                    if (visitedFragmentNames.Contains(spread.Name) ||
                        !ShouldIncludeNode(context, spread.Directives))
                    {
                        return;
                    }

                    visitedFragmentNames.Add(spread.Name);

                    var fragment = context.Fragments.FindDefinition(spread.Name);
                    if (fragment == null ||
                        !ShouldIncludeNode(context, fragment.Directives) ||
                        !DoesFragmentConditionMatch(context, fragment.Type.Name, specificType))
                    {
                        return;
                    }

                    CollectFields(context, specificType, fragment.SelectionSet, fields, visitedFragmentNames);
                }
                else if (selection is InlineFragment)
                {
                    var inline = (InlineFragment)selection;

                    if (!ShouldIncludeNode(context, inline.Directives) ||
                        !DoesFragmentConditionMatch(context, inline.Type.Name, specificType))
                    {
                        return;
                    }

                    CollectFields(context, specificType, inline.SelectionSet, fields, visitedFragmentNames);
                }
            });

            return(fields);
        }
예제 #24
0
        public bool DoesFragmentConditionMatch(ExecutionContext context, IHaveFragmentType fragment, GraphType type)
        {
            var conditionalType = context.Schema.FindType(fragment.Type);

            if (conditionalType == type)
            {
                return(true);
            }

            if (conditionalType is InterfaceGraphType)
            {
                var interfaceType = (InterfaceGraphType)conditionalType;
                var hasInterfaces = type as IImplementInterfaces;
                if (hasInterfaces != null)
                {
                    var interfaces = context.Schema.FindTypes(hasInterfaces.Interfaces);
                    return(interfaceType.IsPossibleType(interfaces));
                }
            }

            return(false);
        }
예제 #25
0
        public object CoerceValue(ISchema schema, GraphType type, object input, Variables variables = null)
        {
            if (type is NonNullGraphType)
            {
                var nonNull = type as NonNullGraphType;
                return(CoerceValue(schema, schema.FindType(nonNull.Type), input, variables));
            }

            if (input == null)
            {
                return(null);
            }

            var variable = input as Variable;

            if (variable != null)
            {
                return(variables != null
                    ? variables.ValueFor(variable.Name)
                    : null);
            }

            if (type is ListGraphType)
            {
                var listType     = type as ListGraphType;
                var listItemType = schema.FindType(listType.Type);
                var list         = input as IEnumerable;
                return(list != null && !(input is string)
                    ? list.Map(item => CoerceValue(schema, listItemType, item, variables)).ToArray()
                    : new[] { CoerceValue(schema, listItemType, input, variables) });
            }

            if (type is ObjectGraphType || type is InputObjectGraphType)
            {
                var obj = new Dictionary <string, object>();

                if (input is KeyValuePair <string, object> )
                {
                    var kvp = (KeyValuePair <string, object>)input;
                    input = new Dictionary <string, object> {
                        { kvp.Key, kvp.Value }
                    };
                }

                var kvps = input as IEnumerable <KeyValuePair <string, object> >;
                if (kvps != null)
                {
                    input = kvps.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                }

                var dict = input as Dictionary <string, object>;
                if (dict == null)
                {
                    return(null);
                }

                type.Fields.Apply(field =>
                {
                    object inputValue;
                    if (dict.TryGetValue(field.Name, out inputValue))
                    {
                        var fieldValue  = CoerceValue(schema, schema.FindType(field.Type), inputValue, variables);
                        obj[field.Name] = fieldValue ?? field.DefaultValue;
                    }
                });

                return(obj);
            }

            if (type is ScalarGraphType)
            {
                var scalarType = type as ScalarGraphType;
                return(scalarType.Coerce(input));
            }

            return(input);
        }