Example #1
0
        /// <inheritdoc/>
        public void Leave(INode node, ValidationContext context)
        {
            _ancestorStack.Pop();

            if (node is SelectionSet)
            {
                _parentTypeStack.Pop();
            }
            else if (node is Field)
            {
                _fieldDefStack.Pop();
                _typeStack.Pop();
            }
            else if (node is Directive)
            {
                _directive = null;
            }
            else if (node is Operation || node is FragmentDefinition || node is InlineFragment)
            {
                _typeStack.Pop();
            }
            else if (node is VariableDefinition)
            {
                _inputTypeStack.Pop();
            }
            else if (node is Argument)
            {
                _argument = null;
                _inputTypeStack.Pop();
            }
            else if (node is ListValue || node is ObjectField)
            {
                _inputTypeStack.Pop();
            }
        }
Example #2
0
        /// <inheritdoc/>
        public virtual Task <bool> AllowDirective(DirectiveGraphType directive)
        {
            if (directive.Introspectable.HasValue)
            {
                return(directive.Introspectable.Value ? Allowed : Forbidden);
            }

            // If the directive has all its locations of type ExecutableDirectiveLocation,
            // only then it will be present in the introspection response.
            foreach (var location in directive.Locations)
            {
                if (!(
                        location == DirectiveLocation.Query ||
                        location == DirectiveLocation.Mutation ||
                        location == DirectiveLocation.Subscription ||
                        location == DirectiveLocation.Field ||
                        location == DirectiveLocation.FragmentDefinition ||
                        location == DirectiveLocation.FragmentSpread ||
                        location == DirectiveLocation.InlineFragment))
                {
                    return(Forbidden);
                }
            }

            return(Allowed);
        }
Example #3
0
        public void InputTypeIsDereferenced_DirectiveArgument(Type referenceType, Type mappedType)
        {
            var query = new ObjectGraphType();

            query.Field(typeof(StringGraphType), "test");
            var schema = new Schema
            {
                Query = query
            };
            var directive = new DirectiveGraphType("MyDirective")
            {
                Arguments = new QueryArguments
                {
                    new QueryArgument(referenceType)
                    {
                        Name = "arg"
                    }
                }
            };

            directive.Locations.Add(DirectiveLocation.Field);
            schema.Directives.Register(directive);
            schema.RegisterTypeMapping(typeof(MyClass), typeof(MyClassObjectType));
            schema.RegisterTypeMapping(typeof(MyClass), typeof(MyClassInputType));
            schema.RegisterTypeMapping(typeof(MappedEnum), typeof(MappedEnumGraphType));
            schema.Initialize();
            schema.Directives.Find("MyDirective").Arguments.Find("arg").Type.ShouldBe(mappedType);
        }
        public void prints_directive_without_arguments()
        {
            var    d      = new DirectiveGraphType("my", DirectiveLocation.Field, DirectiveLocation.Query);
            string result = new SchemaPrinter(null).PrintDirective(d);

            result.ShouldBe("directive @my on FIELD | QUERY");
        }
        protected virtual DirectiveGraphType ToDirective(GraphQLDirectiveDefinition directiveDef)
        {
            var result = new DirectiveGraphType((string)directiveDef.Name.Value)
            {
                Description = directiveDef.Description?.Value.ToString() ?? directiveDef.Comment?.Text.ToString(),
                Repeatable  = directiveDef.Repeatable,
                Arguments   = ToQueryArguments(directiveDef.Arguments)
            };

            if (directiveDef.Locations?.Count > 0) // just in case
            {
                foreach (var location in directiveDef.Locations)
                {
                    if (__DirectiveLocation.Instance.Values.FindByName(location.Value)?.Value is DirectiveLocation l)
                    {
                        result.Locations.Add(l);
                    }
                    else
                    {
                        throw new InvalidOperationException($"Directive '{result.Name}' has an unknown directive location '{location.Value}'.");
                    }
                }
            }

            return(result);
        }
 internal Directive(DirectiveGraphType oldDirective, DirectiveGraphType newDirective)
 {
     this.oldDirective = oldDirective;
     this.newDirective = newDirective;
     this.oldArguments = oldDirective.Arguments;
     this.newArguments = newDirective.Arguments;
 }
Example #7
0
        public void Leave(INode node)
        {
            if (node is Operation ||
                node is FragmentDefinition)
            {
                _typeStack.Pop();
            }

            if (node is SelectionSet)
            {
                _parentTypeStack.Pop();
            }

            if (node is Field)
            {
                _fieldDefStack.Pop();
                _typeStack.Pop();
            }

            if (node is Directive)
            {
                _directive = null;
            }

            if (node is Argument)
            {
                _argument = null;
                _inputTypeStack.Pop();
            }
        }
 public override void VisitDirective(DirectiveGraphType directive, ISchema schema)
 {
     if (directive.Locations.Count == 0)
     {
         throw new InvalidOperationException($"Directive '{directive}' must have locations");
     }
 }
 /// <summary>
 /// Initializes a new instance with the specified properties.
 /// </summary>
 public KnownArgumentNamesError(ValidationContext context, Argument node, DirectiveGraphType directive)
     : base(context.OriginalQuery, NUMBER,
            UnknownDirectiveArgMessage(
                node.Name,
                directive.Name,
                StringUtils.SuggestionList(node.Name, directive.Arguments?.Select(q => q.Name))),
            node)
 {
 }
        public string PrintDirective(DirectiveGraphType directive)
        {
            var builder = new StringBuilder();

            builder.Append(PrintDescription(directive.Description));
            builder.AppendLine($"directive @{directive.Name}(");
            builder.AppendLine(formatDirectiveArguments(directive.Arguments));
            builder.Append($") on {formatDirectiveLocationList(directive.Locations)}");
            return(builder.ToString().TrimStart());
        }
Example #11
0
        protected virtual DirectiveGraphType ToDirective(GraphQLDirectiveDefinition directiveDef)
        {
            var locations = directiveDef.Locations.Select(l => ToDirectiveLocation(l.Value));
            var directive = new DirectiveGraphType(directiveDef.Name.Value, locations);

            var arguments = directiveDef.Arguments.Select(ToArguments);

            directive.Arguments = new QueryArguments(arguments);

            return(directive);
        }
        protected virtual DirectiveGraphType ToDirective(GraphQLDirectiveDefinition directiveDef)
        {
            var locations = directiveDef.Locations.Select(l => ToDirectiveLocation(l.Value));
            var directive = new DirectiveGraphType(directiveDef.Name.Value, locations)
            {
                Description = directiveDef.Comment?.Text
            };

            directive.Arguments = ToQueryArguments(directiveDef.Arguments);

            return(directive);
        }
 private void ValidateDirectiveArgumentsUniqueness(DirectiveGraphType type)
 {
     if (type.Arguments?.Count > 0)
     {
         foreach (var item in type.Arguments.List.ToLookup(f => f.Name))
         {
             if (item.Count() > 1)
             {
                 throw new InvalidOperationException($"The argument '{item.Key}' must have a unique name within directive '{type.Name}'; no two directive arguments may share the same name.");
             }
         }
     }
 }
Example #14
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}'")
     });
        public void prints_repeatable_directive_with_arguments()
        {
            var d = new DirectiveGraphType("my", DirectiveLocation.Field, DirectiveLocation.Query)
            {
                Repeatable = true,
                Arguments  = new QueryArguments(new QueryArgument(new IntGraphType())
                {
                    Name = "max"
                })
            };
            string result = new SchemaPrinter(null).PrintDirective(d);

            result.ShouldBe(@"directive @my(
  max: Int
) repeatable on FIELD | QUERY");
        }
Example #16
0
        // See 'Type Validation' section in https://spec.graphql.org/June2018/#sec-Type-System.Directives
        // Directive types have the potential to be invalid if incorrectly defined.
        /// <inheritdoc/>
        public override void VisitDirective(DirectiveGraphType type, ISchema schema)
        {
            if (type.Locations.Count == 0)
            {
                throw new InvalidOperationException($"Directive '{type.Name}' must have locations");
            }

            // 1. A directive definition must not contain the use of a directive which references itself directly.
            // TODO:

            // 2. A directive definition must not contain the use of a directive which references itself indirectly
            // by referencing a Type or Directive which transitively includes a reference to this directive.
            // TODO:

            // 3
            if (type.Name.StartsWith("__"))
            {
                throw new InvalidOperationException($"The directive '{type.Name}' must not have a name which begins with the __ (two underscores).");
            }
        }
        /// <summary>
        /// Inspects the given type and, in accordance with the rules of this maker, will
        /// generate a complete set of necessary graph types required to support it.
        /// </summary>
        /// <param name="concreteType">The concrete type to incorporate into the schema.</param>
        /// <returns>GraphTypeCreationResult.</returns>
        public GraphTypeCreationResult CreateGraphType(Type concreteType)
        {
            var formatter = _schema.Configuration.DeclarationOptions.GraphNamingFormatter;
            var template  = GraphQLProviders.TemplateProvider.ParseType(concreteType) as IGraphDirectiveTemplate;

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

            var result = new GraphTypeCreationResult();

            var directive = new DirectiveGraphType(
                formatter.FormatFieldName(template.Name),
                template.Locations,
                template.ObjectType,
                template.CreateResolver())
            {
                Description = template.Description,
                Publish     = template.Publish,
            };

            // all arguments are required to have the same signature via validation
            // can use any method to fill the arg field list
            var argMaker = new GraphArgumentMaker(_schema);

            foreach (var argTemplate in template.Arguments)
            {
                var argumentResult = argMaker.CreateArgument(argTemplate);
                directive.Arguments.AddArgument(argumentResult.Argument);

                result.MergeDependents(argumentResult);
            }

            result.GraphType    = directive;
            result.ConcreteType = concreteType;
            return(result);
        }
Example #18
0
 public DirectiveAdded(DirectiveGraphType directive) : base(Criticality.NonBreaking)
 {
     this.directive = directive;
 }
 public override void VisitDirective(DirectiveGraphType directive, ISchema schema) => SetDescription(directive);
Example #20
0
 public override void VisitDirectiveArgumentDefinition(QueryArgument argument, DirectiveGraphType type, ISchema schema) => Replace(argument);
Example #21
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);
            }
        }
 /// <inheritdoc />
 public virtual void VisitDirective(DirectiveGraphType type, ISchema schema)
 {
 }
 /// <inheritdoc />
 public virtual void VisitDirectiveArgumentDefinition(QueryArgument argument, DirectiveGraphType type, ISchema schema)
 {
 }
Example #24
0
 /// <inheritdoc/>
 public void VisitDirectiveArgumentDefinition(QueryArgument argument, DirectiveGraphType type, ISchema schema) => ValidateAppliedDirectives(argument, schema, DirectiveLocation.ArgumentDefinition);
Example #25
0
 public DirectiveRemoved(DirectiveGraphType directive) : base(Criticality.Breaking)
 {
     this.directive = directive;
 }
Example #26
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);
            }
        }
Example #27
0
 /// <inheritdoc/>
 public void VisitDirective(DirectiveGraphType type, ISchema schema) => ValidateAppliedDirectives(type, schema, null); // no location for directives (yet), see https://github.com/graphql/graphql-spec/issues/818
Example #28
0
 /// <inheritdoc/>
 public virtual Task <bool> AllowDirective(DirectiveGraphType directive) => _completed;
        /// <inheritdoc/>
        public override void VisitDirectiveArgumentDefinition(QueryArgument argument, DirectiveGraphType type, ISchema schema)
        {
            // 4.1
            if (argument.Name.StartsWith("__"))
            {
                throw new InvalidOperationException($"The argument '{argument.Name}' of directive '{type.Name}' must not have a name which begins with the __ (two underscores).");
            }

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

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

            // 4.2
            if (!argument.ResolvedType.IsInputType())
            {
                throw new InvalidOperationException($"The argument '{argument.Name}' of directive '{type.Name}' must be an input type.");
            }

            // validate default
            if (argument.DefaultValue is GraphQLValue value)
            {
                argument.DefaultValue = Execution.ExecutionHelper.CoerceValue(argument.ResolvedType, Language.CoreToVanillaConverter.Value(value)).Value;
            }
            else if (argument.DefaultValue != null && !argument.ResolvedType.IsValidDefault(argument.DefaultValue))
            {
                throw new InvalidOperationException($"The default value of argument '{argument.Name}' of directive '{type.Name}' is invalid.");
            }
        }
Example #30
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);
            }
        }