/// <inheritdoc/>
        public override void VisitInputObjectFieldDefinition(FieldType field, IInputObjectGraphType type, ISchema schema)
        {
            // 2.2
            if (field.Name.StartsWith("__"))
            {
                throw new InvalidOperationException($"The input field '{field.Name}' of an Input Object '{type.Name}' must not have a name which begins with the __ (two underscores).");
            }

            if (field.ResolvedType == null)
            {
                throw new InvalidOperationException($"The field '{field.Name}' of an Input Object type '{type.Name}' must have non-null '{nameof(IFieldType.ResolvedType)}' property.");
            }

            if (field.ResolvedType is GraphQLTypeReference)
            {
                throw new InvalidOperationException($"The field '{field.Name}' of an Input Object type '{type.Name}' has '{nameof(GraphQLTypeReference)}' type. This type must be replaced with a reference to the actual GraphQL type before using the reference.");
            }

            // 2.3
            if (!field.ResolvedType.IsInputType())
            {
                throw new InvalidOperationException($"The input field '{field.Name}' of an Input Object '{type.Name}' must be an input type.");
            }

            // validate default value
            if (field.DefaultValue is GraphQLValue value)
            {
                field.DefaultValue = Execution.ExecutionHelper.CoerceValue(field.ResolvedType, Language.CoreToVanillaConverter.Value(value)).Value;
            }
            else if (field.DefaultValue != null && !field.ResolvedType.IsValidDefault(field.DefaultValue))
            {
                throw new InvalidOperationException($"The default value of Input Object type field '{type.Name}.{field.Name}' is invalid.");
            }
        }
 /// <summary>
 /// Prevents a default instance of the <see cref="InputObjectResolver" /> class from being created.
 /// </summary>
 /// <param name="otherResolver">The other resolver to copy core data from.</param>
 private InputObjectResolver(InputObjectResolver otherResolver)
 {
     _graphType      = otherResolver._graphType;
     _objectType     = otherResolver._objectType;
     _propSetters    = otherResolver._propSetters;
     _fieldResolvers = otherResolver._fieldResolvers;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="InputObjectResolver" /> class.
 /// </summary>
 /// <param name="graphType">The graph type in the target schema for the object in question.</param>
 /// <param name="concreteType">The concrete type to render the data as.</param>
 public InputObjectResolver(IInputObjectGraphType graphType, Type concreteType)
 {
     _graphType      = Validation.ThrowIfNullOrReturn(graphType, nameof(graphType));
     _objectType     = Validation.ThrowIfNullOrReturn(concreteType, nameof(concreteType));
     _propSetters    = InstanceFactory.CreatePropertySetterInvokerCollection(concreteType);
     _fieldResolvers = new Dictionary <string, IInputValueResolver>();
 }
Esempio n. 4
0
        public string PrintInputObject(IInputObjectGraphType type)
        {
            var description = Options.IncludeDescriptions ? PrintDescription(type.Description) : "";
            var fields      = type.Fields.Select(x => "  " + PrintInputValue(x));

            return(description + "input {1} {{{0}{2}{0}}}".ToFormat(Environment.NewLine, type.Name, string.Join(Environment.NewLine, fields)));
        }
Esempio n. 5
0
 public string PrintType(IGraphType type)
 {
     return(type switch
     {
         EnumerationGraphType graphType => PrintEnum(graphType),
         ScalarGraphType scalarGraphType => PrintScalar(scalarGraphType),
         IObjectGraphType objectGraphType => PrintObject(objectGraphType),
         IInterfaceGraphType interfaceGraphType => PrintInterface(interfaceGraphType),
         UnionGraphType unionGraphType => PrintUnion(unionGraphType),
         DirectiveGraphType directiveGraphType => PrintDirective(directiveGraphType),  //TODO: DirectiveGraphType does not inherit IGraphType
         IInputObjectGraphType input => PrintInputObject(input),
         _ => throw new InvalidOperationException($"Unknown GraphType '{type.GetType().Name}' with name '{type.Name}'")
     });
        // See 'Type Validation' section in https://spec.graphql.org/June2018/#sec-Input-Objects
        // Input Object types have the potential to be invalid if incorrectly defined.
        /// <inheritdoc/>
        public override void VisitInputObject(IInputObjectGraphType type, ISchema schema)
        {
            // 1
            if (type.Fields.Count == 0)
            {
                throw new InvalidOperationException($"An Input Object type '{type.Name}' must define one or more input fields.");
            }

            // 2.1
            foreach (var item in type.Fields.List.ToLookup(f => f.Name))
            {
                if (item.Count() > 1)
                {
                    throw new InvalidOperationException($"The input field '{item.Key}' must have a unique name within Input Object type '{type.Name}'; no two fields may share the same name.");
                }
            }
        }
        /// <summary>
        /// Creates the object resolver used to individually resolve the fields against the schema and assemble the final input object.
        /// </summary>
        /// <param name="inputType">The graph type to generate a resolver for.</param>
        /// <param name="type">The concrete type that the supplied graph type is linked to.</param>
        /// <returns>IQueryInputValueResolver.</returns>
        private IInputValueResolver CreateObjectResolver(IInputObjectGraphType inputType, Type type)
        {
            var inputObjectResolver = new InputObjectResolver(inputType, type);

            foreach (var field in inputType.Fields)
            {
                IInputValueResolver childResolver;
                if (field.TypeExpression.TypeName == inputType.Name)
                {
                    childResolver = inputObjectResolver;
                }
                else
                {
                    var graphType = _schema.KnownTypes.FindGraphType(field.TypeExpression.TypeName);
                    childResolver = this.CreateResolver(graphType, field.TypeExpression);
                }

                inputObjectResolver.AddFieldResolver(field.Name, childResolver);
            }

            return(inputObjectResolver);
        }
Esempio n. 8
0
 private IInputObjectGraphType Configure <TSourceType>()
 {
     _graphType = new AutoInputObjectGraphType <TSourceType>();
     return(_graphType);
 }
Esempio n. 9
0
 public override void VisitInputObjectFieldDefinition(FieldType field, IInputObjectGraphType type, ISchema schema) => Replace(field);
 /// <inheritdoc />
 public virtual void VisitInputObjectFieldDefinition(FieldType field, IInputObjectGraphType type, ISchema schema)
 {
 }
 /// <inheritdoc />
 public virtual void VisitInputObject(IInputObjectGraphType type, ISchema schema)
 {
 }
 /// <inheritdoc/>
 public void VisitInputObject(IInputObjectGraphType type, ISchema schema) => ValidateAppliedDirectives(type, null, null, schema, DirectiveLocation.InputObject);
 /// <inheritdoc/>
 public void VisitInputObjectFieldDefinition(FieldType field, IInputObjectGraphType type, ISchema schema) => ValidateAppliedDirectives(field, type, null, schema, DirectiveLocation.InputFieldDefinition);
 public void VisitObject(ValidationContext context, VariableDefinition variable, VariableName variableName, IInputObjectGraphType type, object?variableValue, object?parsedValue)
 {
     foreach (var visitor in _visitors)
     {
         visitor.VisitObject(context, variable, variableName, type, variableValue, parsedValue);
     }
 }
Esempio n. 15
0
            public override void VisitField(ValidationContext context, VariableDefinition variable, VariableName variableName, IInputObjectGraphType type, FieldType field, object variableValue, object parsedValue)
            {
                var lengthDirective = field.FindAppliedDirective("length");

                if (lengthDirective == null)
                {
                    return;
                }

                var min = lengthDirective.FindArgument("min")?.Value;
                var max = lengthDirective.FindArgument("max")?.Value;

                if (parsedValue == null)
                {
                    if (min != null)
                    {
                        context.ReportError(new InputFieldsAndArgumentsOfCorrectLengthError(context, variable, variableName, null, (int?)min, (int?)max));
                    }
                }
                else if (parsedValue is string str)
                {
                    if (min != null && str.Length < (int)min || max != null && str.Length > (int)max)
                    {
                        context.ReportError(new InputFieldsAndArgumentsOfCorrectLengthError(context, variable, variableName, str.Length, (int?)min, (int?)max));
                    }
                }
            }
 public override void VisitInputObjectFieldDefinition(FieldType field, IInputObjectGraphType type, ISchema schema) => SetDescription(field);
 /// <inheritdoc/>
 public virtual void VisitObject(ValidationContext context, VariableDefinition variable, VariableName variableName, IInputObjectGraphType type, object?variableValue, object?parsedValue)
 {
 }
 public override void VisitInputObject(IInputObjectGraphType type, ISchema schema) => SetDescription(type);
Esempio n. 19
0
        public virtual void RegisterCommands(IEnumerable <Type> commandHandlerTypes)
        {
            foreach (var commandHandlerType in commandHandlerTypes)
            {
                var genericType = commandHandlerType.GetInterfaces().Single(x => x.GetTypeInfo().IsAssignableToGenericType(typeof(ICommandHandler <,>)) ||
                                                                            x.GetTypeInfo().IsAssignableToGenericType(typeof(IAsyncCommandHandler <,>)));
                var genericArguments = genericType.GetGenericArguments();
                var commandType      = genericArguments[0];
                var queryResultType  = genericArguments[1];
                var resultType       = genericArguments[1];

                if (commandType.GetCustomAttribute <ExposeGraphQLAttribute>() == null)
                {
                    continue;
                }

                var isCollection = resultType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(resultType);

                if (isCollection)
                {
                    resultType = resultType.GetGenericArguments()[0];
                }

                var descriptionAttribute = commandType.GetCustomAttribute <DescriptionAttribute>();
                var exposeAttribute      = commandType.GetCustomAttribute <ExposeGraphQLAttribute>();
                var authorizeAttribute   = commandType.GetCustomAttribute <AuthorizeAttribute>();

                if (exposeAttribute == null)
                {
                    continue;
                }

                IInputObjectGraphType inputGqlType = null;

                var properties = commandType.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(x => !typeof(IResolveFieldContext).IsAssignableFrom(x.PropertyType)).ToList();

                if (properties.Any())
                {
                    var inputObjectType = typeof(AutoInputGraphType <>).MakeGenericType(commandType);
                    inputGqlType             = (IInputObjectGraphType)_container.GetInstance(inputObjectType);
                    inputGqlType.Description = descriptionAttribute?.Description;
                }

                IGraphType resultGqlType = null;

                if (!_typeCache.ContainsKey(queryResultType) && !BuiltInTypeMappings.Any(x => x.clrType == resultType) && !TypeMappings.Any(x => x.clrType == resultType))
                {
                    var resultTypeName   = resultType.Name;
                    var returnObjectType = typeof(AutoObjectGraphType <>).MakeGenericType(resultType);
                    resultGqlType      = (IGraphType)_container.GetInstance(returnObjectType);
                    resultGqlType.Name = resultTypeName;

                    ListGraphType listGqlType = null;
                    if (isCollection)
                    {
                        var name = resultGqlType.Name;
                        listGqlType = (ListGraphType)Activator.CreateInstance(typeof(ListGraphType <>).MakeGenericType(returnObjectType), null);
                        listGqlType.ResolvedType = resultGqlType;
                        resultGqlType            = (IGraphType)listGqlType;
                        // resultGqlType.Name = "ListOf" + name;
                    }

                    RegisterTypeMapping(resultType, returnObjectType);
                }
                else if (_typeCache.ContainsKey(queryResultType))
                {
                    resultGqlType = _typeCache[queryResultType];
                }

                var arguments = new List <QueryArgument>();

                if (inputGqlType != null)
                {
                    var argument = AllowNullCommand ? new QueryArgument(inputGqlType) : new QueryArgument(new NonNullGraphType(inputGqlType));
                    argument.Name = "command";
                    arguments.Add(argument);
                }

                var mutationName = exposeAttribute.IsFieldNameSet ? exposeAttribute.FieldName : _commandNameSuffixRegex.Replace(commandType.Name, string.Empty);

                if (!Mutation.HasField(mutationName))
                {
                    var type = new FieldType
                    {
                        Type = resultGqlType == null?BuiltInTypeMappings.Where(x => x.clrType == resultType).Select(x => x.graphType).SingleOrDefault() ?? TypeMappings.Where(x => x.clrType == resultType).Select(x => x.graphType).SingleOrDefault() : null,
                                   ResolvedType = resultGqlType,
                                   Resolver     = new CommandResolver(_container, commandHandlerType, commandType, resultType, GetJsonSerializerSettings()),
                                   Name         = GetNormalizedFieldName(mutationName),
                                   Description  = descriptionAttribute?.Description,
                                   Arguments    = new QueryArguments(arguments)
                    };
                    type.Metadata[GraphQLExtensions.PermissionsKey] = authorizeAttribute?.Permissions?.ToList();

                    Mutation.AddField(type);
                }
            }
        }