Ejemplo n.º 1
0
        public static void Add(IStatsProvider statsProvider, ComplexGraphType <object> type)
        {
            type.Field <ListGraphType <StatType> >("stats", arguments: new QueryArguments
            {
                new QueryArgument(typeof(StringGraphType))
                {
                    Name        = "team1",
                    Description = "Team 1"
                },

                new QueryArgument(typeof(StringGraphType))
                {
                    Name        = "team2",
                    Description = "Team 2"
                }
            },
                                                   resolve: context =>
            {
                var c     = context as ResolveFieldContext;
                var team1 = c.Arguments["team1"].ToString();
                var team2 = c.Arguments["team2"].ToString();

                return(statsProvider.GetStatsAsync(team1, team2).Result);
            });
        }
Ejemplo n.º 2
0
        public static void AddFields <TOutput>(IContainer container, ComplexGraphType <object> obj) where TOutput : class
        {
            var outputType           = typeof(TOutput);
            var objectType           = obj.GetType();
            var filter               = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;
            var methods              = objectType.GetMethods(filter);
            var objectTypeProperties = objectType.GetProperties(filter);

            foreach (var propertyInfo in objectTypeProperties)
            {
                if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic)
                {
                    AddField(container, obj, outputType, propertyInfo, methods.FirstOrDefault(m => m.Name == $"Get{propertyInfo.Name}"));
                }
            }
            foreach (var propertyInfo in outputType.GetProperties(filter))
            {
                //Skip properties that are already defined in the object type
                if (objectTypeProperties.Any(p => p.Name == propertyInfo.Name))
                {
                    continue;
                }
                if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic)
                {
                    AddField(container, obj, outputType, propertyInfo, methods.FirstOrDefault(m => m.Name == $"Get{propertyInfo.Name}"));
                }
            }
        }
Ejemplo n.º 3
0
        public void ConfigureField(ComplexGraphType <TModel> graphType, GraphTypeCache cache, IServiceCollection services)
        {
            FieldType field;

            if (TryGetScalarGraphType(out var graphQlType))
            {
                AuthResolver.ValidateGraphqlType(graphQlType, Property);
                field = new FieldType
                {
                    Type     = graphQlType,
                    Name     = Property.Name,
                    Resolver = AuthResolver.GetResolver(services, NameFieldResolver.Instance)
                };
            }
            else
            {
                if (ResolverConfiguration == null)
                {
                    throw new UnableToResolveException(Property, typeof(TModel));
                }

                field          = ResolverConfiguration.ConfigureField(Property, cache, services);
                field.Resolver = AuthResolver.GetResolver(services, field.Resolver);
            }

            var descAttr = Property.GetCustomAttribute <DescriptionAttribute>();

            field.Description = descAttr?.Description;

            var isOutputType      = field.Type?.IsOutputType();
            var isOutputGraphType = field.ResolvedType?.IsOutputType();

            graphType.AddField(field);
        }
Ejemplo n.º 4
0
        public void AddNavigationConnectionField <TSource, TReturn>(
            ComplexGraphType <TSource> graph,
            string name,
            Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve = null,
            Type?itemGraphType = null,
            IEnumerable <QueryArgument>?arguments = null,
            IEnumerable <string>?includeNames     = null,
            int pageSize       = 10,
            string?description = null)
            where TReturn : class
        {
            Guard.AgainstNull(nameof(graph), graph);

            Guard.AgainstNullWhiteSpace(nameof(name), name);
            Guard.AgainstNegative(nameof(pageSize), pageSize);

            itemGraphType ??= GraphTypeFinder.FindGraphType <TReturn>();
            var fieldType = GetFieldType <TSource>(name, itemGraphType);

            var builder = ConnectionBuilder <TSource> .Create <FakeGraph>(name);

            if (description != null)
            {
                builder.Description(description);
            }

            builder.PageSize(pageSize).Bidirectional();
            SetField(builder, fieldType);
            IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);

            var hasId = keyNames.ContainsKey(typeof(TReturn));

            if (resolve != null)
            {
                builder.ResolveAsync(async context =>
                {
                    var efFieldContext = BuildContext(context);

                    var enumerable = resolve(efFieldContext);


                    enumerable = enumerable.ApplyGraphQlArguments(hasId, context);
                    enumerable = await efFieldContext.Filters.ApplyFilter(enumerable, context.UserContext);
                    var page   = enumerable.ToList();

                    return(ConnectionConverter.ApplyConnectionContext(
                               page,
                               context.First,
                               context.After,
                               context.Last,
                               context.Before));
                });
            }

            var connection = builder;

            var field = graph.AddField(connection.FieldType);

            field.AddWhereArgument(hasId, arguments);
        }
Ejemplo n.º 5
0
        internal static void AddAppliedDirectivesField <TSourceType>(this ComplexGraphType <TSourceType> type, string element)
            where TSourceType : IProvideMetadata
        {
            type.FieldAsync <NonNullGraphType <ListGraphType <NonNullGraphType <__AppliedDirective> > > >(
                name: "appliedDirectives",
                description: $"Directives applied to the {element}",
                resolve: async context =>
            {
                if (context.Source !.HasAppliedDirectives())
                {
                    var appliedDirectives = context.Source.GetAppliedDirectives();
                    var result            = context.ArrayPool.Rent <AppliedDirective>(appliedDirectives !.Count);

                    int index = 0;
                    foreach (var applied in appliedDirectives.List)
                    {
                        // return only registered directives allowed by filter
                        var schemaDirective = context.Schema.Directives.Find(applied.Name);
                        if (schemaDirective != null && await context.Schema.Filter.AllowDirective(schemaDirective))
                        {
                            result[index++] = applied;
                        }
                    }

                    return(result.Constrained(index));
                }

                return(Array.Empty <AppliedDirective>());
            });
        }
        static void AddMember <TSource>(ComplexGraphType <TSource> graph, PropertyInfo property)
        {
            var(compile, propertyGraphType) = Compile <TSource>(property);
            var resolver     = new SimpleFieldResolver <TSource>(compile);
            var graphQlField = graph.Field(type: propertyGraphType, name: property.Name);

            graphQlField.Resolver = resolver;
        }
Ejemplo n.º 7
0
 internal static void Register <TProduct>(ComplexGraphType <TProduct> type, Func <IResolveFieldContext <TProduct>, Object> reviewResolver = null)
     where TProduct : IProduct
 {
     type.Field(p => p.Name).Description("The products name");
     type.Field(p => p.Id).Description("The products id").Type(new NonNullGraphType(new IdGraphType()));
     type.Field(p => p.Stock).Description("The number of products in stock");
     type.Field(p => p.Type).Description("The type of product");
     type.Field <ListGraphType <ReviewType> >("reviews", resolve: reviewResolver);
 }
Ejemplo n.º 8
0
        public bool TryPrime <T>(ComplexGraphType <T> graphType)
        {
            if (_cache.ContainsKey(typeof(T)))
            {
                return(false);
            }

            _cache[typeof(T)] = graphType;

            return(true);
        }
 /// <summary>
 /// Add all reflected properties as fields (unless they are specified in <paramref name="excludedProperties"/>.
 /// </summary>
 /// <typeparam name="TSourceType"></typeparam>
 /// <param name="type"></param>
 /// <param name="excludedProperties"></param>
 public static void AddAllPropertiesAsFields <TSourceType>(this ComplexGraphType <TSourceType> type, params Expression <Func <TSourceType, object> >[] excludedProperties)
 {
     GraphObjectTypeReflectionHelper.SetFields(
         type,
         GetRegisteredProperties(typeof(TSourceType)),
         new GraphObjectTypeReflectionOptions <TSourceType>
     {
         ExcludedProperties = excludedProperties,
     }
         );
 }
        public static void SetFields <TSourceType>(ComplexGraphType <TSourceType> type, IEnumerable <PropertyInfo> properties, GraphObjectTypeReflectionOptions <TSourceType> options)
        {
            // Default the options if we get a null passed in.
            if (options == null)
            {
                options = new GraphObjectTypeReflectionOptions <TSourceType>();
            }

            //type.Name = typeof(TSourceType).GraphQLName(); // Don't do this, it will then break with Input types.

            // Helper method that works out if
            bool isNullable(PropertyInfo propertyInfo)
            {
                if (!options.Nullable.HasValue)
                {
                    return(IsNullableProperty(propertyInfo));
                }

                if (options.NullableProperties?.Any(p => GetPropertyName(p) == propertyInfo.Name) == true)
                {
                    return(true);
                }

                if (options.NonNullableProperties?.Any(p => GetPropertyName(p) == propertyInfo.Name) == true)
                {
                    return(false);
                }

                return(options.Nullable.Value);
            }

            foreach (var propertyInfo in properties)
            {
                if (options.ExcludedProperties?.Any(p => GetPropertyName(p) == propertyInfo.Name) == true)
                {
                    continue;
                }

                if (options.SkipExisting)
                {
                    if (type.Fields.Any(p => p.Name == propertyInfo.Name))
                    {
                        continue;
                    }
                }

                type.Field(
                    type: propertyInfo.PropertyType.GetGraphTypeFromType(isNullable(propertyInfo)),
                    name: propertyInfo.Name,
                    description: propertyInfo.Description(),
                    deprecationReason: propertyInfo.ObsoleteMessage()
                    ).DefaultValue = (propertyInfo.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault() as DefaultValueAttribute)?.Value;
            }
        }
        /// <summary>
        /// Adds a connection field. Shorthand for <see cref="AddConnectionField<TEntity, TEntityGraphType>" />.
        /// </summary>
        public static FieldType AddConnectionField(this ComplexGraphType <object> type, Type entityType, Func <ResolveFieldContext <object>, object> resolve, string name, params QueryArgument[] arguments)
        {
            // construct type parameters
            var entityGraphType = typeof(NodeObjectType <>).MakeGenericType(entityType).ConvertToVirtualType();
            var method          = typeof(ComplexGraphTypeExtensions).GetMethods().Where(m => m.Name == "AddConnectionField" && m.IsGenericMethod).First();

            method = method.MakeGenericMethod(entityType, entityGraphType);

            // call like AddConnectionField<TEntity, TEntityGraphType>(...)
            return((FieldType)method.Invoke(null, new object[] { type, resolve, name, arguments }));
        }
Ejemplo n.º 12
0
        public static GraphQL.Builders.FieldBuilder <object, IQueryable <TSource> > CustomField <TGraphType, TSource>(
            this ComplexGraphType <object> graphType,
            string name,
            System.Func <GraphQL.IResolveFieldContext <object>, IQueryable <TSource> > resolve)
            where TSource : class
        {
            var builder = graphType.Field <ObjectGraphType <IQueryable <TSource> >, IQueryable <TSource> >(name);

            builder.Resolve(resolve);
            return(builder);
        }
Ejemplo n.º 13
0
        public static FieldType RemoteField <TSourceType>(this ComplexGraphType <TSourceType> self, IEnumerable <Type> types, string remoteMoniker, string typeName, string name, string description = null, QueryArguments arguments = null, Func <ResolveFieldContext <TSourceType>, object> resolve = null, string deprecationReason = null)
        {
            var type = types.FirstOrDefault(t => t.GetCustomAttributes(true).Any(a => a is RemoteLiteralGraphTypeMetadataAttribute metadata && metadata.RemoteMoniker == remoteMoniker && metadata.Name == typeName));

            if (type == null)
            {
                throw new ArgumentException($"Couldn't find a type in {nameof(types)} with remote '{remoteMoniker}' and name '{name}'");
            }

            return(self.Field(type, name, description, arguments, resolve, deprecationReason));
        }
Ejemplo n.º 14
0
        public static FieldType AssociationField <TSourceType>(
            this ComplexGraphType <TSourceType> _this,
            IGraphTypesCache graphTypesCache, string name, IReadOnlyList <string> allowedTypes, string roleId, GraphDirections graphDirection)
        {
            var graphTypes = allowedTypes.Select(ckId => graphTypesCache.GetOrCreate(ckId));

            var unionType = new RtEntityAssociationType(
                $"{_this.Name}_{name}{CommonConstants.GraphQlUnionSuffix}",
                $"Association {roleId} ({graphDirection}) of entity type {_this.Name}", graphTypesCache, graphTypes, roleId, graphDirection);

            return(_this.Field(name, null, unionType, resolve: context => context.Source));
        }
        /// <summary>
        /// Adds a field that gets an entity by id. Shorthand for <see cref="AddSingleField<TEntity, TEntityGraphType, TId>" />.
        /// </summary>
        public static FieldType AddSingleField(this ComplexGraphType <object> type, Type entityType, Func <ResolveFieldContext <object>, object> resolve, string name)
        {
            // construct type parameters
            var entityGraphType = typeof(NodeObjectType <>).MakeGenericType(entityType).ConvertToVirtualType();
            var idType          = entityType.GetIdType().MapToGraphType();
            var idName          = entityType.GetIdPropertyName().ToFirstLower();
            var method          = typeof(ComplexGraphTypeExtensions).GetMethods().Where(m => m.Name == "AddSingleField" && m.IsGenericMethod && m.GetGenericArguments().Count() == 3).First();

            method = method.MakeGenericMethod(entityType, entityGraphType, idType);

            // call like AddSingleField<TEntity, TEntityGraphType, TId>(...)
            return((FieldType)method.Invoke(null, new object[] { type, idName, resolve, name }));
        }
 /// <summary>
 /// Add all reflected properties as fields (unless they are specified in <paramref name="excludedProperties"/>.
 ///
 /// Properties with names already registered will be excluded automatically, allowing you to do this after first specifying those fields you want to control manually.
 /// </summary>
 /// <typeparam name="TSourceType"></typeparam>
 /// <param name="type"></param>
 /// <param name="nullable"></param>
 /// <param name="excludedProperties"></param>
 public static void AddRemainingPropertiesAsFields <TSourceType>(this ComplexGraphType <TSourceType> type, bool?nullable = null, params Expression <Func <TSourceType, object> >[] excludedProperties)
 {
     GraphObjectTypeReflectionHelper.SetFields(
         type,
         GetRegisteredProperties(typeof(TSourceType)),
         new GraphObjectTypeReflectionOptions <TSourceType>
     {
         Nullable           = nullable,
         ExcludedProperties = excludedProperties,
         SkipExisting       = true,
     }
         );
 }
    void AddEnumerableConnection <TSource, TGraph, TReturn>(
        ComplexGraphType <TSource> graph,
        string name,
        Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve,
        int pageSize,
        string?description,
        IEnumerable <QueryArgument>?arguments,
        IEnumerable <string>?includeNames)
        where TGraph : IGraphType
        where TReturn : class
    {
        var builder = ConnectionBuilder.Create <TGraph, TSource>();

        builder.Name(name);

        if (description is not null)
        {
            builder.Description(description);
        }
        builder.PageSize(pageSize).Bidirectional();
        IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);

        var hasId = keyNames.ContainsKey(typeof(TReturn));

        if (resolve is not null)
        {
            builder.ResolveAsync(async context =>
            {
                var efFieldContext = BuildContext(context);

                var enumerable = resolve(efFieldContext);

                enumerable = enumerable.ApplyGraphQlArguments(hasId, context);
                enumerable = await efFieldContext.Filters.ApplyFilter(enumerable, context.UserContext);
                var page   = enumerable.ToList();

                return(ConnectionConverter.ApplyConnectionContext(
                           page,
                           context.First,
                           context.After,
                           context.Last,
                           context.Before));
            });
        }

        // TODO: works around https://github.com/graphql-dotnet/graphql-dotnet/pull/2581/
        builder.FieldType.Type = typeof(NonNullGraphType <ConnectionType <TGraph, EdgeType <TGraph> > >);
        var field = graph.AddField(builder.FieldType);

        field.AddWhereArgument(hasId, arguments);
    }
        /// <summary>
        /// Adds a field that gets an entity by id.
        /// Example usage:
        /// <code>
        ///     this.AddSingleField<Order, NodeObjectType<Order>, IdGraphType>("id", context => {
        ///         var id = Guid.Parse(context.GetArgument<string>("id"));
        ///         var order = orderRepository.GetOrderById(id);
        ///         return order;
        ///     });
        /// </code>
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <typeparam name="TEntityGraphType">The type of the entity's GraphQL type (i.e. NodeObjectType<Entity>)</typeparam>
        /// <typeparam name="TId">The type of the id field (i.e. IdGraphType or IntGraphType)</typeparam>
        /// <param name="type"></param>
        /// <param name="idName">The name of the id property.</param>
        /// <param name="resolve">The resolving function that returns a <see cref="TEntity"/>.</param>
        /// <param name="name">The name of the field.</param>
        public static FieldType AddSingleField <TEntity, TEntityGraphType, TId>(this ComplexGraphType <object> type, string idName, Func <ResolveFieldContext <object>, object> resolve, string name = null) where TEntity : class, new() where TEntityGraphType : ComplexGraphType <object>, IGraphType <TEntity> where TId : GraphType
        {
            // create name if non is given
            var lowerCaseName = name != null ? name : $"{typeof(TEntity).Name.ToFirstLower()}";

            var arguments = new QueryArguments(
                new QueryArgument <NonNullGraphType <TId> >
            {
                Name        = idName,
                Description = $"id of a {lowerCaseName}"
            });

            return(type.Field(typeof(TEntityGraphType).ConvertToVirtualType(), lowerCaseName, $"The {lowerCaseName}", arguments, resolve));
        }
Ejemplo n.º 19
0
        static void MapProperties <TSource>(ComplexGraphType <TSource> graph, Type type, IReadOnlyList <string>?exclusions = null)
        {
            var publicProperties = type.GetPublicProperties()
                                   .OrderBy(x => x.Name);

            foreach (var property in publicProperties)
            {
                if (ShouldIgnore(graph, property.Name, property.PropertyType, exclusions))
                {
                    continue;
                }

                AddMember(graph, property);
            }
        }
Ejemplo n.º 20
0
        public static void AutoMap <TSource>(this
                                             ComplexGraphType <TSource> graph,
                                             IReadOnlyList <string>?exclusions = null)
        {
            var type = typeof(TSource);

            try
            {
                MapProperties(graph, type, exclusions);
            }
            catch (GetGraphException exception)
            {
                throw new Exception($"Failed to map '{graph.GetType().Name}'. {exception.Message}");
            }
        }
Ejemplo n.º 21
0
        public static ConnectionBuilder <TSourceType> Connection <TNodeType, TGraphType, TSourceType>(
            this ComplexGraphType <TNodeType> _this, IGraphTypesCache entityDtoCache, TGraphType itemType,
            string prefixName)
            where TGraphType : IGraphType
        {
            var type = entityDtoCache.GetOrCreateConnection(itemType, prefixName);

            var connectionBuilder =
                ConnectionBuilder <TSourceType> .Create <TGraphType>(
                    $"{prefixName}{CommonConstants.GraphQlConnectionSuffix}");

            connectionBuilder.FieldType.ResolvedType = type;
            _this.AddField(connectionBuilder.FieldType);
            return(connectionBuilder);
        }
Ejemplo n.º 22
0
        public static void AddField(IContainer container, ComplexGraphType <Object> obj, Type type, PropertyInfo propertyInfo, MethodInfo methodInfo)
        {
            if (propertyInfo.PropertyType == typeof(IContainer))
            {
                return;
            }
            var fieldType        = propertyInfo.PropertyType;
            var fieldName        = StringExtensions.PascalCase(propertyInfo.Name);
            var fieldDescription = "";
            var authFieldName    = $"{type.FullName}.{propertyInfo.Name}";

            Func <ResolveFieldContext <object>, object> contextResolve;

            if (methodInfo != null)
            {
                // Custom mapping of property
                contextResolve = context =>
                {
                    AuthorizeProperty(container, authFieldName);
                    return(methodInfo.Invoke(obj, GetArgumentsForMethod(methodInfo, container, context)));
                };
            }
            else
            {
                // 1 to 1 mapping of property to source
                contextResolve = context =>
                {
                    AuthorizeProperty(container, authFieldName);
                    var properties = context.Source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
                    var sourceProp = properties.FirstOrDefault(p => p.Name == propertyInfo.Name);
                    if (sourceProp == null)
                    {
                        throw new ArgumentException($"No matching source property found for GraphObject. Type: {type.Name} Property: {propertyInfo.Name}");
                    }
                    return(sourceProp.GetValue(context.Source));
                };
            }
            var graphType = TypeLoader.GetGraphType(fieldType);
            var nonNull   = Enumerable.Any(propertyInfo.CustomAttributes, a => a.AttributeType == typeof(RequiredAttribute));

            if (nonNull)
            {
                graphType = typeof(NonNullGraphType <>).MakeGenericType(graphType);
            }
            obj.Field(graphType, fieldName, fieldDescription, null, contextResolve);
            container.GetInstance <AuthorizationMap>().AddAuthorization(type, propertyInfo);
        }
Ejemplo n.º 23
0
        public static ComplexGraphType <IPublishedContent> AddUmbracoContentPropeties(
            this ComplexGraphType <IPublishedContent> graphType,
            IContentTypeComposition contentType,
            PublishedItemType publishedItemType)
        {
            var publishedContentType = PublishedContentType.Get(publishedItemType, contentType.Alias);

            foreach (var property in contentType.CompositionPropertyTypes)
            {
                //TODO: black/whitelist properties
                if (property.PropertyEditorAlias == Constants.PropertyEditors.ListViewAlias ||
                    property.PropertyEditorAlias == Constants.PropertyEditors.FolderBrowserAlias ||
                    property.Alias.StartsWith("umbracoMember"))
                {
                    continue;
                }

                var publishedPropertyType = publishedContentType.GetPropertyType(property.Alias);

                var resolver = GraphQLValueResolversResolver.Current.FindResolver(publishedPropertyType)
                               ?? new DefaultValueResolver();

                var propertyGraphType = resolver.GetGraphQLType(publishedPropertyType);

                if (property.Mandatory)
                {
                    propertyGraphType = typeof(NonNullGraphType <>).MakeGenericType(propertyGraphType);
                }

                graphType.Field(
                    propertyGraphType,
                    property.Alias.ToCamelCase(),
                    property.Description,
                    resolve: context =>
                {
                    var publishedProperty = context.Source.GetProperty(property.Alias);
                    return(publishedProperty == null
                            ? null
                            : resolver.Resolve(publishedPropertyType, publishedProperty.Value));
                }
                    ).SetPermissions(graphType);
            }

            return(graphType);
        }
Ejemplo n.º 24
0
        public static ComplexGraphType <IPublishedContent> AddContentDataProperties(this ComplexGraphType <IPublishedContent> graphType)
        {
            //TODO: black/whitelist properties
            graphType.Field <NonNullGraphType <DateGraphType> >("createDate", "Create date of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("creatorName", "Name of the content creator.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("documentTypeAlias", "Document type alias of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <IdGraphType> >("id", "Unique id of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <IntGraphType> >("index", "Index of the content.", resolve: context => context.Source.GetIndex()).SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <IntGraphType> >("level", "Level of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <BooleanGraphType> >("isFirst", "Is the content first in the list.", resolve: context => context.Source.IsFirst()).SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <BooleanGraphType> >("isLast", "Is the content last in the list.", resolve: context => context.Source.IsLast()).SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <BooleanGraphType> >("isVisible", "Is the content visible.", resolve: context => context.Source.IsVisible()).SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("name", "Name of the content.").SetPermissions(graphType, true);
            graphType.Field <PublishedContentGraphType>("parent", "Parent of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <IntGraphType> >("sortOrder", "SortOrder of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <DateGraphType> >("updateDate", "Update date of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("url", "Url of the content.").SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("urlAbsolute", "Absolute url of the content.", resolve: context => context.Source.UrlAbsolute()).SetPermissions(graphType, true);
            graphType.Field <NonNullGraphType <StringGraphType> >("writerName", "Name of the content writer.").SetPermissions(graphType, true);

            graphType.FilteredConnection <PublishedContentGraphType, IPublishedContent>()
            .Name("ancestors")
            .Description("Ancestors of the content.")
            .Argument <BooleanGraphType>("includeSelf", "include self in list")
            .Bidirectional()
            .Resolve(context =>
                     (context.GetArgument <bool?>("includeSelf") == true
                        ? context.Source.AncestorsOrSelf()
                        : context.Source.Ancestors()).Filter(context).ToConnection(context)
                     );

            graphType.FilteredConnection <PublishedContentGraphType, IPublishedContent>()
            .Name("siblings")
            .Description("Siblings of the content.")
            .Bidirectional()
            .Resolve(context => context.Source.Siblings().Filter(context).ToConnection(context));

            graphType.FilteredConnection <PublishedContentGraphType, IPublishedContent>()
            .Name("children")
            .Description("Children of the content.")
            .Bidirectional()
            .Resolve(context => context.Source.Children.Filter(context).ToConnection(context));

            return(graphType);
        }
Ejemplo n.º 25
0
 internal static FieldType FieldAsync <TSourceType>(this ComplexGraphType <TSourceType> _this,
                                                    string name,
                                                    string description       = null,
                                                    IGraphType graphType     = null,
                                                    QueryArguments arguments = null,
                                                    Func <IResolveFieldContext <TSourceType>, Task <object> > resolve = null,
                                                    string deprecationReason = null)
 {
     return(_this.AddField(new FieldType
     {
         Name = name,
         Description = description,
         DeprecationReason = deprecationReason,
         ResolvedType = graphType,
         Arguments = arguments,
         Resolver = resolve != null ? new AsyncFieldResolver <TSourceType, object>(resolve) : null
     }));
 }
Ejemplo n.º 26
0
        public static void AddAllFields(IContainer container, ComplexGraphType <Object> obj, Type type, bool declaredPropertiesOnly)
        {
            var filter = BindingFlags.Instance | BindingFlags.Public;

            if (declaredPropertiesOnly)
            {
                filter = filter | BindingFlags.DeclaredOnly;
            }
            var methods = type.GetMethods(filter);

            foreach (var propertyInfo in type.GetProperties(filter))
            {
                if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic)
                {
                    AddField(container, obj, type, propertyInfo, methods.FirstOrDefault(m => m.Name == $"Get{propertyInfo.Name}"));
                }
            }
        }
Ejemplo n.º 27
0
        public FieldType AddNavigationField <TSource, TReturn>(
            ComplexGraphType <TSource> graph,
            string name,
            Func <ResolveEfFieldContext <TDbContext, TSource>, TReturn?>?resolve = null,
            Type?graphType = null,
            IEnumerable <string>?includeNames = null,
            string?description = null)
            where TReturn : class
        {
            Guard.AgainstNull(nameof(graph), graph);
            Guard.AgainstNullWhiteSpace(nameof(name), name);

            graphType ??= GraphTypeFinder.FindGraphType <TReturn>();

            FieldType field = new()
            {
                Name        = name,
                Type        = graphType,
                Description = description
            };

            IncludeAppender.SetIncludeMetadata(field, name, includeNames);

            if (resolve != null)
            {
                field.Resolver = new AsyncFieldResolver <TSource, TReturn?>(
                    async context =>
                {
                    var fieldContext = BuildContext(context);

                    var result = resolve(fieldContext);
                    if (await fieldContext.Filters.ShouldInclude(context.UserContext, result))
                    {
                        return(result);
                    }

                    return(null);
                });
            }

            return(graph.AddField(field));
        }
    }
Ejemplo n.º 28
0
        internal static void AutoMap <TDbContext, TSource>(
            ComplexGraphType <TSource> graph,
            IEfGraphQLService <TDbContext> graphService,
            IReadOnlyList <string>?exclusions = null)
            where TDbContext : DbContext
        {
            var type = typeof(TSource);

            try
            {
                MapNavigationProperties(graph, graphService, type, exclusions);

                MapProperties(graph, type, exclusions);
            }
            catch (GetGraphException exception)
            {
                throw new Exception($"Failed to map '{graph.GetType().Name}'. {exception.Message}");
            }
        }
    public void AddNavigationConnectionField <TSource, TReturn>(
        ComplexGraphType <TSource> graph,
        string name,
        Func <ResolveEfFieldContext <TDbContext, TSource>, IEnumerable <TReturn> >?resolve = null,
        Type?itemGraphType = null,
        IEnumerable <QueryArgument>?arguments = null,
        IEnumerable <string>?includeNames     = null,
        int pageSize       = 10,
        string?description = null)
        where TReturn : class
    {
        Guard.AgainstWhiteSpace(nameof(name), name);
        Guard.AgainstNegative(nameof(pageSize), pageSize);

        itemGraphType ??= GraphTypeFinder.FindGraphType <TReturn>();

        var addConnectionT = addEnumerableConnection.MakeGenericMethod(typeof(TSource), itemGraphType, typeof(TReturn));

        addConnectionT.Invoke(this, new object?[] { graph, name, resolve, pageSize, description, arguments, includeNames });
    }
        FilteredConnection <TNodeType, TSourceType>(this ComplexGraphType <TSourceType> graphType)
            where TNodeType : GraphType
        {
            var builder = graphType.Connection <TNodeType>();

            builder.FieldType.Arguments.Add(
                new QueryArgument(typeof(FilterGraphType <TNodeType>))
            {
                Name         = "filter",
                ResolvedType = new FilterGraphType <TNodeType>(graphType)
            }
                );
            builder.FieldType.Arguments.Add(
                new QueryArgument(typeof(ListGraphType <NonNullGraphType <OrderByGraphType <TNodeType> > >))
            {
                Name         = "orderBy",
                ResolvedType = new ListGraphType(new NonNullGraphType(new OrderByGraphType <TNodeType>(graphType)))
            }
                );
            return(builder);
        }