Пример #1
0
 /// <summary>
 /// Add any methods marked with GraphQLMutationAttribute in the given type to the schema. Names are added as lowerCaseCamel`
 /// </summary>
 /// <param name="mutationClassInstance"></param>
 /// <typeparam name="TType"></typeparam>
 public void AddMutationFrom <TType>(TType mutationClassInstance)
 {
     foreach (var method in mutationClassInstance.GetType().GetMethods())
     {
         if (method.GetCustomAttribute(typeof(GraphQLMutationAttribute)) is GraphQLMutationAttribute attribute)
         {
             var    isAsync = method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null;
             string name    = SchemaGenerator.ToCamelCaseStartsLower(method.Name);
             //== JT: Allow user to customize the schema-first casing.
             var n = (System.ComponentModel.DisplayNameAttribute)method.GetCustomAttribute(typeof(System.ComponentModel.DisplayNameAttribute), false);
             if (n != null)
             {
                 name = n.DisplayName;
             }
             //==
             var claims           = method.GetCustomAttributes(typeof(GraphQLAuthorizeAttribute)).Cast <GraphQLAuthorizeAttribute>();
             var requiredClaims   = new RequiredClaims(claims);
             var actualReturnType = GetTypeFromMutationReturn(isAsync ? method.ReturnType.GetGenericArguments()[0] : method.ReturnType);
             var typeName         = GetSchemaTypeNameForDotnetType(actualReturnType);
             var returnType       = new GqlTypeInfo(() => GetReturnType(typeName), actualReturnType);
             var mutationType     = new MutationType(this, name, returnType, mutationClassInstance, method, attribute.Description, requiredClaims, isAsync, SchemaFieldNamer);
             mutations[name] = mutationType;
         }
     }
 }
Пример #2
0
        internal Field(string name, LambdaExpression resolve, string description, GqlTypeInfo returnType, RequiredClaims authorizeClaims)
        {
            Name            = name;
            Description     = description;
            AuthorizeClaims = authorizeClaims;
            ReturnType      = returnType ?? throw new ArgumentNullException(nameof(returnType), "retypeType can not be null");

            if (resolve != null)
            {
                if (resolve.Body.NodeType == ExpressionType.Call && ((MethodCallExpression)resolve.Body).Method.DeclaringType == typeof(ArgumentHelper) && ((MethodCallExpression)resolve.Body).Method.Name == "WithService")
                {
                    // they are wanting services injected
                    var call             = (MethodCallExpression)resolve.Body;
                    var lambdaExpression = (LambdaExpression)((UnaryExpression)call.Arguments.First()).Operand;
                    Resolve  = lambdaExpression.Body;
                    Services = lambdaExpression.Parameters.Select(p => p.Type).ToList();
                }
                else
                {
                    Resolve = resolve.Body;
                }
                FieldParam = resolve.Parameters.First();

                if (resolve.Body.NodeType == ExpressionType.MemberAccess)
                {
                    ReturnType.TypeNotNullable     = GraphQLNotNullAttribute.IsMemberMarkedNotNull(((MemberExpression)resolve.Body).Member) || ReturnType.TypeNotNullable;
                    ReturnType.ElementTypeNullable = GraphQLElementTypeNullable.IsMemberElementMarkedNullable(((MemberExpression)resolve.Body).Member) || ReturnType.ElementTypeNullable;
                }
            }
        }
Пример #3
0
        public MutationType(ISchemaProvider schema, string methodName, GqlTypeInfo returnType, object mutationClassInstance, MethodInfo method, string description, RequiredClaims authorizeClaims, bool isAsync)
        {
            Description = description;
            ReturnType  = returnType;
            this.mutationClassInstance = mutationClassInstance;
            this.method     = method;
            Name            = methodName;
            AuthorizeClaims = authorizeClaims;
            this.isAsync    = isAsync;

            argInstanceType = method.GetParameters()
                              .FirstOrDefault(p => p.GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null || p.ParameterType.GetTypeInfo().GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null)?.ParameterType;
            if (argInstanceType != null)
            {
                foreach (var item in argInstanceType.GetProperties())
                {
                    if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
                    {
                        continue;
                    }
                    argumentTypes.Add(SchemaGenerator.ToCamelCaseStartsLower(item.Name), ArgType.FromProperty(schema, item));
                }
                foreach (var item in argInstanceType.GetFields())
                {
                    if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
                    {
                        continue;
                    }
                    argumentTypes.Add(SchemaGenerator.ToCamelCaseStartsLower(item.Name), ArgType.FromField(schema, item));
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Add a mapping from a Dotnet type to a GQL schema type. Make sure you have added the GQL type
        /// in the schema as a Scalar type or full type
        /// </summary>
        /// <param name="gqlType">The GQL schema type in full form. E.g. [Int!]!, [Int], Int, etc.</param>
        /// <typeparam name="TFrom"></typeparam>
        public void AddTypeMapping <TFrom>(string gqlType)
        {
            var typeInfo = GqlTypeInfo.FromGqlType(this, typeof(TFrom), gqlType);

            // add mapping
            customTypeMappings.Add(typeof(TFrom), typeInfo);
            SetupIntrospectionTypesAndField();
        }
Пример #5
0
        public MutationType(ISchemaProvider schema, string methodName, GqlTypeInfo returnType, object mutationClassInstance, MethodInfo method, string description, RequiredClaims authorizeClaims, bool isAsync, Func <MemberInfo, string> fieldNamer)
        {
            Description = description;
            ReturnType  = returnType;
            this.mutationClassInstance = mutationClassInstance;
            this.method     = method;
            Name            = methodName;
            AuthorizeClaims = authorizeClaims;
            this.isAsync    = isAsync;

            argInstanceType = method.GetParameters()
                              .FirstOrDefault(p => p.GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null || p.ParameterType.GetTypeInfo().GetCustomAttribute(typeof(MutationArgumentsAttribute)) != null)?.ParameterType;
            if (argInstanceType != null)
            {
                foreach (var item in argInstanceType.GetProperties())
                {
                    if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
                    {
                        continue;
                    }
                    argumentTypes.Add(fieldNamer(item), ArgType.FromProperty(schema, item));
                }
                foreach (var item in argInstanceType.GetFields())
                {
                    if (GraphQLIgnoreAttribute.ShouldIgnoreMemberFromInput(item))
                    {
                        continue;
                    }
                    argumentTypes.Add(fieldNamer(item), ArgType.FromField(schema, item));
                }
            }
            //== JT: Start Here
            else
            {
                /*== JT
                 * When parameters are the standard System Types like; Int, String, etc or using the EntityGraphQL.Schema.RequiredField,
                 * loop through the parameters and NOT the object's properties
                 * NOTE: some parameters might be Services
                 * EX: public ReturnModel RemoveById(DataContext context, RequiredField<int> id)
                 */
                // !! Forcing a single parameter ONLY. Anything more than that should require a POCO !!
                ParameterInfo item = method.GetParameters()
                                     .FirstOrDefault(p => p.ParameterType.Namespace.StartsWith("EntityGraphQL.Schema") || p.ParameterType.Namespace.StartsWith("System"));

                if (item.ParameterType.Name == "Nullable`1")
                {
                    Type argType = item.ParameterType.GetGenericArguments()[0];
                    argInstanceType = argType;
                }
                else
                {
                    argInstanceType = item.ParameterType;
                }
                //TODO: see if able to use the "fieldNamer()" function
                argumentTypes.Add(SchemaGenerator.ToCamelCaseStartsLower(item.Name), ArgType.FromParameter(schema, item));
            }
            //==
        }
Пример #6
0
        public static GqlTypeInfo FromGqlType(ISchemaProvider schema, Type dotnetType, string gqlType)
        {
            var strippedType = gqlType.Trim('!').Trim('[').Trim(']').Trim('!');
            var typeInfo     = new GqlTypeInfo(() => schema.Type(strippedType), dotnetType)
            {
                TypeNotNullable = gqlType.EndsWith("!"),
                IsList          = gqlType.Contains("["),
            };

            typeInfo.ElementTypeNullable = !(typeInfo.IsList && gqlType.Trim('!').Trim('[').Trim(']').EndsWith("!"));

            return(typeInfo);
        }
Пример #7
0
        private static TypeElement BuildType(ISchemaProvider schema, GqlTypeInfo typeInfo, Type clrType, bool isInput = false)
        {
            // Is collection of objects?
            var type = new TypeElement();

            if (clrType.IsEnumerableOrArray())
            {
                type.Kind   = "LIST";
                type.Name   = null;
                type.OfType = BuildType(schema, typeInfo, clrType.GetEnumerableOrArrayType(), isInput);
            }
            else if (clrType.Name == "EntityQueryType`1")
            {
                type.Kind   = "SCALAR";
                type.Name   = "String";
                type.OfType = null;
            }
            else if (clrType.GetTypeInfo().IsEnum)
            {
                type.Kind   = "ENUM";
                type.Name   = typeInfo.SchemaType.Name;
                type.OfType = null;
            }
            else
            {
                type.Kind   = typeInfo.SchemaType.IsScalar ? "SCALAR" : "OBJECT";
                type.OfType = null;
                if (type.Kind == "OBJECT" && isInput)
                {
                    type.Kind = "INPUT_OBJECT";
                    //== JT: !! INPUT_OBJECT names MUST use camelCase to avoid collision to OBJECT types !!
                    type.Name = SchemaGenerator.ToCamelCaseStartsLower(typeInfo.SchemaType.Name);
                }
                else
                {
                    type.Name = typeInfo.SchemaType.Name;
                }
                //==
            }
            if (typeInfo.TypeNotNullable)
            {
                return(new TypeElement
                {
                    Kind = "NON_NULL",
                    Name = null,
                    OfType = type
                });
            }

            return(type);
        }
        private static TypeElement BuildType(ISchemaProvider schema, GqlTypeInfo typeInfo, Type clrType, bool isInput = false)
        {
            // Is collection of objects?
            var type = new TypeElement();

            if (clrType.IsEnumerableOrArray())
            {
                type.Kind   = "LIST";
                type.Name   = null;
                type.OfType = BuildType(schema, typeInfo, clrType.GetEnumerableOrArrayType(), isInput);
            }
            else if (clrType.Name == "EntityQueryType`1")
            {
                type.Kind   = "SCALAR";
                type.Name   = "String";
                type.OfType = null;
            }
            else if (clrType.GetTypeInfo().IsEnum)
            {
                type.Kind   = "ENUM";
                type.Name   = typeInfo.SchemaType.Name;
                type.OfType = null;
            }
            else
            {
                type.Kind   = typeInfo.SchemaType.IsScalar ? "SCALAR" : "OBJECT";
                type.OfType = null;
                if (type.Kind == "OBJECT" && isInput)
                {
                    type.Kind = "INPUT_OBJECT";
                }
                type.Name = typeInfo.SchemaType.Name;
            }
            if (typeInfo.TypeNotNullable)
            {
                return(new TypeElement
                {
                    Kind = "NON_NULL",
                    Name = null,
                    OfType = type
                });
            }

            return(type);
        }
Пример #9
0
 /// <summary>
 /// Add any methods marked with GraphQLMutationAttribute in the given type to the schema. Names are added as lowerCaseCamel`
 /// </summary>
 /// <param name="mutationClassInstance"></param>
 /// <typeparam name="TType"></typeparam>
 public void AddMutationFrom <TType>(TType mutationClassInstance)
 {
     foreach (var method in mutationClassInstance.GetType().GetMethods())
     {
         if (method.GetCustomAttribute(typeof(GraphQLMutationAttribute)) is GraphQLMutationAttribute attribute)
         {
             var    isAsync          = method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null;
             string name             = SchemaFieldNamer(method.Name);
             var    claims           = method.GetCustomAttributes(typeof(GraphQLAuthorizeAttribute)).Cast <GraphQLAuthorizeAttribute>();
             var    requiredClaims   = new RequiredClaims(claims);
             var    actualReturnType = GetTypeFromMutationReturn(isAsync ? method.ReturnType.GetGenericArguments()[0] : method.ReturnType);
             var    typeName         = GetSchemaTypeNameForDotnetType(actualReturnType);
             var    returnType       = new GqlTypeInfo(() => GetReturnType(typeName), actualReturnType);
             var    mutationType     = new MutationType(this, name, returnType, mutationClassInstance, method, attribute.Description, requiredClaims, isAsync, SchemaFieldNamer);
             mutations[name] = mutationType;
         }
     }
 }
Пример #10
0
 public Field(ISchemaProvider schema, string name, LambdaExpression resolve, string description, object argTypes, GqlTypeInfo returnType, RequiredClaims claims) : this(name, resolve, description, returnType, claims)
 {
     ArgumentTypesObject = argTypes;
     allArguments        = argTypes.GetType().GetProperties().ToDictionary(p => p.Name, p => ArgType.FromProperty(schema, p));
     argTypes.GetType().GetFields().ToDictionary(p => p.Name, p => ArgType.FromField(schema, p)).ToList().ForEach(kvp => allArguments.Add(kvp.Key, kvp.Value));
 }