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))); }
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)); }
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)); }
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))); } }