public CoercionResult CoerceInput(Type targetType, string name, object value)
        {
            Check.IsNotNull(targetType, nameof(targetType));

            if (!targetType.IsGenericType)
            {
                throw new InvalidOperationException(); // todo message
            }

            var elementType        = targetType.GetGenericArguments()[0];
            var elementTypeAdapter = GraphQLTypeHelper.CreateTypeAdapter(elementType);

            var enumerableValue = value is IEnumerable enumerable
                ? enumerable.Cast <object>()
                : new object[]
            {
                value
            };

            var coercedValues = enumerableValue
                                //.Select((x, i) => elementTypeAdapter.CoerceInput(elementType, $"{name}[{i}]", x))
                                .Select((x, i) => elementTypeAdapter.CoerceInput(elementType, $"{name}[{i}]", x is JToken token ? token.ToObject <object>() : x))
                                .ToList();

            var errors = coercedValues
                         .SelectMany(x => x.Errors ?? Enumerable.Empty <CoercionError>())
                         .ToList();

            var values = coercedValues
                         .Select(x => x.Value)
                         .ToList();

            return(new CoercionResult(values, errors));
        }
        public GraphQLTypeDescription GetTypeDescription(Type targetType)
        {
            Check.IsNotNull(targetType, nameof(targetType));

            if (!targetType.IsGenericType)
            {
                throw new InvalidOperationException(); // todo message
            }

            var elementType        = targetType.GetGenericArguments()[0];
            var elementTypeAdapter = GraphQLTypeHelper.CreateTypeAdapter(elementType);

            return(GraphQLTypeDescription.NotNull(elementTypeAdapter.GetTypeDescription(elementType)));
        }
Example #3
0
        public CoercionResult CoerceInput(Type targetType, string name, object value)
        {
            Check.IsNotNull(targetType, nameof(targetType));

            if (!targetType.IsGenericType)
            {
                throw new InvalidOperationException(); // todo message
            }

            var wrappedType = targetType.GetGenericArguments()[0];

            var json      = JsonConvert.SerializeObject(value);
            var converter = new InputConverter(name);
            var result    = JsonConvert.DeserializeObject(json, wrappedType, converter);
            var errors    = new List <CoercionError>(converter.Errors);

            var properties = result.GetType()
                             .GetProperties()
                             .Where(x => x.SetMethod != null && x.GetMethod != null && typeof(IInput).IsAssignableFrom(x.PropertyType));

            foreach (var property in properties)
            {
                if (property.GetValue(result) == null)
                {
                    var inputType = Input.FindInputType(property.PropertyType);

                    if (inputType == null)
                    {
                        throw new InvalidOperationException(); // todo message
                    }

                    var graphQLType = inputType.GetGenericArguments()[0];
                    var typeAdapter = GraphQLTypeHelper.CreateTypeAdapter(graphQLType);

                    if (typeAdapter == null)
                    {
                        throw new InvalidOperationException(); // todo message
                    }

                    var coercionResult = typeAdapter.CoerceInput(graphQLType, $"{name}.{property.Name}", null);
                    var propertyResult = Input.Create(property.PropertyType, coercionResult.Value);

                    errors.AddRange(coercionResult.Errors ?? Enumerable.Empty <CoercionError>());

                    property.SetValue(result, propertyResult);
                }
            }

            return(new CoercionResult(result, errors));
        }
Example #4
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var inputType = Input.FindInputType(objectType);

            if (inputType == null)
            {
                throw new InvalidOperationException(); // todo message
            }

            var graphQLType = inputType.GetGenericArguments()[0];
            var typeAdapter = GraphQLTypeHelper.CreateTypeAdapter(graphQLType);

            if (typeAdapter == null)
            {
                throw new InvalidOperationException(); // todo message
            }

            object value;

            if (reader.TokenType == JsonToken.StartArray)
            {
                var listValue = new List <object>();

                serializer.Populate(JArray.Load(reader).CreateReader(), listValue);

                value = listValue;
            }
            else
            {
                value = reader.Value;
            }

            //var value = reader.TokenType == JsonToken.StartArray
            //    ? JArray.Load(reader)
            //    : reader.Value;

            var coercionResult = typeAdapter.CoerceInput(graphQLType, $"{name}.{reader.Path}", value);
            var result         = Input.Create(objectType, coercionResult.Value);

            errors.AddRange(coercionResult.Errors ?? Enumerable.Empty <CoercionError>());

            return(result);
        }
        public CoercionResult CoerceResult(Type targetType, string name, object value)
        {
            Check.IsNotNull(targetType, nameof(targetType));

            if (!targetType.IsGenericType)
            {
                throw new InvalidOperationException(); // todo message
            }

            var elementType        = targetType.GetGenericArguments()[0];
            var elementTypeAdapter = GraphQLTypeHelper.CreateTypeAdapter(elementType);

            var coercedValue = elementTypeAdapter
                               .CoerceResult(elementType, name, value);

            return(new CoercionResult(
                       coercedValue.Value,
                       coercedValue.Value == null
                    ? new[] { new CoercionError(name, GetTypeDescription(targetType), value) }
                    : null));
        }
Example #6
0
        public GraphQLObject()
        {
            fields = new Dictionary <string, Field>();

            var fieldMembers = GetType()
                               .GetTypeInfo()
                               .GetMethods()
                               .Select(x => new
            {
                FieldAttribute    = x.GetCustomAttribute <FieldAttribute>(),
                ObsoleteAttribute = x.GetCustomAttribute <ObsoleteAttribute>(),
                Method            = x,
            })
                               .Where(x => x.FieldAttribute != null)
                               .ToList();

            foreach (var member in fieldMembers)
            {
                var fieldName  = member.FieldAttribute.Name ?? member.Method.Name;
                var returnType = member.Method.ReturnType;

                if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    returnType = returnType.GetGenericArguments()[0];
                }

                var genericParams = returnType.GetGenericArguments();

                // todo check return type is IValueAccessor
                if (genericParams.Length == 0)
                {
                    throw new InvalidOperationException(); // todo message
                }

                var fieldType    = genericParams[0];
                var nullable     = genericParams[0].IsGenericType && typeof(GraphQLNotNull <>).IsAssignableFrom(genericParams[0].GetGenericTypeDefinition());
                var singular     = true;
                var itemNullable = false;

                genericParams = genericParams[0].GetGenericArguments();

                if (genericParams.Length != 0 && genericParams[0].IsGenericType)
                {
                    singular = !typeof(GraphQLList <>).IsAssignableFrom(genericParams[0].GetGenericTypeDefinition());

                    genericParams = genericParams[0].GetGenericArguments();

                    if (genericParams.Length != 0 && genericParams[0].IsGenericType)
                    {
                        itemNullable = typeof(GraphQLNotNull <>).IsAssignableFrom(genericParams[0].GetGenericTypeDefinition());
                    }
                }

                fields.Add(fieldName, new Field(
                               fieldName,
                               member.FieldAttribute.Description,
                               member.ObsoleteAttribute == null ? null : member.ObsoleteAttribute.Message ?? "No longer supported",
                               nullable,
                               singular,
                               itemNullable,
                               new BoundGraphQLTypeAdapter(fieldType, GraphQLTypeHelper.CreateTypeAdapter(fieldType)),
                               member.Method.GetParameters()
                               .Where(x => x.ParameterType.IsGenericType && x.ParameterType.GetGenericTypeDefinition() == typeof(Input <>))
                               .ToDictionary(
                                   x => x.Name,
                                   x => new BoundGraphQLTypeAdapter(
                                       x.ParameterType.GetGenericArguments()[0],
                                       GraphQLTypeHelper.CreateTypeAdapter(x.ParameterType.GetGenericArguments()[0]))), // todo gracefully fail. we're grabbing the GQL type from the generic parameter of Input<>
                               new ValueAccessorFactory(this, member.Method)));
            }
        }