/// <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>(); }
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))); }
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); }
private IInputObjectGraphType Configure <TSourceType>() { _graphType = new AutoInputObjectGraphType <TSourceType>(); return(_graphType); }
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); } }
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);
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); } } }