public void can_determine_whether_argument_exists_in_resolver()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<IntGraphType>()
                .Argument<StringGraphType, string>("arg1", "desc1", "12345")
                .Returns<int>()
                .Resolve(context =>
                {
                    context.HasArgument("arg1").ShouldEqual(true);
                    context.HasArgument("arg0").ShouldEqual(false);
                    return 0;
                });

            var field = objectType.Fields.First();
            field.Arguments.Count.ShouldEqual(1);

            field.Arguments[0].Name.ShouldEqual("arg1");
            field.Arguments[0].Description.ShouldEqual("desc1");
            field.Arguments[0].Type.ShouldEqual(typeof(StringGraphType));
            field.Arguments[0].DefaultValue.ShouldEqual("12345");
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>
                {
                    { "arg1", "abc" }
                }
            });
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ResolveFieldContext"/> class.
 /// </summary>
 /// <param name="fieldName">Name of the field.</param>
 /// <param name="fieldAst">The field ast.</param>
 /// <param name="fieldDefinition">The field definition.</param>
 /// <param name="returnType">Type of the return.</param>
 /// <param name="parentType">Type of the parent.</param>
 /// <param name="arguments">The arguments.</param>
 /// <param name="rootValue">The root value.</param>
 /// <param name="source">The source.</param>
 /// <param name="schema">The schema.</param>
 /// <param name="operation">The operation.</param>
 /// <param name="fragments">The fragments.</param>
 /// <param name="variables">The variables.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <param name="userContext">The user context.</param>
 public ResolveFieldContext(
     string fieldName,
     Field fieldAst,
     FieldType fieldDefinition,
     GraphType returnType,
     ObjectGraphType parentType,
     IReadOnlyDictionary<string, object> arguments,
     object rootValue,
     object source,
     ISchema schema,
     Operation operation,
     IEnumerable<IFragment> fragments,
     IEnumerable<Variable> variables,
     CancellationToken cancellationToken,
     object userContext)
 {
     FieldName = fieldName;
     FieldAst = fieldAst;
     FieldDefinition = fieldDefinition;
     ReturnType = returnType;
     ParentType = parentType;
     Arguments = arguments;
     RootValue = rootValue;
     Source = source;
     Schema = schema;
     Operation = operation;
     Fragments = fragments;
     Variables = variables;
     CancellationToken = cancellationToken;
     UserContext = userContext;
 }
 public virtual void AddPossibleType(ObjectGraphType type)
 {
     if (type != null && !_possibleTypes.Contains(type))
     {
         _possibleTypes.Add(type);
     }
 }
        public void throws_error_when_trying_to_register_field_of_incompatible_type()
        {
            var graphType = new ObjectGraphType();

            Should.Throw<ArgumentOutOfRangeException>(
                () => graphType.Field(typeof(string), "id")
            );
        }
        public void throws_error_when_trying_to_register_field_with_same_name()
        {
            var graphType = new ObjectGraphType();
            graphType.Field<StringGraphType>("id");

            Should.Throw<ArgumentOutOfRangeException>(
                () => graphType.Field<StringGraphType>("id")
            );
        }
        public void can_access_object()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType, int>()
                .Resolve(context =>
                {
                    context.Source.ShouldEqual(12345);
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Source = 12345
            });
        }
        public void can_access_object_with_custom_resolver()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .WithObject(obj => (int)obj + 1)
                .Resolve(context =>
                {
                    context.Object.ShouldEqual(12346);
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Source = 12345,
            });
        }
        public void can_be_defined_of_graphtype()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<IntGraphType>()
                .Name("Field1");
            objectType.Field<FloatGraphType>()
                .Name("Field2");
            objectType.Field<DateGraphType>()
                .Name("Field3");

            var fields = objectType.Fields.ToList();
            fields.Count.ShouldEqual(3);
            fields[0].Name.ShouldEqual("Field1");
            fields[0].Type.ShouldEqual(typeof(IntGraphType));
            fields[1].Name.ShouldEqual("Field2");
            fields[1].Type.ShouldEqual(typeof(FloatGraphType));
            fields[2].Name.ShouldEqual("Field3");
            fields[2].Type.ShouldEqual(typeof(DateGraphType));
        }
Example #9
0
        public DataGraphType(Builder builder, SchemaInfo schemaInfo)
        {
            Name = schemaInfo.DataType;

            foreach (var fieldInfo in schemaInfo.Fields)
            {
                if (fieldInfo.Field.RawProperties is ComponentFieldProperties ||
                    fieldInfo.Field.RawProperties is ComponentsFieldProperties)
                {
                    var fieldGraphType = new ObjectGraphType
                    {
                        Name = fieldInfo.LocalizedType
                    };

                    var partitioning = builder.ResolvePartition(((RootField)fieldInfo.Field).Partitioning);

                    foreach (var partitionKey in partitioning.AllKeys)
                    {
                        fieldGraphType.AddField(new FieldType
                        {
                            Name         = partitionKey.EscapePartition(),
                            Arguments    = ContentActions.Json.Arguments,
                            ResolvedType = AllTypes.Json,
                            Resolver     = FieldVisitor.JsonPath,
                            Description  = fieldInfo.Field.RawProperties.Hints
                        }).WithSourceName(partitionKey);
                    }

                    fieldGraphType.Description = $"The dynamic structure of the {fieldInfo.DisplayName} field of the {schemaInfo.DisplayName} content type.";

                    AddField(new FieldType
                    {
                        Name         = fieldInfo.FieldNameDynamic,
                        ResolvedType = fieldGraphType,
                        Resolver     = ContentResolvers.Field
                    }).WithSourceName(fieldInfo);
                }
                else
                {
                    var(resolvedType, resolver, args) = builder.GetGraphType(fieldInfo);

                    if (resolver != null)
                    {
                        var fieldGraphType = new ObjectGraphType
                        {
                            Name = fieldInfo.LocalizedType
                        };

                        var partitioning = builder.ResolvePartition(((RootField)fieldInfo.Field).Partitioning);

                        foreach (var partitionKey in partitioning.AllKeys)
                        {
                            fieldGraphType.AddField(new FieldType
                            {
                                Name         = partitionKey.EscapePartition(),
                                Arguments    = args,
                                ResolvedType = resolvedType,
                                Resolver     = resolver,
                                Description  = fieldInfo.Field.RawProperties.Hints
                            }).WithSourceName(partitionKey);
                        }

                        fieldGraphType.Description = $"The structure of the {fieldInfo.DisplayName} field of the {schemaInfo.DisplayName} content type.";

                        AddField(new FieldType
                        {
                            Name         = fieldInfo.FieldName,
                            ResolvedType = fieldGraphType,
                            Resolver     = ContentResolvers.Field
                        }).WithSourceName(fieldInfo);
                    }
                }
            }

            Description = $"The structure of the {schemaInfo.DisplayName} data type.";
        }
Example #10
0
        public ISchema Build()
        {
            var root = new ObjectGraphType
            {
                Name = "QueryRoot"
            };

            Dictionary <Type, ObjectGraphType> objectTypes = new Dictionary <Type, ObjectGraphType>();

            async Task <object> resolveField(IResolveFieldContext <object> context, Type type)
            {
                if (context != null && context.Source is IDictionary <string, object> dynamicObject)
                {
                    var name = context?.FieldAst?.Name;
                    if (name != null)
                    {
                        if (dynamicObject.TryGetValue(name, out var val))
                        {
                            return(await Task.FromResult(val));
                        }
                        else
                        {
                            throw new InvalidOperationException($"Expected to find property or method '{name}' on type '{GraphQLName(type.Name)}' but it does not exist.");
                        }
                    }
                }
                return(await NameFieldResolver.Instance.ResolveAsync(context));
            }

            foreach (var graphQLEntity in metadata.Values)
            {
                var entity = new ObjectGraphType();
                entity.Name = graphQLEntity.Entity.Type.Name;

                foreach (var prop in graphQLEntity.Entity.Included)
                {
                    entity.FieldAsync(
                        GraphQLType(prop.Value.Info.PropertyType),
                        GraphQLName(prop.Key),
                        resolve: (ctx) => resolveField(ctx, graphQLEntity.Entity.Type)
                        );
                }

                objectTypes.Add(graphQLEntity.Entity.Type, entity);
            }

            foreach (var graphQLEntity in metadata.Values)
            {
                var entity = objectTypes[graphQLEntity.Entity.Type];

                foreach (var relation in graphQLEntity.Entity.Relations)
                {
                    if (relation.Value.IsCollection)
                    {
                        entity.FieldAsync(
                            GraphQLName(relation.Key),
                            new ListGraphType(objectTypes[relation.Value.EntityRightType])
                            );
                    }
                    else
                    {
                        entity.FieldAsync(
                            GraphQLName(relation.Key),
                            objectTypes[relation.Value.EntityRightType]
                            );
                    }
                }

                root.FieldAsync(
                    PluralGraphQLName(entity.Name),
                    new ListGraphType(entity),
                    resolve: async context => await defaultResolver.GetAsync(context.FieldAst, graphQLEntity.Entity)
                    );
            }

            var schemaDynamic = new Schema
            {
                Query = root
            };

            return(schemaDynamic);
        }
Example #11
0
 /// <summary>
 /// Вызывается для инициализации схемы для мутаций GraphQL.
 /// </summary>
 /// <param name="schema">Объект инициализируемой схемы.</param>
 public override void InitializeMutation(ObjectGraphType <object> schema)
 {
 }
        public void should_have_deprecation_reason()
        {
            var objectType = new ObjectGraphType();

            objectType.Field<StringGraphType>()
                .DeprecationReason("Old field");

            objectType.Fields
                .First().DeprecationReason.ShouldEqual("Old field");
        }
        public void should_have_name_and_description()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Name("TheName")
                .Description("TheDescription");

            var fields = objectType.Fields.ToList();
            fields.Count.ShouldEqual(1);
            fields[0].Name.ShouldEqual("TheName");
            fields[0].Description.ShouldEqual("TheDescription");
            fields[0].Type.ShouldEqual(typeof(StringGraphType));
        }
        public void build_dynamic_schema()
        {
            var schema = new Schema();

            var person = new ObjectGraphType();
            person.Name = "Person";
            person.Field("name", new StringGraphType());
            person.Field(
                "friends",
                new ListGraphType(new NonNullGraphType(person)),
                resolve: ctx => new[] {new SomeObject {Name = "Jaime"}, new SomeObject {Name = "Joe"}});

            var root = new ObjectGraphType();
            root.Name = "Root";
            root.Field("hero", person, resolve: ctx => ctx.RootValue);

            schema.Query = root;
            schema.RegisterTypes(person);

            var printed = new SchemaPrinter(schema).Print();

            #if DEBUG
            Console.WriteLine(printed);
            #endif

            AssertQuerySuccess(
                schema,
                @"{ hero { name friends { name } } }",
                @"{ hero: { name : 'Quinn', friends: [ { name: 'Jaime' }, { name: 'Joe' }] } }",
                root: new SomeObject { Name = "Quinn"});
        }
Example #15
0
 public ObjectTypeInterfaceRemoved(Type interfaceType, ObjectGraphType objectType) : base(Criticality.Breaking)
 {
     this.interfaceType = interfaceType;
     this.objectType    = objectType;
 }
Example #16
0
        public void prints_unions()
        {
            var root = new ObjectGraphType {
                Name = "Query"
            };

            root.Field <SingleUnion>("single");
            root.Field <MultipleUnion>("multiple");

            var schema = new Schema {
                Query = root
            };

            AssertEqual(print(schema), "", @"
type Bar implements IFoo {
  # This is of type String
  str: String
}

scalar BigInt

scalar Byte

# The `Date` scalar type represents a year, month and day in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar Date

# The `DateTime` scalar type represents a date and time. `DateTime` expects
# timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTime

# The `DateTimeOffset` scalar type represents a date, time and offset from UTC.
# `DateTimeOffset` expects timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTimeOffset

scalar Decimal

# This is a Foo object type
type Foo {
  # This is of type String
  str: String
  # This is of type Integer
  int: Int
}

scalar Guid

# This is a Foo interface type
interface IFoo {
  # This is of type String
  str: String
}

scalar Long

# The `Milliseconds` scalar type represents a period of time represented as the total number of milliseconds.
scalar Milliseconds

union MultipleUnion = Foo | Bar

type Query {
  single: SingleUnion
  multiple: MultipleUnion
}

scalar SByte

# The `Seconds` scalar type represents a period of time represented as the total number of seconds.
scalar Seconds

scalar Short

union SingleUnion = Foo

scalar UInt

scalar ULong

scalar UShort

scalar Uri
", excludeScalars: true);
        }
 public EmptyQuerySchema()
 {
     Query = new ObjectGraphType {
         Name = "Empty"
     };
 }
Example #18
0
        public void SetupMutationDefinitions(ObjectGraphType type)
        {
            type.FieldAsync <AnyTimerType>(
                "newAnyTimer",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <NewAnyTimerInputType> > {
                Name = SchemaConstants.Args
            }
                    ),
                resolve: async context =>
            {
                var args = context.GetArgument <NewAnyTimerInputType>(SchemaConstants.Args);
                if (args.Senders.Count == 0)
                {
                    return((AnyTimer)context.Error(GraphQLErrors.NoSenders));
                }

                var user = await context.UserRecord();
                if (string.Equals(user.Uid, args.Receiver))
                {
                    return(context.Error(GraphQLErrors.ReceiverSameAsSender));
                }
                var anytimer = new AnyTimer
                {
                    Id          = Guid.NewGuid().ToString(),
                    CreatorId   = user.Uid,
                    CreatedTime = DateTime.Now,
                    LastUpdated = DateTime.Now,
                    Status      = AnyTimerStatus.Requested,
                    Reason      = args.Reason,
                };
                var receiver = await context.UserRecord(args.Receiver);
                if (receiver == null)
                {
                    return((AnyTimer)context.Error(GraphQLErrors.UnknownUser(args.Receiver)));
                }
                if ((await _friendRepository.ByUsers(user.Uid, receiver.Uid))?.Status !=
                    FriendRequestStatus.Accepted)
                {
                    return((AnyTimer)context.Error(GraphQLErrors.NotFriends(receiver.Uid)));
                }
                anytimer.ReceiverId = receiver.Uid;

                await ResolveSenders(args, anytimer, context);

                if (context.Errors.Count > 0)
                {
                    return(null);
                }

                UpdateStatus(anytimer, AnyTimerStatus.Requested);

                await _repository.Add(anytimer);
                // TODO Send push notifications

                return(anytimer);
            }
                ).RequiresAuthentication();

            type.FieldAsync <AnyTimerType>(
                "editAnyTimer",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = SchemaConstants.Id
            },
                    new QueryArgument <AnyTimerInputType> {
                Name = SchemaConstants.Args
            }
                    ),
                resolve: async context =>
            {
                var args = context.GetArgument <AnyTimerInputType>(SchemaConstants.Args);
                if (args.Senders.Count == 0)
                {
                    return((AnyTimer)context.Error(GraphQLErrors.NoSenders));
                }

                var anytimer = await _repository.ById(context.GetArgument <string>(SchemaConstants.Id));
                if (anytimer == null)
                {
                    return(context.Error(GraphQLErrors.UnknownAnyTimer));
                }
                var user = await context.UserRecord();
                if (!anytimer.CreatorId.Equals(user.Uid))
                {
                    return(context.Error(GraphQLErrors.NotCreator));
                }
                if (anytimer.Status == AnyTimerStatus.Cancelled || anytimer.Status == AnyTimerStatus.Accepted)
                {
                    return(context.Error(GraphQLErrors.NotEditable));
                }

                anytimer.Reason = args.Reason;
                UpdateStatus(anytimer, AnyTimerStatus.Edited);

                await ResolveSenders(args, anytimer, context);

                if (context.Errors.Count > 0)
                {
                    return(null);
                }

                await _repository.Update(anytimer);

                return(anytimer);
            }
                ).RequiresAuthentication();
        }
        /// <summary>
        /// Adds all fields to a graph type by iterating through the model type properties.
        /// </summary>
        /// <typeparam name="T">The model type.</typeparam>
        /// <param name="type"></param>
        /// <param name="handleIdProperty">If set to true, the Id property is added as field. Default is false.</param>
        public static void AddFieldsFromType <T>(this ObjectGraphType <object> type, bool handleIdProperty = false)
        {
            var properties = typeof(T).GetExactProperies();

            foreach (var property in properties)
            {
                var typeName     = property.PropertyType.Name;
                var propertyName = property.Name.ToFirstLower();

                // handle Id
                if (propertyName == "id")
                {
                    // skip property named "id" if desired. May be skipped because it is handled already in NodeType.
                    if (!handleIdProperty)
                    {
                        continue;
                    }

                    type.AddIdField();
                    continue;
                }

                // convert all foreign key id fields to be global unique
                if (propertyName.EndsWith("Id"))
                {
                    type.Field <IdGraphType>(propertyName, null, null, context =>
                    {
                        var node = context.Source;
                        return(GlobalId.ToGlobalId(property.Name.Remove(propertyName.Length - 2), property.GetValue(node).ToString()));
                    });
                    continue;
                }

                // create primitive fields like ints, strings, floats etc.
                if (property.PropertyType.IsSimpleType())
                {
                    type.CreateFieldFromPrimitiveProperty(property);
                    continue;
                }

                // generate connection field for collection / list
                if (property.PropertyType.GetInterface("ICollection") != null && property.PropertyType.IsGenericType())
                {
                    // create an ObjectType<itemType>
                    var itemType    = property.PropertyType.GenericTypeArguments[0];
                    var graphQLType = typeof(NodeObjectType <>).MakeGenericType(itemType);
                    graphQLType = graphQLType.ConvertToVirtualType();

                    // construct resolver
                    Func <ResolveFieldContext <object>, object> resolver = (context) => {
                        // get the collection / list items
                        // TODO: crazy thoughts: what if this property was not loaded yet?
                        // If, for example, a list of users is loaded by a repository, the roles
                        // of each user may not have been loaded.
                        // Could it be possibe to somehow get and call a repository here and perform
                        // something like lazy loading?
                        // Further: if a collection of object is loaded, could it be easily possible to
                        // perform batch loading and have some temporaly cache for this requests?
                        var items = context.Source.GetProperyValue(propertyName);

                        // constuct a type like Connection<Order, TId>
                        var connectionType = typeof(Connection <,>);
                        var idType         = itemType.GetIdType();
                        connectionType = connectionType.MakeGenericType(new[] { itemType, idType });

                        // call like new Connection<Order, TId>(items)
                        var connection = Activator.CreateInstance(connectionType, items);
                        return(connection);
                    };

                    type.AddConnectionField(itemType, resolver, propertyName, null);

                    continue;
                }

                // create complex property fields
                var complexType = typeof(NodeObjectType <>).MakeGenericType(property.PropertyType).ConvertToVirtualType();
                type.Field(complexType, propertyName);
            }
        }
Example #20
0
 public QueryBuilder <TSource> Create <TSource>(ObjectGraphType <object> objectGraphType, string queryName, string description = null)
 {
     return(new QueryBuilder <TSource>(objectGraphType, queryName, description, _graphQlRepository, _distributedCache, _logger, _connectionEdgeHandler));
 }
Example #21
0
        public static IEnumerable <IGraphType> CreateGraphTypes(
            IEnumerable <IContentTypeComposition> contentTypes,
            PublishedItemType publishedItemType,
            Func <IContentTypeBase, string> resolveName = null)
        {
            if (resolveName == null)
            {
                resolveName = Conventions.NameResolvers.PascalCase;
            }

            var interfaceGraphTypes = new Dictionary <string, IInterfaceGraphType>();

            //TODO: Whitelist/blacklist content types

            var contentTypeList = contentTypes.ToList();
            var compositions    = contentTypeList.SelectMany(x => x.ContentTypeComposition).Distinct().ToList();

            foreach (var contentType in compositions)
            {
                var graphType = new InterfaceGraphType <IPublishedContent>
                {
                    Name        = resolveName(contentType),
                    Description = contentType.Description,
                    Metadata    =
                    {
                        ["documentTypeAlias"] = contentType.Alias,
                    }
                };

                graphType.AddUmbracoContentPropeties(contentType, publishedItemType);

                yield return(graphType);

                interfaceGraphTypes.Add(contentType.Alias, graphType);
            }

            foreach (var contentType in contentTypeList.Except(compositions))
            {
                var graphType = new ObjectGraphType <IPublishedContent>
                {
                    Name        = resolveName(contentType),
                    Description = contentType.Description,
                    IsTypeOf    = content => ((IPublishedContent)content).DocumentTypeAlias == contentType.Alias,
                    Metadata    =
                    {
                        ["documentTypeAlias"] = contentType.Alias,
                        ["allowedAtRoot"]     = contentType.AllowedAsRoot,
                        ["allowedChildren"]   = contentType.AllowedContentTypes.Select(x => x.Alias).ToArray(),
                    }
                };

                graphType.Interface <PublishedContentGraphType>();
                foreach (var composition in contentType.ContentTypeComposition)
                {
                    if (interfaceGraphTypes.TryGetValue(composition.Alias, out IInterfaceGraphType interfaceType))
                    {
                        graphType.AddResolvedInterface(interfaceType);
                    }
                }

                graphType.AddUmbracoBuiltInProperties();
                graphType.AddUmbracoContentPropeties(contentType, publishedItemType);

                yield return(graphType);
            }
        }
Example #22
0
        protected virtual IObjectGraphType ToObjectGraphType(GraphQLObjectTypeDefinition astType, bool isExtensionType = false)
        {
            var name       = (string)astType.Name.Value;
            var typeConfig = Types.For(name);

            AssertKnownType(typeConfig);

            ObjectGraphType type;

            if (!_types.ContainsKey(name))
            {
                type = new ObjectGraphType {
                    Name = name
                };
            }
            else
            {
                type = _types[name] as ObjectGraphType ?? throw new InvalidOperationException($"Type '{name} should be ObjectGraphType");
            }

            if (!isExtensionType)
            {
                type.Description = typeConfig.Description ?? astType.Comment?.Text.ToString();
                type.IsTypeOf    = typeConfig.IsTypeOfFunc;
            }

            typeConfig.CopyMetadataTo(type);

            Func <string, GraphQLFieldDefinition, FieldType> constructFieldType;

            if (IsSubscriptionType(type))
            {
                constructFieldType = ToSubscriptionFieldType;
            }
            else
            {
                constructFieldType = ToFieldType;
            }

            if (astType.Fields != null)
            {
                foreach (var f in astType.Fields)
                {
                    type.AddField(constructFieldType(type.Name, f));
                }
            }

            if (astType.Interfaces != null)
            {
                foreach (var i in astType.Interfaces)
                {
                    type.AddResolvedInterface(new GraphQLTypeReference((string)i.Name.Value));
                }
            }

            if (isExtensionType)
            {
                type.AddExtensionAstType(astType);
            }
            else
            {
                type.SetAstType(astType);
                OverrideDeprecationReason(type, typeConfig.DeprecationReason);
            }

            return(type);
        }
Example #23
0
        public object ResolveField(ExecutionContext context, ObjectGraphType parentType, object source, Fields fields)
        {
            var field = fields.First();

            var fieldDefinition = GetFieldDefinition(context.Schema, parentType, field);
            if (fieldDefinition == null)
            {
                return null;
            }

            var arguments = GetArgumentValues(fieldDefinition.Arguments, field.Arguments, context.Variables);

            Func<ResolveFieldContext, object> defaultResolve = (ctx) =>
            {
                return ctx.Source != null ? GetProperyValue(ctx.Source, ctx.FieldAst.Name) : null;
            };

            try
            {
                var resolveContext = new ResolveFieldContext();
                resolveContext.FieldAst = field;
                resolveContext.FieldDefinition = fieldDefinition;
                resolveContext.Schema = context.Schema;
                resolveContext.ParentType = parentType;
                resolveContext.Arguments = arguments;
                resolveContext.Source = source;
                var resolve = fieldDefinition.Resolve ?? defaultResolve;
                var result = resolve(resolveContext);
                return CompleteValue(context, fieldDefinition.Type, fields, result);
            }
            catch (Exception exc)
            {
                context.Errors.Add(new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc));
                return null;
            }
        }
Example #24
0
 public FieldRemoved(ObjectGraphType objectType, IFieldType field) : base(Criticality.Breaking)
 {
     this.field      = field;
     this.objectType = objectType;
 }
Example #25
0
        private FieldType BuildSchemaBasedFieldType(LuceneQuery query, JToken schema)
        {
            var typetype = new ObjectGraphType <JObject>
            {
                Name = query.Name
            };

            var properties = schema["Properties"];

            foreach (var child in properties.Children())
            {
                var name      = ((JProperty)child).Name;
                var nameLower = name.Replace('.', '_');
                var type      = child["type"].ToString();

                if (type == "String")
                {
                    var field = typetype.Field(
                        typeof(StringGraphType),
                        nameLower,
                        resolve: context =>
                    {
                        var source = context.Source;
                        return(source[context.FieldDefinition.Metadata["Name"].ToString()].ToObject <string>());
                    });
                    field.Metadata.Add("Name", name);
                }
                if (type == "Integer")
                {
                    var field = typetype.Field(
                        typeof(IntGraphType),
                        nameLower,
                        resolve: context =>
                    {
                        var source = context.Source;
                        return(source[context.FieldDefinition.Metadata["Name"].ToString()].ToObject <int>());
                    });
                    field.Metadata.Add("Name", name);
                }
            }

            var fieldType = new FieldType
            {
                Arguments = new QueryArguments(
                    new QueryArgument <StringGraphType> {
                    Name = "parameters"
                }
                    ),

                Name         = query.Name,
                ResolvedType = new ListGraphType(typetype),
                Resolver     = new LockedAsyncFieldResolver <object, object>(async context =>
                {
                    var queryManager = context.ResolveServiceProvider().GetService <IQueryManager>();
                    var iquery       = await queryManager.GetQueryAsync(context.FieldName);

                    var parameters = context.GetArgument <string>("parameters");

                    var queryParameters = parameters != null ?
                                          JsonConvert.DeserializeObject <Dictionary <string, object> >(parameters)
                        : new Dictionary <string, object>();

                    var result = await queryManager.ExecuteQueryAsync(iquery, queryParameters);
                    return(result.Items);
                }),
                Type = typeof(ListGraphType <ObjectGraphType <JObject> >)
            };

            return(fieldType);
        }
Example #26
0
 public DummySchema()
 {
     Query = new ObjectGraphType();
 }
        private void AddRootEntityFields(ISchema schema)
        {
            var query = schema.Query;

            if (query == null)
            {
                schema.Query = query = new ObjectGraphType {
                    Name = "Query"
                };
            }

            query.Field("_service", new NonNullGraphType(new GraphQLTypeReference("_Service")), resolve: context => new {});

            var representationsType = new NonNullGraphType(new ListGraphType(new NonNullGraphType(new GraphQLTypeReference("_Any"))));

            query.FieldAsync(
                "_entities",
                new NonNullGraphType(new ListGraphType(new GraphQLTypeReference("_Entity"))),
                arguments: new QueryArguments(new QueryArgument(representationsType)
            {
                Name = "representations"
            }),
                resolve: async context =>
            {
                AddTypeNameToSelection(context.FieldAst, context.Document);

                var reps = context.GetArgument <List <Dictionary <string, object> > >("representations");

                var results = new List <object>();

                foreach (var rep in reps)
                {
                    var typeName = rep["__typename"].ToString();
                    var type     = context.Schema.FindType(typeName);
                    if (type != null)
                    {
                        // execute resolver
                        var resolver = type.GetMetadata <IFederatedResolver>(ResolverMetadataField);
                        if (resolver != null)
                        {
                            var resolveContext = new FederatedResolveContext
                            {
                                Arguments          = rep,
                                ParentFieldContext = context
                            };
                            var result = await resolver.Resolve(resolveContext).ConfigureAwait(false);
                            results.Add(result);
                        }
                        else
                        {
                            results.Add(rep);
                        }
                    }
                    else
                    {
                        // otherwise return the representation
                        results.Add(rep);
                    }
                }

                return(results);
            });
        }
    public async Task VerifyCorrectExecutionOrder()
    {
        var sb = new StringBuilder();
        Func <IResolveFieldContext, object> resolver = context =>
        {
            sb.AppendLine(string.Join(".", context.ResponsePath));
            return("test");
        };
        var leaderGraphType = new ObjectGraphType()
        {
            Name = "LoaderType"
        };

        leaderGraphType.Field <StringGraphType>("lastName", resolve: resolver);
        leaderGraphType.Field <StringGraphType>("name", resolve: resolver);
        var familiesGraphType = new ObjectGraphType()
        {
            Name = "FamiliesType"
        };

        familiesGraphType.Field("leader", leaderGraphType, resolve: resolver);
        familiesGraphType.Field("leader_dataLoader", leaderGraphType, resolve: context =>
        {
            resolver(context);
            return(new SimpleDataLoader <object>(ctx =>
            {
                sb.AppendLine(string.Join(".", context.ResponsePath) + "-completed");
                return Task.FromResult <object>("test");
            }));
        });
        var queryGraphType = new ObjectGraphType();

        queryGraphType.Field("families", new ListGraphType(familiesGraphType), resolve: context =>
        {
            resolver(context);
            return(new object[] { "a", "a", "a" });
        });
        var schema = new Schema
        {
            Query    = queryGraphType,
            Mutation = queryGraphType,
        };
        var documentExecuter = new DocumentExecuter();
        var executionOptions = new ExecutionOptions()
        {
            Schema = schema,
            Query  = "mutation { families { leader_dataLoader { lastName name } leader { lastName name } } }",
        };
        await documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);

        sb.ToString().ShouldBeCrossPlat(@"families
families.0.leader_dataLoader
families.0.leader
families.0.leader.lastName
families.0.leader.name
families.1.leader_dataLoader
families.1.leader
families.1.leader.lastName
families.1.leader.name
families.2.leader_dataLoader
families.2.leader
families.2.leader.lastName
families.2.leader.name
families.0.leader_dataLoader-completed
families.1.leader_dataLoader-completed
families.2.leader_dataLoader-completed
families.0.leader_dataLoader.lastName
families.0.leader_dataLoader.name
families.1.leader_dataLoader.lastName
families.1.leader_dataLoader.name
families.2.leader_dataLoader.lastName
families.2.leader_dataLoader.name
");
    }
 public virtual void VisitObjectGraphType(ObjectGraphType type)
 {
 }
 private async Task<IReadOnlyDictionary<string, object>> ExecuteFields( ExecutionContext context, ObjectGraphType rootType, object source, Dictionary<string, IEnumerable<Field>> fields, List<ExecutionError> executionErrors )
 {
     return await fields.ToDictionaryAsync(
         pair => pair.Key,
         pair => ResolveField( context, rootType, source, pair.Value, executionErrors ) );
 }
        public void getting_unspecified_argument_in_resolver_yields_overridden_default_value()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Argument<StringGraphType, string>("arg1", "desc1", "default")
                .Resolve(context =>
                {
                    context.GetArgument("arg1", "default2").ShouldEqual("default2");
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>(),
                FieldDefinition = field
            });
        }
        private async Task<object> ResolveField( ExecutionContext context, ObjectGraphType parentType, object source, IEnumerable<Field> fields, List<ExecutionError> executionErrors )
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            IReadOnlyList<Field> fieldsAsReadOnlyList = fields.ToReadOnlyList();

            Field field = fieldsAsReadOnlyList.First();

            FieldType fieldDefinition = GetFieldDefinition(context.Schema, parentType, field);
            if (fieldDefinition == null)
            {
                return null;
            }

            IReadOnlyDictionary<string, object> arguments = GetArgumentValues(context.Schema, fieldDefinition.Arguments, field.Arguments, context.Variables);

            Func<ResolveFieldContext, object> defaultResolve =
                ctx =>
                {
                    return ctx.Source != null ? GetProperyValue(ctx.Source, ctx.FieldAst.Name) : null;
                };

            try
            {
                ResolveFieldContext resolveContext = new ResolveFieldContext(
                    field.Name,
                    field,
                    fieldDefinition,
                    context.Schema.FindType( fieldDefinition.Type ),
                    parentType,
                    arguments,
                    context.RootValue,
                    source,
                    context.Schema,
                    context.Operation,
                    context.Fragments,
                    context.Variables,
                    context.CancellationToken,
                    context.UserContext );

                Func<ResolveFieldContext, object> resolve = fieldDefinition.Resolve ?? defaultResolve;
                object result = resolve( resolveContext );

                Task resultAsTask = result as Task;
                if( resultAsTask != null )
                {
                    await resultAsTask;
                    result = GetProperyValue( resultAsTask, "Result" );
                }

                if ( fieldDefinition.IsPluralIdentifyingRootField )
                {
                    ThrowIfPluralIdentifyingRootFieldRequirementsNotMet(
                        result,
                        resolveContext );
                }
                
                __Field parentTypeAsField = parentType as __Field;
                Type resultAsType = result as Type;
                if ( parentTypeAsField != null &&
                     resultAsType != null )
                {
                    result = context.Schema.FindType( resultAsType );
                }

                return await CompleteValue(
                    context,
                    context.Schema.FindType( fieldDefinition.Type ),
                    fieldsAsReadOnlyList,
                    result,
                    executionErrors );
            }
            catch( Exception exception )
            {
                executionErrors.Add(
                    new ExecutionError( string.Format( "Error trying to resolve {0}.", field.Name ), exception ) );

                return null;
            }
        }
        public void can_register_field_of_compatible_type()
        {
            var graphType = new ObjectGraphType();

            graphType.Field(typeof(BooleanGraphType), "isValid").Type.ShouldEqual(typeof(BooleanGraphType));
        }
Example #34
0
        protected virtual IObjectGraphType ToObjectGraphType(GraphQLObjectTypeDefinition astType, bool isExtensionType = false)
        {
            var typeConfig = Types.For(astType.Name.Value);

            ObjectGraphType type;

            if (!_types.ContainsKey(astType.Name.Value))
            {
                type = new ObjectGraphType {
                    Name = astType.Name.Value
                };
            }
            else
            {
                type = _types[astType.Name.Value] as ObjectGraphType ?? throw new InvalidOperationException($"Type '{astType.Name.Value} should be ObjectGraphType");
            }

            if (!isExtensionType)
            {
                type.Description = typeConfig.Description ?? astType.Comment?.Text;
                type.IsTypeOf    = typeConfig.IsTypeOfFunc;
            }

            CopyMetadata(type, typeConfig);

            Func <string, GraphQLFieldDefinition, FieldType> constructFieldType;

            if (IsSubscriptionType(type))
            {
                constructFieldType = ToSubscriptionFieldType;
            }
            else
            {
                constructFieldType = ToFieldType;
            }

            if (astType.Fields != null)
            {
                var fields = astType.Fields.Select(f => constructFieldType(type.Name, f));
                fields.Apply(f => type.AddField(f));
            }

            if (astType.Interfaces != null)
            {
                astType.Interfaces
                .Select(i => new GraphQLTypeReference(i.Name.Value))
                .Apply(type.AddResolvedInterface);
            }

            if (isExtensionType)
            {
                type.AddExtensionAstType(astType);
            }
            else
            {
                type.SetAstType(astType);
            }

            VisitNode(type, v => v.VisitObject(type));

            return(type);
        }
        public void should_return_the_right_type()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Name("TheName")
                .Returns<string>()
                .Resolve(_ => "SomeString");

            var fields = objectType.Fields.ToList();
            fields.Count.ShouldEqual(1);
            fields[0].Name.ShouldEqual("TheName");
            fields[0].Type.ShouldEqual(typeof(StringGraphType));

            var context = new ResolveFieldContext();
            fields[0].Resolve(context).GetType().ShouldEqual(typeof(string));
            fields[0].Resolve(context).ShouldEqual("SomeString");
        }
 public void can_register_field_of_compatible_type()
 {
     var graphType = new ObjectGraphType();
     graphType.Field(typeof(BooleanGraphType), "isValid").Type.ShouldBe(typeof(BooleanGraphType));
 }
        public void can_get_enum_argument()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Argument<EpisodeEnum, Episodes>("episode", "episodes")
                .Resolve(context =>
                {
                    context.GetArgument<Episodes>("episode").ShouldEqual(Episodes.JEDI);
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>
                {
                    {"episode", "JEDI" }
                },
                FieldDefinition = field
            });
        }
 public void can_implement_interfaces_in_derived_generic()
 {
     var type = new ObjectGraphType<TestPoco>();
     type.Interface(typeof(TestInterface));
     type.Interfaces.Count().ShouldBe(1);
 }
Example #39
0
        public async Task can_define_simple_connection_with__custom_edge_and_connection_types()
        {
            var type       = new ObjectGraphType();
            var connection = new ParentChildrenConnection
            {
                TotalCount = 1,
                PageInfo   = new PageInfo
                {
                    HasNextPage     = true,
                    HasPreviousPage = false,
                    StartCursor     = "01",
                    EndCursor       = "01",
                },
                Edges = new List <ParentChildrenEdge>
                {
                    new ParentChildrenEdge
                    {
                        Cursor = "01",
                        Node   = new Child
                        {
                            Field1 = "abcd",
                            Field2 = 1
                        },
                        FriendedAt = FriendedAt
                    },
                    new ParentChildrenEdge
                    {
                        Cursor = "01",
                        Node   = new Child
                        {
                            Field1 = "abcd",
                            Field2 = 10
                        },
                        FriendedAt = FriendedAt
                    },
                    new ParentChildrenEdge
                    {
                        Cursor = "01",
                        Node   = new Child
                        {
                            Field1 = "abcd",
                            Field2 = 7
                        },
                        FriendedAt = FriendedAt
                    },
                },
                ConnectionField1 = ConnectionField1Value
            };

            type.Connection <ChildType, ParentChildrenEdgeType, ParentChildrenConnectionType>()
            .Name("testConnection")
            .ResolveAsync(resArgs => Task.FromResult <object>(connection));

            var field = type.Fields.Single();

            field.Name.ShouldBe("testConnection");
            field.Type.ShouldBe(typeof(ParentChildrenConnectionType));

            var boxedResult = await(Task <object>) field.Resolver.Resolve(new ResolveFieldContext());
            var result      = boxedResult as ParentChildrenConnection;

            result.ShouldNotBeNull();
            if (result != null)
            {
                result.TotalCount.ShouldBe(1);
                result.PageInfo.HasNextPage.ShouldBe(true);
                result.PageInfo.HasPreviousPage.ShouldBe(false);
                result.PageInfo.StartCursor.ShouldBe("01");
                result.PageInfo.EndCursor.ShouldBe("01");
                result.Edges.Count.ShouldBe(3);
                result.Edges.First().Cursor.ShouldBe("01");
                result.Edges.First().Node.Field1.ShouldBe("abcd");
                result.Items.Count.ShouldBe(3);
                result.Items.First().Field1.ShouldBe("abcd");
                result.Edges.ShouldAllBe(c => c.FriendedAt == FriendedAt);
                result.HighestField2.ShouldBe(10);
                result.ConnectionField1.ShouldBe(ConnectionField1Value);
            }
        }
 public void can_implement_interfaces()
 {
     var type = new ObjectGraphType();
     type.Interface(typeof(TestInterface));
     type.Interfaces.Count().ShouldBe(1);
 }
Example #41
0
        public void prints_multiple_interfaces_with_field_descriptions()
        {
            var root = new ObjectGraphType {
                Name = "Query"
            };

            root.Field <BarMultipleType>("bar");

            var schema = new Schema {
                Query = root
            };

            var options = new SchemaPrinterOptions
            {
                IncludeDescriptions = true
            };

            var result = print(schema, options);

            AssertEqual(result, "", @"
interface Baaz {
  # This is of type Integer
  int: Int
}

type Bar implements IFoo & Baaz {
  # This is of type String
  str: String
  # This is of type Integer
  int: Int
}

scalar BigInt

scalar Byte

# The `Date` scalar type represents a year, month and day in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar Date

# The `DateTime` scalar type represents a date and time. `DateTime` expects
# timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTime

# The `DateTimeOffset` scalar type represents a date, time and offset from UTC.
# `DateTimeOffset` expects timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTimeOffset

scalar Decimal

scalar Guid

# This is a Foo interface type
interface IFoo {
  # This is of type String
  str: String
}

scalar Long

# The `Milliseconds` scalar type represents a period of time represented as the total number of milliseconds.
scalar Milliseconds

type Query {
  bar: Bar
}

scalar SByte

# The `Seconds` scalar type represents a period of time represented as the total number of seconds.
scalar Seconds

scalar Short

scalar UInt

scalar ULong

scalar UShort

scalar Uri
", excludeScalars: true);
        }
        public void can_get_enum_argument_with_overriden_default_value()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Argument<EpisodeEnum, Episodes>("episode", "episodes")
                .Resolve(context =>
                {
                    context.GetArgument("episode", Episodes.EMPIRE).ShouldEqual(Episodes.EMPIRE);
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>(),
                FieldDefinition = field
            });
        }
        public void prints_builtin_scalars()
        {
            var root = new ObjectGraphType {
                Name = "Query"
            };

            root.Field <BigIntGraphType>("bigint");
            root.Field <ByteGraphType>("byte");
            root.Field <DateGraphType>("date");
            root.Field <DateTimeGraphType>("datetime");
            root.Field <DateTimeOffsetGraphType>("datetimeoffset");
            root.Field <DecimalGraphType>("decimal");
            root.Field <GuidGraphType>("guid");
            root.Field <LongGraphType>("long");
            root.Field <TimeSpanMillisecondsGraphType>("milliseconds");
            root.Field <SByteGraphType>("sbyte");
            root.Field <TimeSpanSecondsGraphType>("seconds");
            root.Field <ShortGraphType>("short");
            root.Field <UIntGraphType>("uint");
            root.Field <ULongGraphType>("ulong");
            root.Field <UShortGraphType>("ushort");
            root.Field <UriGraphType>("uri");

            var schema = new Schema {
                Query = root
            };

            var expected = new Dictionary <string, string>
            {
                {
                    "Query",
                    @"scalar BigInt

scalar Byte

# The `Date` scalar type represents a year, month and day in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar Date

# The `DateTime` scalar type represents a date and time. `DateTime` expects
# timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTime

# The `DateTimeOffset` scalar type represents a date, time and offset from UTC.
# `DateTimeOffset` expects timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTimeOffset

scalar Decimal

scalar Guid

scalar Long

# The `Milliseconds` scalar type represents a period of time represented as the
# total number of milliseconds in range [-922337203685477, 922337203685477].
scalar Milliseconds

type Query {
  bigint: BigInt
  byte: Byte
  date: Date
  datetime: DateTime
  datetimeoffset: DateTimeOffset
  decimal: Decimal
  guid: Guid
  long: Long
  milliseconds: Milliseconds
  sbyte: SByte
  seconds: Seconds
  short: Short
  uint: UInt
  ulong: ULong
  ushort: UShort
  uri: Uri
}

scalar SByte

# The `Seconds` scalar type represents a period of time represented as the total
# number of seconds in range [-922337203685, 922337203685].
scalar Seconds

scalar Short

scalar UInt

scalar ULong

scalar UShort

scalar Uri"
                },
            };

            AssertEqual(print(schema), expected);
        }
        public void can_get_list_argument()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Argument<NonNullGraphType<ListGraphType<NonNullGraphType<StringGraphType>>>>("episodes", "episodes")
                .Resolve(context =>
                {
                    context.GetArgument<IEnumerable<string>>("episodes").ShouldEqual(new List<string> { "JEDI", "EMPIRE" });
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>
                {
                    {"episodes", new object[] {"JEDI", "EMPIRE" } }
                },
                FieldDefinition = field
            });
        }
        /// <summary>
        /// Register Managers
        /// </summary>
        /// <param name="services"></param>
        /// <param name="query"></param>
        private static void RegisterManagers(IServiceCollection services, ObjectGraphType query, ObjectGraphType mutation)
        {
            Type[] managerTypes = null;
            try
            {
                managerTypes = Assembly.Load("ProfileLocation.Managers").GetTypes();
            }
            catch (Exception ex)
            {
                _logger.Warn(ex, $"Cannot load managers dll");
                return;
            }

            XElement[] xmlMemberComments   = null;
            var        managersXmlLocation = Path.ChangeExtension(Assembly.Load("ProfileLocation.Managers").Location, ".xml");

            if (File.Exists(managersXmlLocation))
            {
                xmlMemberComments = XDocument.Load(managersXmlLocation).Root.Element("members").Elements().ToArray();
            }


            //Reflect on all Managers
            foreach (var managerType in managerTypes.Where(w => w.IsClass && w.Name.EndsWith("Manager")))
            {
                if (managerType.GetCustomAttribute <QLIgnoreAttribute>() != null)
                {
                    _logger.Info($"Manager: {managerType.Name} is ignored due to QLIgnore Attribute");
                    continue;
                }

                var managerObsoleteAtt = (ObsoleteAttribute)managerType.GetCustomAttribute(typeof(ObsoleteAttribute));
                var deprecationReason  = managerObsoleteAtt != null ? managerObsoleteAtt.Message ?? "Marked Obsolete" : null;

                //Add type to DI
                services.AddTransient(managerType);

                //Reflect on each method exposed and add as a field to QL Context
                foreach (var method in managerType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                {
                    //If method returns void then ignore as not supported
                    if (method.ReturnType == typeof(void) || method.ReturnType == typeof(Task))
                    {
                        _logger.Warn($"Manager {managerType.Name} has method({method.Name}) which returns {method.ReturnType.Name} and is not currently supported");
                        continue;
                    }

                    var isAsync          = method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>);
                    var methodReturnType = isAsync ? method.ReturnType.GetGenericArguments()[0] : method.ReturnType;

                    if (method.GetCustomAttribute <QLIgnoreAttribute>() != null)
                    {
                        _logger.Info($"Manager: {managerType.Name} has method({method.Name}) that is ignored due to QLIgnore Attribute");
                        continue;
                    }

                    string memberXmlComment = null;
                    var    memberXml        = xmlMemberComments?.FirstOrDefault(f => f.Attribute("name")?.Value.StartsWith($"M:{method.DeclaringType.FullName}.{method.Name}") ?? false);
                    if (memberXml != null)
                    {
                        memberXmlComment = memberXml.Element("summary")?.Value?.Trim();
                    }

                    var methodObsoleteAtt       = (ObsoleteAttribute)managerType.GetCustomAttribute(typeof(ObsoleteAttribute));
                    var methodDeprecationReason = methodObsoleteAtt != null ? methodObsoleteAtt.Message ?? "Marked Obsolete" : null;
                    if (!string.IsNullOrWhiteSpace(methodDeprecationReason))
                    {
                        deprecationReason = methodDeprecationReason;
                    }

                    QueryArguments queryArgs = new QueryArguments();
                    foreach (var inputParam in method.GetParameters())
                    {
                        var qlInputType = GraphQLUtilities.GenerateQlInputType(inputParam.ParameterType, services, out _);
                        var paramXml    = memberXml?.Elements().FirstOrDefault(f => f.Attribute("name")?.Value == inputParam.Name)?.Value?.Trim();
                        queryArgs.Add(GraphQLUtilities.GetQLInputQueryArgument(inputParam, qlInputType, paramXml));
                    }

                    var fieldName = $"{managerType.Name}_{method.Name}";

                    // If the method is marked with a qlquery attribute then attach it to the query object if not default to mutation
                    var qlQueryAttr         = method.GetCustomAttribute <QLQueryAttribute>();
                    var destinationQLObject = qlQueryAttr == null ? mutation : query;

                    //Check if method has been overloaded
                    if (destinationQLObject.Fields.Any(a => a.Name == fieldName))
                    {
                        _logger.Debug($"Manager {managerType.Name} has method({method.Name}) overloads which is not supported");
                        fieldName = fieldName + "_" + (destinationQLObject.Fields.Count(a => a.Name == fieldName) + 1);
                    }

                    //Add field to QL
                    if (isAsync)
                    {
                        destinationQLObject.FieldAsync(
                            GraphQLUtilities.GenerateQLOutputType(methodReturnType, services),
                            fieldName,
                            memberXmlComment,
                            queryArgs,
                            async context =>
                        {
                            var serviceProv = ((QLUserContext)context.UserContext).ServiceProvider;
                            var logger      = (ILogManager)serviceProv.GetService(typeof(ILogManager));

                            try
                            {
                                GetMethodManagerAndMethodParameters(method, context, serviceProv, out var manager, out var parameters);

                                logger.Debug($"Invoking Async {managerType.Name}.{method.Name}");
                                var methodTask = (Task)method.Invoke(manager, parameters);
                                await methodTask.ConfigureAwait(false);
                                var resultPropertyInfo = methodTask.GetType().GetProperty("Result");
                                return(resultPropertyInfo.GetValue(methodTask));
                            }
                            catch (Exception ex)
                            {
                                logger.Fatal($"Error during manager call, {managerType.Name}.{method.Name}", ex);
                                throw;
                            }
                        },
                            deprecationReason);
                    }
                    else
                    {
                        destinationQLObject.Field(
                            GraphQLUtilities.GenerateQLOutputType(methodReturnType, services),
                            fieldName,
                            memberXmlComment,
                            queryArgs,
                            context =>
                        {
                            var serviceProv = ((QLUserContext)context.UserContext).ServiceProvider;
                            var logger      = (ILogManager)serviceProv.GetService(typeof(ILogManager));

                            try
                            {
                                GetMethodManagerAndMethodParameters(method, context, serviceProv, out var manager, out var parameters);

                                logger.Debug($"Invoking {managerType.Name}.{method.Name}");
                                return(method.Invoke(manager, parameters));
                            }
        public void prints_interface()
        {
            var root = new ObjectGraphType {
                Name = "Root"
            };

            root.Field <BarType>("bar");

            var schema = new Schema {
                Query = root
            };

            AssertEqual(print(schema), "", @"
schema {
  query: Root
}

type Bar implements Foo {
  # This is of type String
  str: String
}

scalar Byte

# The `Date` scalar type represents a year, month and day in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar Date

# The `DateTime` scalar type represents a date and time. `DateTime` expects
# timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTime

# The `DateTimeOffset` scalar type represents a date, time and offset from UTC.
# `DateTimeOffset` expects timestamps to be formatted in accordance with the
# [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) standard.
scalar DateTimeOffset

scalar Decimal

# This is a Foo interface type
interface Foo {
  # This is of type String
  str: String
}

scalar Guid

# The `Milliseconds` scalar type represents a period of time represented as the total number of milliseconds.
scalar Milliseconds

type Root {
  bar: Bar
}

scalar SByte

# The `Seconds` scalar type represents a period of time represented as the total number of seconds.
scalar Seconds

scalar Short

scalar UInt

scalar ULong

scalar Uri

scalar UShort
", excludeScalars: true);
        }
Example #47
0
        public void SetupMutationDefinitions(ObjectGraphType type)
        {
            type.FieldAsync <StatusEventType>(
                "cancelAnyTimer",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = SchemaConstants.Id
            }
                    ),
                resolve: async context =>
            {
                var user     = await context.UserRecord();
                var anytimer = await _repository.ById(context.GetArgument <string>(SchemaConstants.Id));
                if (anytimer == null)
                {
                    return(context.Error(GraphQLErrors.UnknownAnyTimer));
                }
                if (!anytimer.CreatorId.Equals(user.Uid))
                {
                    return(context.Error(GraphQLErrors.NotCreator));
                }
                if (anytimer.Status == AnyTimerStatus.Cancelled)
                {
                    return(context.Error(GraphQLErrors.NotEditable));
                }

                // TODO Update total own for senders

                var evt = AnyTimerMutations.UpdateStatus(anytimer, AnyTimerStatus.Cancelled);
                await _repository.Update(anytimer);

                return(evt);
            }
                ).RequiresAuthentication();

            type.FieldAsync <StatusEventType>(
                "acceptAnyTimer",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = SchemaConstants.Id
            }
                    ),
                resolve: async context =>
            {
                var user     = await context.UserRecord();
                var anytimer = await _repository.ById(context.GetArgument <string>(SchemaConstants.Id));
                if (anytimer == null)
                {
                    return(context.Error(GraphQLErrors.UnknownAnyTimer));
                }
                if (!anytimer.ReceiverId.Equals(user.Uid))
                {
                    return(context.Error(GraphQLErrors.NotReceiver));
                }
                if (anytimer.Status != AnyTimerStatus.Requested && anytimer.Status != AnyTimerStatus.Disputed &&
                    anytimer.Status != AnyTimerStatus.Edited)
                {
                    return(context.Error(GraphQLErrors.NotEditable));
                }

                var evt = AnyTimerMutations.UpdateStatus(anytimer, AnyTimerStatus.Accepted);

                // TODO Send push notifications
                // TODO Add to total of owed for senders.

                await _repository.Update(anytimer);
                return(evt);
            }
                ).RequiresAuthentication();

            type.FieldAsync <StatusEventType>(
                "disputeAnyTimer",
                arguments: new QueryArguments(
                    new QueryArgument <IdGraphType> {
                Name = SchemaConstants.Id
            },
                    new QueryArgument <StringGraphType> {
                Name = SchemaConstants.Message
            }
                    ),
                resolve: async context =>
            {
                var user     = await context.UserRecord();
                var anytimer = await _repository.ById(context.GetArgument <string>(SchemaConstants.Id));
                if (anytimer == null)
                {
                    return(context.Error(GraphQLErrors.UnknownAnyTimer));
                }
                if (!anytimer.ReceiverId.Equals(user.Uid))
                {
                    return(context.Error(GraphQLErrors.NotReceiver));
                }
                if (anytimer.Status != AnyTimerStatus.Requested && anytimer.Status != AnyTimerStatus.Edited)
                {
                    return(context.Error(GraphQLErrors.NotEditable));
                }

                var evt = AnyTimerMutations.UpdateStatus(anytimer, AnyTimerStatus.Accepted,
                                                         context.GetArgument <string>(SchemaConstants.Message));

                // Add to total of owed for senders
                await _repository.Update(anytimer);

                return(evt);
            }
                );
        }
        public object ExecuteFields(ExecutionContext context, ObjectGraphType rootType, object source, Dictionary<string, Fields> fields)
        {
            var result = new Dictionary<string, object>();

            fields.Apply(pair =>
            {
                result[pair.Key] = ResolveField(context, rootType, source, pair.Value);
            });

            return result;
        }
Example #49
0
        public static ObjectGraphType AddBeerMutations(this ObjectGraphType objectGraphType, IRepository <Beer> beerRepository)
        {
            objectGraphType.FieldAsync <BeerType>(
                "createBeer",
                arguments: new QueryArguments(new QueryArgument <NonNullGraphType <BeerInputType> > {
                Name = "beer"
            }),
                resolve: async context =>
            {
                try
                {
                    return(await beerRepository.Add(context.GetArgument <Beer>("beer")).ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    context.Errors.Add(new ExecutionError("Couldn't add new beer"));
                    return(null);
                }
            });

            objectGraphType.FieldAsync <BeerType>(
                "updateBeer",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <BeerInputType> > {
                Name = "beer"
            },
                    new QueryArgument <NonNullGraphType <IdGraphType> > {
                Name = "beerId"
            }),
                resolve: async(context) =>
            {
                var beer   = context.GetArgument <Beer>("beer");
                var beerId = context.GetArgument <int>("beerId");

                try
                {
                    var dbBeer         = await beerRepository.GetSingle(x => x.Id == beerId);
                    dbBeer.Name        = beer.Name;
                    dbBeer.Description = beer.Description;
                    dbBeer.IBU         = beer.IBU;
                    dbBeer.ABV         = beer.ABV;

                    return(await beerRepository.Update(dbBeer).ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    context.Errors.Add(new ExecutionError("Couldn't find beer in database."));
                    return(null);
                }
            });

            objectGraphType.FieldAsync <DeletePayloadType>(
                "deleteBeer",
                arguments: new QueryArguments(new QueryArgument <NonNullGraphType <IdGraphType> > {
                Name = "beerId"
            }),
                resolve: async context =>
            {
                var beerId = context.GetArgument <int>("beerId");

                try
                {
                    await beerRepository.Delete(x => x.Id == beerId).ConfigureAwait(false);
                    return(new DeletePayload {
                        Success = true
                    });
                }
                catch (Exception ex)
                {
                    context.Errors.Add(new ExecutionError("Couldn't delete beer from database."));
                    return(null);
                }
            });

            return(objectGraphType);
        }
Example #50
0
        public async Task<object> ResolveField(ExecutionContext context, ObjectGraphType parentType, object source, Fields fields)
        {
            context.CancellationToken.ThrowIfCancellationRequested();

            var field = fields.First();

            var fieldDefinition = GetFieldDefinition(context.Schema, parentType, field);
            if (fieldDefinition == null)
            {
                return null;
            }

            var arguments = GetArgumentValues(context.Schema, fieldDefinition.Arguments, field.Arguments, context.Variables);

            Func<ResolveFieldContext, object> defaultResolve = (ctx) =>
            {
                return ctx.Source != null ? GetProperyValue(ctx.Source, ctx.FieldAst.Name) : null;
            };

            try
            {
                var resolveContext = new ResolveFieldContext();
                resolveContext.FieldAst = field;
                resolveContext.FieldDefinition = fieldDefinition;
                resolveContext.Schema = context.Schema;
                resolveContext.ParentType = parentType;
                resolveContext.Arguments = arguments;
                resolveContext.Source = source;
                resolveContext.CancellationToken = context.CancellationToken;
                var resolve = fieldDefinition.Resolve ?? defaultResolve;
                var result = resolve(resolveContext);

                if(result is Task)
                {
                    var task = result as Task;
                    await task;

                    result = GetProperyValue(task, "Result");
                }

                if (parentType is __Field && result is Type)
                {
                    result = context.Schema.FindType(result as Type);
                }

                return await CompleteValue(context, context.Schema.FindType(fieldDefinition.Type), fields, result);
            }
            catch (Exception exc)
            {
                context.Errors.Add(new ExecutionError("Error trying to resolve {0}.".ToFormat(field.Name), exc));
                return null;
            }
        }
        public void can_create_custom_directive_for_all_locations_graph_type_first()
        {
            var schema = new Schema();

            schema.ApplyDirective("schema");
            schema.HasAppliedDirectives().ShouldBeTrue();
            schema.GetAppliedDirectives().Count.ShouldBe(1);

            var objectType = new ObjectGraphType();

            objectType.ApplyDirective("type");
            objectType.HasAppliedDirectives().ShouldBeTrue();
            objectType.GetAppliedDirectives().Count.ShouldBe(1);

            var field = objectType.Field <StringGraphType>("test");

            field.ApplyDirective("field");
            field.HasAppliedDirectives().ShouldBeTrue();
            field.GetAppliedDirectives().Count.ShouldBe(1);

            var interfaceType = new InterfaceGraphType();

            interfaceType.ApplyDirective("interface");
            interfaceType.HasAppliedDirectives().ShouldBeTrue();
            interfaceType.GetAppliedDirectives().Count.ShouldBe(1);

            var unionType = new UnionGraphType();

            unionType.ApplyDirective("union");
            unionType.HasAppliedDirectives().ShouldBeTrue();
            unionType.GetAppliedDirectives().Count.ShouldBe(1);

            var arg = new QueryArgument(new StringGraphType());

            arg.ApplyDirective("arg");
            arg.HasAppliedDirectives().ShouldBeTrue();
            arg.GetAppliedDirectives().Count.ShouldBe(1);

            var enumType = new EnumerationGraphType();

            enumType.ApplyDirective("enumType");
            enumType.HasAppliedDirectives().ShouldBeTrue();
            enumType.GetAppliedDirectives().Count.ShouldBe(1);

            var enumValue = new EnumValueDefinition();

            enumValue.ApplyDirective("enumValue");
            enumValue.HasAppliedDirectives().ShouldBeTrue();
            enumValue.GetAppliedDirectives().Count.ShouldBe(1);

            var inputType = new InputObjectGraphType();

            inputType.ApplyDirective("inputType");
            inputType.HasAppliedDirectives().ShouldBeTrue();
            inputType.GetAppliedDirectives().Count.ShouldBe(1);

            var input = inputType.Field <StringGraphType>("test");

            input.ApplyDirective("inputField");
            input.HasAppliedDirectives().ShouldBeTrue();
            input.GetAppliedDirectives().Count.ShouldBe(1);

            var scalarType = new BigIntGraphType();

            scalarType.ApplyDirective("scalar");
            scalarType.HasAppliedDirectives().ShouldBeTrue();
            scalarType.GetAppliedDirectives().Count.ShouldBe(1);
        }
Example #52
0
    public void MergeFieldAndFragment()
    {
        var fragmentSelection = new GraphQLSelectionSet
        {
            Selections = new List <ASTNode>
            {
                FirstTestField
            }
        };
        var fragment = new GraphQLFragmentDefinition
        {
            FragmentName = new GraphQLFragmentName {
                Name = new GraphQLName("fragment")
            },
            TypeCondition = new GraphQLTypeCondition
            {
                Type = new GraphQLNamedType
                {
                    Name = new GraphQLName("Query")
                }
            },
            SelectionSet = fragmentSelection
        };

        var document = new GraphQLDocument
        {
            Definitions = new List <ASTNode>
            {
                fragment
            }
        };

        var query = new ObjectGraphType {
            Name = "Query"
        };

        query.Fields.Add(new FieldType
        {
            Name         = "test",
            ResolvedType = new StringGraphType()
        });
        var schema = new Schema {
            Query = query
        };

        var context = new ExecutionContext
        {
            Document = document,
            Schema   = schema
        };

        var fragSpread = new GraphQLFragmentSpread {
            FragmentName = new GraphQLFragmentName {
                Name = new GraphQLName("fragment")
            }
        };
        var outerSelection = new GraphQLSelectionSet
        {
            Selections = new List <ASTNode>
            {
                fragSpread,
                SecondTestField
            }
        };

        var fields = CollectFrom(context, query, outerSelection);

        fields.ShouldHaveSingleItem();
        fields["test"].Field.SelectionSet.Selections.ShouldContain(x => x == FirstInnerField);
        fields["test"].Field.SelectionSet.Selections.ShouldContain(x => x == SecondInnerField);
    }
Example #53
0
        public void Initialize(IGraphModel model, ISchemaEntity schema)
        {
            var schemaType = schema.TypeName();
            var schemaName = schema.DisplayName();

            Name = $"{schemaType}DataDto";

            foreach (var field in schema.SchemaDef.Fields.ForApi())
            {
                var(resolvedType, valueResolver) = model.GetGraphType(schema, field);

                if (valueResolver != null)
                {
                    var fieldType = field.TypeName();
                    var fieldName = field.DisplayName();

                    var fieldGraphType = new ObjectGraphType
                    {
                        Name = $"{schemaType}Data{fieldType}Dto"
                    };

                    var partition = model.ResolvePartition(field.Partitioning);

                    foreach (var partitionItem in partition)
                    {
                        var key = partitionItem.Key;

                        var partitionResolver = new FuncFieldResolver <object>(c =>
                        {
                            if (((ContentFieldData)c.Source).TryGetValue(key, out var value))
                            {
                                return(valueResolver(value, c));
                            }
                            else
                            {
                                return(null);
                            }
                        });

                        fieldGraphType.AddField(new FieldType
                        {
                            Name         = key.EscapePartition(),
                            Resolver     = partitionResolver,
                            ResolvedType = resolvedType,
                            Description  = field.RawProperties.Hints
                        });
                    }

                    fieldGraphType.Description = $"The structure of the {fieldName} field of the {schemaName} content type.";

                    var fieldResolver = new FuncFieldResolver <NamedContentData, IReadOnlyDictionary <string, IJsonValue> >(c =>
                    {
                        return(c.Source.GetOrDefault(field.Name));
                    });

                    AddField(new FieldType
                    {
                        Name         = field.Name.ToCamelCase(),
                        Resolver     = fieldResolver,
                        ResolvedType = fieldGraphType,
                        Description  = $"The {fieldName} field."
                    });
                }
            }

            Description = $"The structure of the {schemaName} content type.";
        }
Example #54
0
        private void AddFieldToType(ObjectGraphType type, FieldType field)
        {
            var newField = type.Field(field.Type, field.Name, field.Description, field.Arguments, field.Resolve);

            newField.DeprecationReason = field.DeprecationReason;
        }
Example #55
0
        public string PrintObject(ObjectGraphType type)
        {
            var interfaces = type.Interfaces.Select(x => Schema.FindType(x).Name).ToList();
            var implementedInterfaces = interfaces.Any()
                ? " implements {0}".ToFormat(string.Join(", ", interfaces))
                : "";

            return "type {1}{2} {{{0}{3}{0}}}".ToFormat(Environment.NewLine, type.Name, implementedInterfaces, PrintFields(type));
        }
        public void can_get_nullable_argument_with_value()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<StringGraphType>()
                .Argument<IntGraphType, int?>("skip", "desc1", 1)
                .Resolve(context =>
                {
                    context.GetArgument<int?>("skip").ShouldEqual(1);
                    return null;
                });

            var field = objectType.Fields.First();
            field.Resolve(new ResolveFieldContext
            {
                Arguments = new Dictionary<string, object>
                {
                    { "skip", 1 }
                },
                FieldDefinition = field
            });
        }
Example #57
0
 public async Task<object> ExecuteFields(ExecutionContext context, ObjectGraphType rootType, object source, Dictionary<string, Fields> fields)
 {
     return await fields.ToDictionaryAsync(
         pair => pair.Key,
         pair => ResolveField(context, rootType, source, pair.Value));
 }
        public void can_have_arguments_with_and_without_default_values()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<IntGraphType>()
                .Argument<StringGraphType, string>("arg1", "desc1", "12345")
                .Argument<IntGraphType, int>("arg2", "desc2", 9)
                .Argument<IntGraphType>("arg3", "desc3");

            var field = objectType.Fields.First();
            field.Arguments.Count.ShouldEqual(3);

            field.Arguments[0].Name.ShouldEqual("arg1");
            field.Arguments[0].Description.ShouldEqual("desc1");
            field.Arguments[0].Type.ShouldEqual(typeof(StringGraphType));
            field.Arguments[0].DefaultValue.ShouldEqual("12345");

            field.Arguments[1].Name.ShouldEqual("arg2");
            field.Arguments[1].Description.ShouldEqual("desc2");
            field.Arguments[1].Type.ShouldEqual(typeof(IntGraphType));
            field.Arguments[1].DefaultValue.ShouldEqual(9);

            field.Arguments[2].Name.ShouldEqual("arg3");
            field.Arguments[2].Description.ShouldEqual("desc3");
            field.Arguments[2].Type.ShouldEqual(typeof(IntGraphType));
            field.Arguments[2].DefaultValue.ShouldEqual(null);
        }
Example #59
0
        public FieldType GetFieldDefinition(ISchema schema, ObjectGraphType parentType, Field field)
        {
            if (field.Name == SchemaIntrospection.SchemaMeta.Name && schema.Query == parentType)
            {
                return SchemaIntrospection.SchemaMeta;
            }
            if (field.Name == SchemaIntrospection.TypeMeta.Name && schema.Query == parentType)
            {
                return SchemaIntrospection.TypeMeta;
            }
            if (field.Name == SchemaIntrospection.TypeNameMeta.Name)
            {
                return SchemaIntrospection.TypeNameMeta;
            }

            return parentType.Fields.FirstOrDefault(f => f.Name == field.Name);
        }
        public void can_have_a_default_value()
        {
            var objectType = new ObjectGraphType();
            objectType.Field<IntGraphType>()
                .Returns<int>()
                .DefaultValue(15);

            objectType.Fields.First().DefaultValue.ShouldEqual(15);
        }