// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostEnvironment env, ISchema schema)
        {
            var printedSchema = new SchemaPrinter(schema).Print();

            Console.WriteLine(printedSchema);

            Console.WriteLine(schema.FindType("FooInput"));
            Console.WriteLine(schema.FindType("BarInput"));
            Console.WriteLine(schema.FindType("BazInput"));

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseHsts();
            }

            // add http for Schema at default url /graphql
            app.UseGraphQL <ISchema>("/graphql");
            app.UseWebSockets();
            app.UseGraphQLWebSockets <ISchema>("/graphql");

            // use graphql-playground at default url /ui/playground
            app.UseGraphiQLServer(new GraphiQLOptions {
                Path = "/graphiql", GraphQLEndPoint = "/graphql"
            });
            app.UseGraphQLPlayground(new GraphQLPlaygroundOptions());

            app.Run(async(context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
        }
예제 #2
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()));
        }
예제 #3
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);
        }
예제 #4
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);
        }
        public static IGraphType GraphTypeFromType(this IType type, ISchema schema)
        {
            if (type is NonNullType)
            {
                var nonnull = (NonNullType)type;
                var ofType = GraphTypeFromType(nonnull.Type, schema);
                var nonnullGraphType = typeof(NonNullGraphType<>).MakeGenericType(ofType.GetType());
                var instance = (NonNullGraphType)Activator.CreateInstance(nonnullGraphType);
                instance.ResolvedType = ofType;
                return instance;
            }

            if (type is ListType)
            {
                var list = (ListType)type;
                var ofType = GraphTypeFromType(list.Type, schema);
                var listGraphType = typeof(ListGraphType<>).MakeGenericType(ofType.GetType());
                var instance = (ListGraphType)Activator.CreateInstance(listGraphType);
                instance.ResolvedType = ofType;
                return instance;
            }

            if (type is NamedType)
            {
                var named = (NamedType)type;
                return schema.FindType(named.Name);
            }

            return null;
        }
예제 #6
0
        public static GraphType GraphTypeFromType(this IType type, ISchema schema)
        {
            if (type is NonNullType)
            {
                var nonnull          = (NonNullType)type;
                var ofType           = GraphTypeFromType(nonnull.Type, schema);
                var nonnullGraphType = typeof(NonNullGraphType <>).MakeGenericType(ofType.GetType());
                return((GraphType)Activator.CreateInstance(nonnullGraphType));
            }

            if (type is ListType)
            {
                var list          = (ListType)type;
                var ofType        = GraphTypeFromType(list.Type, schema);
                var listGraphType = typeof(ListGraphType <>).MakeGenericType(ofType.GetType());
                return((GraphType)Activator.CreateInstance(listGraphType));
            }

            if (type is NamedType)
            {
                var named = (NamedType)type;
                return(schema.FindType(named.Name));
            }

            return(null);
        }
예제 #7
0
        public Dictionary <string, object> GetArgumentValues(ISchema schema, QueryArguments definitionArguments, Arguments astArguments, Variables variables)
        {
            if (definitionArguments == null || !definitionArguments.Any())
            {
                return(null);
            }

            return(definitionArguments.Aggregate(new Dictionary <string, object>(), (acc, arg) =>
            {
                var value = astArguments != null ? astArguments.ValueFor(arg.Name) : null;
                var type = schema.FindType(arg.Type);

                if (value is Variable)
                {
                    var variable = (Variable)value;
                    value = variables.ValueFor(variable.Name);
                }

                object coercedValue = null;
                if (IsValidValue(schema, type, value))
                {
                    coercedValue = CoerceValue(schema, type, value, variables);
                }
                acc[arg.Name] = coercedValue ?? arg.DefaultValue;
                return acc;
            }));
        }
예제 #8
0
 public void ContainsTypeNames(ISchema schema, params string[] typeNames)
 {
     typeNames.Apply(typeName =>
     {
         var type = schema.FindType(typeName);
         type.ShouldNotBeNull("Did not find {0} in type lookup.".ToFormat(typeName));
     });
 }
 private void ContainsTypeNames(ISchema schema, params string[] typeNames)
 {
     typeNames.Apply(typeName =>
     {
         var type = schema.FindType(typeName);
         type.ShouldNotBeNull("Did not find {0} in type lookup.".ToFormat(typeName));
     });
 }
예제 #10
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);
        }
예제 #11
0
        public static IObjectGraphType GetObjectType(this IAbstractGraphType abstractType, object value, ISchema schema)
        {
            var result = abstractType.ResolveType != null
                ? abstractType.ResolveType(value)
                : GetTypeOf(abstractType, value);

            if (result is GraphQLTypeReference reference)
            {
                result = schema.FindType(reference.TypeName) as IObjectGraphType;
            }

            return(result);
        }
예제 #12
0
        public object GetVariableValue(ISchema schema, Variable variable, object input)
        {
            var type  = schema.FindType(variable.Type.FullName);
            var value = input ?? variable.DefaultValue;

            if (IsValidValue(schema, type, value))
            {
                return(CoerceValue(schema, type, value));
            }

            if (value == null)
            {
                throw new Exception("Variable '${0}' of required type '{1}' was not provided.".ToFormat(variable.Name, type.Name ?? variable.Type.FullName));
            }

            throw new Exception("Variable '${0}' expected value of type '{1}'.".ToFormat(variable.Name, type.Name ?? variable.Type.FullName));
        }
예제 #13
0
        /// <summary>
        /// Go through all of the implementations of type, as well as the interfaces
        /// that they implement. If any of those types include the provided field,
        /// suggest them, sorted by how often the type is referenced,  starting
        /// with Interfaces.
        /// </summary>
        private IEnumerable <string> getSuggestedTypeNames(
            ISchema schema,
            GraphType type,
            string fieldName)
        {
            if (type is InterfaceGraphType || type is UnionGraphType)
            {
                var suggestedObjectTypes = new List <string>();
                var interfaceUsageCount  = new LightweightCache <string, int>(key => 0);

                var absType = type as GraphQLAbstractType;
                absType.PossibleTypes.Apply(possibleType =>
                {
                    if (!possibleType.HasField(fieldName))
                    {
                        return;
                    }

                    // This object defines this field.
                    suggestedObjectTypes.Add(possibleType.Name);

                    possibleType.Interfaces.Apply(possibleInterfaceType =>
                    {
                        var possibleInterface = schema.FindType(possibleInterfaceType);

                        if (!possibleInterface.HasField(fieldName))
                        {
                            return;
                        }

                        // This interface type defines this field.
                        interfaceUsageCount[possibleInterface.Name] = interfaceUsageCount[possibleInterface.Name] + 1;
                    });
                });

                var suggestedInterfaceTypes = interfaceUsageCount.Keys.OrderBy(x => interfaceUsageCount[x]);
                return(suggestedInterfaceTypes.Concat(suggestedObjectTypes));
            }

            return(Enumerable.Empty <string>());
        }
예제 #14
0
        public object GetVariableValue(ISchema schema, VariableDefinition variable, IValue input)
        {
            var type = schema.FindType(variable.Type.Name());

            var value = input ?? variable.DefaultValue;

            if (IsValidValue(schema, type, variable.Type, input))
            {
                var coercedValue = CoerceValue(schema, type, value);
                return(coercedValue);
            }

            var val = ValueFromAst(value);

            if (val == null)
            {
                throw new ExecutionError("Variable '${0}' of required type '{1}' was not provided.".ToFormat(variable.Name, type.Name ?? variable.Type.FullName()));
            }

            throw new ExecutionError("Variable '${0}' expected value of type '{1}'.".ToFormat(variable.Name, type?.Name ?? variable.Type.FullName()));
        }
        public static IGraphType GraphTypeFromType(this IType type, ISchema schema)
        {
            if (type == null)
            {
                return(null);
            }

            if (type is NonNullType nonnull)
            {
                var ofType = GraphTypeFromType(nonnull.Type, schema);
                if (ofType == null)
                {
                    return(null);
                }
                var nonnullGraphType = typeof(NonNullGraphType <>).MakeGenericType(ofType.GetType());
                var instance         = (NonNullGraphType)Activator.CreateInstance(nonnullGraphType);
                instance.ResolvedType = ofType;
                return(instance);
            }

            if (type is ListType list)
            {
                var ofType = GraphTypeFromType(list.Type, schema);
                if (ofType == null)
                {
                    return(null);
                }
                var listGraphType = typeof(ListGraphType <>).MakeGenericType(ofType.GetType());
                var instance      = (ListGraphType)Activator.CreateInstance(listGraphType);
                instance.ResolvedType = ofType;
                return(instance);
            }

            if (type is NamedType named)
            {
                return(schema.FindType(named.Name));
            }

            return(null);
        }
예제 #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[] {});
        }
예제 #17
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);
        }
예제 #18
0
        // TODO: combine duplication with CoerceValue
        public object CoerceValueAst(ISchema 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;
        }
예제 #19
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 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;
        }
예제 #20
0
        private object CoerceValue( ISchema schema, GraphType type, object input, IEnumerable<Variable> variables = null )
        {
            NonNullGraphType typeAsNonNullGraphType = type as NonNullGraphType;
            if( typeAsNonNullGraphType != null )
            {
                NonNullGraphType nonNull = typeAsNonNullGraphType;
                return CoerceValue(schema, schema.FindType(nonNull.Type), input, variables);
            }

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

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

            ListGraphType typeAsListGraphType = type as ListGraphType;
            if( typeAsListGraphType != null )
            {
                GraphType listItemType = schema.FindType( typeAsListGraphType.Type );
                IEnumerable 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)
            {
                bool inputTypeFound = false;

                Dictionary<string, object> obj = new Dictionary<string, object>();

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

                if (!inputTypeFound)
                {
                    try
                    {
                        input = JObject.FromObject(input).Children()
                            .Cast<JProperty>()
                            .Select(x => {
                                JToken value = JToken.FromObject(x.Value);
                                return new KeyValuePair<string, object>(x.Name, value);
                            })
                            .ToDictionary(x => x.Key, x => x.Value);
                    }
                    catch
                    {
                        input = new Dictionary<string, object>
                        {
                            {(string)input, null} 
                        };
                    }
                }

                Dictionary<string, object> dict = (Dictionary<string, object>)input;

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

                return obj;
            }

            ScalarGraphType typeAsScalarGraphType = type as ScalarGraphType;
            if( typeAsScalarGraphType != null )
            {
                return typeAsScalarGraphType.Coerce( input );
            }

            return input;
        }
예제 #21
0
        public void Enter(INode node)
        {
            _ancestorStack.Push(node);

            if (node is SelectionSet)
            {
                _parentTypeStack.Push(GetLastType());
                return;
            }

            if (node is Field)
            {
                var field      = (Field)node;
                var parentType = _parentTypeStack.Peek().GetNamedType(_schema);
                var fieldType  = GetFieldDef(_schema, parentType, field);
                _fieldDefStack.Push(fieldType);
                var targetType = _schema.FindType(fieldType?.Type);
                _typeStack.Push(targetType);
                return;
            }

            if (node is Directive)
            {
                var directive = (Directive)node;
                _directive = _schema.Directives.SingleOrDefault(x => x.Name == directive.Name);
            }

            if (node is Operation)
            {
                var        op   = (Operation)node;
                IGraphType type = null;
                if (op.OperationType == OperationType.Query)
                {
                    type = _schema.Query;
                }
                else if (op.OperationType == OperationType.Mutation)
                {
                    type = _schema.Mutation;
                }
                else if (op.OperationType == OperationType.Subscription)
                {
                    type = _schema.Subscription;
                }
                _typeStack.Push(type);
                return;
            }

            if (node is FragmentDefinition)
            {
                var def  = (FragmentDefinition)node;
                var type = _schema.FindType(def.Type.Name);
                _typeStack.Push(type);
                return;
            }

            if (node is InlineFragment)
            {
                var def  = (InlineFragment)node;
                var type = def.Type != null?_schema.FindType(def.Type.Name) : GetLastType();

                _typeStack.Push(type);
                return;
            }

            if (node is VariableDefinition)
            {
                var varDef    = (VariableDefinition)node;
                var inputType = varDef.Type.GraphTypeFromType(_schema);
                _inputTypeStack.Push(inputType);
                return;
            }

            if (node is Argument)
            {
                var           argAst  = (Argument)node;
                QueryArgument argDef  = null;
                IGraphType    argType = null;

                var args = GetDirective() != null?GetDirective()?.Arguments : GetFieldDef()?.Arguments;

                if (args != null)
                {
                    argDef  = args.Find(argAst.Name);
                    argType = _schema.FindType(argDef?.Type);
                }

                _argument = argDef;
                _inputTypeStack.Push(argType);
            }

            if (node is ListValue)
            {
                var type = GetInputType().GetNamedType(_schema);
                _inputTypeStack.Push(type);
            }

            if (node is ObjectField)
            {
                var        objectType = GetInputType().GetNamedType(_schema);
                IGraphType fieldType  = null;

                if (objectType is InputObjectGraphType)
                {
                    var complexType = objectType as IComplexGraphType;
                    var inputField  = complexType.Fields.FirstOrDefault(x => x.Name == ((ObjectField)node).Name);
                    fieldType = inputField != null?_schema.FindType(inputField.Type) : null;
                }

                _inputTypeStack.Push(fieldType);
            }
        }
예제 #22
0
        public object GetVariableValue(ISchema schema, Variable variable, object input)
        {
            var type = schema.FindType(variable.Type.FullName);
            var value = input ?? variable.DefaultValue;
            if (IsValidValue(schema, type, value))
            {
                return CoerceValue(schema, type, value);
            }

            if (value == null)
            {
                throw new Exception("Variable '${0}' of required type '{1}' was not provided.".ToFormat(variable.Name, variable.Type.FullName));
            }

            throw new Exception("Variable '${0}' expected value of type '{1}'.".ToFormat(variable.Name, type.Name));
        }
예제 #23
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;
        }
예제 #24
0
        public object GetVariableValue(ISchema schema, Variable variable, object input)
        {
            var type = schema.FindType(variable.Type.Name);
            if (IsValidValue(schema, type, input))
            {
                if (input == null && variable.DefaultValue != null)
                {
                    return CoerceValueAst(schema, type, variable.DefaultValue, null);
                }

                return CoerceValue(schema, type, input);
            }

            throw new Exception("Variable {0} expected type '{1}'.".ToFormat(variable.Name, type.Name));
        }
예제 #25
0
        public void Enter(INode node)
        {
            _ancestorStack.Push(node);

            if (node is SelectionSet)
            {
                _parentTypeStack.Push(GetLastType());
                return;
            }

            if (node is Field field)
            {
                var parentType = _parentTypeStack.Peek().GetNamedType();
                var fieldType  = GetFieldDef(_schema, parentType, field);
                _fieldDefStack.Push(fieldType);
                var targetType = fieldType?.ResolvedType;
                _typeStack.Push(targetType);
                return;
            }

            if (node is Directive directive)
            {
                _directive = _schema.FindDirective(directive.Name);
            }

            if (node is Operation op)
            {
                IGraphType type = null;
                if (op.OperationType == OperationType.Query)
                {
                    type = _schema.Query;
                }
                else if (op.OperationType == OperationType.Mutation)
                {
                    type = _schema.Mutation;
                }
                else if (op.OperationType == OperationType.Subscription)
                {
                    type = _schema.Subscription;
                }
                _typeStack.Push(type);
                return;
            }

            if (node is FragmentDefinition def1)
            {
                var type = _schema.FindType(def1.Type.Name);
                _typeStack.Push(type);
                return;
            }

            if (node is InlineFragment def)
            {
                var type = def.Type != null?_schema.FindType(def.Type.Name) : GetLastType();

                _typeStack.Push(type);
                return;
            }

            if (node is VariableDefinition varDef)
            {
                var inputType = varDef.Type.GraphTypeFromType(_schema);
                _inputTypeStack.Push(inputType);
                return;
            }

            if (node is Argument argAst)
            {
                QueryArgument argDef  = null;
                IGraphType    argType = null;

                var args = GetDirective() != null?GetDirective()?.Arguments : GetFieldDef()?.Arguments;

                if (args != null)
                {
                    argDef  = args.Find(argAst.Name);
                    argType = argDef?.ResolvedType;
                }

                _argument = argDef;
                _inputTypeStack.Push(argType);
            }

            if (node is ListValue)
            {
                var type = GetInputType().GetNamedType();
                _inputTypeStack.Push(type);
            }

            if (node is ObjectField objectField)
            {
                var        objectType = GetInputType().GetNamedType();
                IGraphType fieldType  = null;

                if (objectType is IInputObjectGraphType complexType)
                {
                    var inputField = complexType.GetField(objectField.Name);

                    fieldType = inputField?.ResolvedType;
                }

                _inputTypeStack.Push(fieldType);
            }
        }
예제 #26
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;
        }
예제 #27
0
        public static IValue AstFromValue(this object value, ISchema schema, IGraphType type)
        {
            if (type is NonNullGraphType)
            {
                var nonnull = (NonNullGraphType)type;
                return(AstFromValue(value, schema, schema.FindType(nonnull.Type)));
            }

            if (value == null || type == null)
            {
                return(null);
            }

            // Convert IEnumerable to GraphQL list. If the GraphQLType is a list, but
            // the value is not an IEnumerable, convert the value using the list's item type.
            if (type is ListGraphType)
            {
                var listType = (ListGraphType)type;
                var itemType = schema.FindType(listType.Type);

                if (!(value is string) && value is IEnumerable)
                {
                    var list   = (IEnumerable)value;
                    var values = list.Map(item => AstFromValue(item, schema, itemType));
                    return(new ListValue(values));
                }

                return(AstFromValue(value, schema, itemType));
            }

            // Populate the fields of the input object by creating ASTs from each value
            // in the dictionary according to the fields in the input type.
            if (type is InputObjectGraphType)
            {
                if (!(value is Dictionary <string, object>))
                {
                    return(null);
                }

                var input = (InputObjectGraphType)type;
                var dict  = (Dictionary <string, object>)value;

                var fields = dict
                             .Select(pair =>
                {
                    var field     = input.Fields.FirstOrDefault(x => x.Name == pair.Key);
                    var fieldType = field != null ? schema.FindType(field.Type) : null;
                    return(new ObjectField(pair.Key, AstFromValue(pair.Value, schema, fieldType)));
                })
                             .ToList();

                return(new ObjectValue(fields));
            }


            Invariant.Check(
                type.IsInputType(schema),
                $"Must provide Input Type, cannot use: {type}");


            var inputType = type as ScalarGraphType;

            // Since value is an internally represented value, it must be serialized
            // to an externally represented value before converting into an AST.
            var serialized = inputType.Serialize(value);

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

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

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

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

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

            if (serialized is DateTime)
            {
                return(new DateTimeValue((DateTime)serialized));
            }

            if (serialized is string)
            {
                if (type is EnumerationGraphType)
                {
                    return(new EnumValue(serialized.ToString()));
                }

                return(new StringValue(serialized.ToString()));
            }

            throw new ExecutionError($"Cannot convert value to AST: {serialized}");
        }
예제 #28
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);
        }
예제 #29
0
        private bool IsValidValue(ISchema schema, GraphType type, object input)
        {
            NonNullGraphType typeAsNonNullGraphType = type as NonNullGraphType;
            if( typeAsNonNullGraphType != null )
            {
                if (input == null)
                {
                    return false;
                }

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

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

            ListGraphType typeAsListGraphType = type as ListGraphType;
            if( typeAsListGraphType != null )
            {
                GraphType listItemType = schema.FindType( typeAsListGraphType.Type );
                IEnumerable 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)
            {
                IReadOnlyDictionary<string, object> dict = input as IReadOnlyDictionary<string, object> ??
                    JObject.FromObject(input).Children()
                        .Cast<JProperty>()
                        .Select(x => {
                            JToken value = JToken.FromObject(x.Value);
                            return new KeyValuePair<string, object>(x.Name, value);
                        })
                        .ToDictionary(x => x.Key, x => x.Value);
                
                // 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 ) );
            }

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

            return false;
        }
예제 #30
0
        private IReadOnlyDictionary<string, object> GetArgumentValues(ISchema schema, IEnumerable<QueryArgument> definitionArguments, IEnumerable<Argument> astArguments, IEnumerable<Variable> variables)
        {
            List<QueryArgument> definitionArgumentsAsList = definitionArguments != null
                ? definitionArguments.ToList()
                : new List<QueryArgument>();

            if (definitionArgumentsAsList.Count == 0)
            {
                return null;
            }

            return definitionArgumentsAsList.Aggregate(new Dictionary<string, object>(), (acc, arg) =>
            {
                object value = astArguments != null ? astArguments.ValueFor(arg.Name) : null;
                GraphType type = schema.FindType(arg.Type);

                object coercedValue = CoerceValue(schema, type, value, variables);
                acc[arg.Name] = IsValidValue(schema, type, coercedValue)
                    ? coercedValue ?? arg.DefaultValue
                    : arg.DefaultValue;
                return acc;
            });
        }
예제 #31
0
        public Dictionary<string, object> GetArgumentValues(ISchema schema, QueryArguments definitionArguments, Arguments astArguments, Variables variables)
        {
            if (definitionArguments == null || !definitionArguments.Any())
            {
                return null;
            }

            return definitionArguments.Aggregate(new Dictionary<string, object>(), (acc, arg) =>
            {
                var value = astArguments != null ? astArguments.ValueFor(arg.Name) : null;
                var coercedValue = CoerceValueAst(schema, schema.FindType(arg.Type), value, variables);
                acc[arg.Name] = coercedValue ?? arg.DefaultValue;
                return acc;
            });
        }
예제 #32
0
        public bool IsValidValue(ISchema schema, IGraphType type, 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, 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;
                if (list != null && !(input is string))
                {
                    return(list.All(item => IsValidValue(schema, listItemType, item)));
                }

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

            if (type is IObjectGraphType || type is InputObjectGraphType)
            {
                var dict        = input as Dictionary <string, object>;
                var complexType = type as IComplexGraphType;

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

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

                return(complexType.Fields.All(field =>
                {
                    object fieldValue = null;
                    dict.TryGetValue(field.Name, out fieldValue);
                    return IsValidValue(
                        schema,
                        schema.FindType(field.Type),
                        fieldValue);
                }));
            }

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

            return(false);
        }
예제 #33
0
        public Dictionary<string, object> GetArgumentValues(ISchema schema, QueryArguments definitionArguments, Arguments astArguments, Variables variables)
        {
            if (definitionArguments == null || !definitionArguments.Any())
            {
                return null;
            }

            return definitionArguments.Aggregate(new Dictionary<string, object>(), (acc, arg) =>
            {
                var value = astArguments != null ? astArguments.ValueFor(arg.Name) : null;
                var type = schema.FindType(arg.Type);

                if (value is Variable)
                {
                    var variable = (Variable) value;
                    value = variables.ValueFor(variable.Name);
                }

                object coercedValue = null;
                if (IsValidValue(schema, type, value))
                {
                    coercedValue = CoerceValue(schema, type, value, variables);
                }
                acc[arg.Name] = coercedValue ?? arg.DefaultValue;
                return acc;
            });
        }
예제 #34
0
        public object CoerceValue(ISchema schema, IGraphType 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 IObjectGraphType || type is InputObjectGraphType)
            {
                var complexType = type as IComplexGraphType;
                var obj         = new Dictionary <string, object>();

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

                complexType.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);
        }
예제 #35
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;
        }
예제 #36
0
        public void Enter(INode node)
        {
            if (node is Operation)
            {
                var       op   = (Operation)node;
                GraphType type = null;
                if (op.OperationType == OperationType.Query)
                {
                    type = _schema.Query;
                }
                else if (op.OperationType == OperationType.Mutation)
                {
                    type = _schema.Mutation;
                }
                else if (op.OperationType == OperationType.Subscription)
                {
                }
                _typeStack.Push(type);
                return;
            }

            if (node is FragmentDefinition)
            {
                var def  = (FragmentDefinition)node;
                var type = _schema.FindType(def.Type.Name);
                _typeStack.Push(type);
                return;
            }

            if (node is SelectionSet)
            {
                _parentTypeStack.Push(GetLastType());
                return;
            }

            if (node is Field)
            {
                var field      = (Field)node;
                var parentType = _parentTypeStack.Peek();
                var fieldType  = GetFieldDef(_schema, parentType, field);
                _fieldDefStack.Push(fieldType);
                var targetType = _schema.FindType(fieldType?.Type);
                _typeStack.Push(targetType);
                return;
            }

            if (node is Directive)
            {
                var directive = (Directive)node;
                _directive = _schema.Directives.SingleOrDefault(x => x.Name == directive.Name);
            }

            if (node is Argument)
            {
                var           argAst  = (Argument)node;
                QueryArgument argDef  = null;
                GraphType     argType = null;

                var args = GetDirective() != null?GetDirective()?.Arguments : GetFieldDef()?.Arguments;

                if (args != null)
                {
                    argDef  = args.Find(argAst.Name);
                    argType = _schema.FindType(argDef?.Type);
                }

                _argument = argDef;
                _inputTypeStack.Push(argType);
            }
        }
예제 #37
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;
                }

                astType = ((NonNullType) astType).Type;
            }

            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;
        }
예제 #38
0
        /// <summary>
        /// Go through all of the implementations of type, as well as the interfaces
        /// that they implement. If any of those types include the provided field,
        /// suggest them, sorted by how often the type is referenced,  starting
        /// with Interfaces.
        /// </summary>
        private IEnumerable<string> getSuggestedTypeNames(
          ISchema schema,
          GraphType type,
          string fieldName)
        {
            if (type is InterfaceGraphType || type is UnionGraphType)
            {
                var suggestedObjectTypes = new List<string>();
                var interfaceUsageCount = new LightweightCache<string, int>(key => 0);

                var absType = type as GraphQLAbstractType;
                absType.PossibleTypes.Apply(possibleType =>
                {
                    if (!possibleType.HasField(fieldName))
                    {
                        return;
                    }

                    // This object defines this field.
                    suggestedObjectTypes.Add(possibleType.Name);

                    possibleType.Interfaces.Apply(possibleInterfaceType =>
                    {
                        var possibleInterface = schema.FindType(possibleInterfaceType);

                        if (!possibleInterface.HasField(fieldName))
                        {
                            return;
                        }

                        // This interface type defines this field.
                        interfaceUsageCount[possibleInterface.Name] = interfaceUsageCount[possibleInterface.Name] + 1;
                    });
                });

                var suggestedInterfaceTypes = interfaceUsageCount.Keys.OrderBy(x => interfaceUsageCount[x]);
                return suggestedInterfaceTypes.Concat(suggestedObjectTypes);
            }

            return Enumerable.Empty<string>();
        }