Ejemplo n.º 1
0
 public MetaFieldGrpcService(
     IMetaFieldServiceProvider metaFieldServiceProvider,
     IGrpcCallerService grpcCallerService,
     IMappingService mappingService)
 {
     _metaFieldServiceProvider = metaFieldServiceProvider;
     _grpcCallerService        = grpcCallerService;
     _mappingService           = mappingService;
 }
        public ContentPageGraphType(
            IDataLoaderContextAccessor dataLoaderContextAccessor,
            IMetaFieldServiceProvider metaFieldServiceProvider,
            IMetaFieldService metaFieldService,
            IMetaFieldLookupService metaFieldLookupService,
            IContentPageService contentPageService,
            IContentPageLookupService contentPageLookupService
            )
        {
            Name = "ContentPage";

            Field <StringGraphType, string>()
            .Name("Id")
            .Description("Globally unique identifier, eg: gid://ContentPage/1000")
            .Resolve(ctx => ctx.Source.Id);

            Field <StringGraphType, string>()
            .Name("ParentId")
            .Description("Globally unique identifier of parent, 'gid://' if none")
            .Resolve(ctx => ctx.Source.ParentId);

            Field <StringGraphType, string>()
            .Name("Handle")
            .Description("A human-friendly unique string for the content page")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Handles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Title")
            .Description("The title of the content page")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Titles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Url")
            .Description("The url of the content page")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Urls
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Type")
            .Description("The type of the content page")
            .Resolve(ctx => ctx.Source.Type);

            Field <StringGraphType, string>()
            .Name("Description")
            .Description("The description of the content page")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Descriptions
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <DateTimeGraphType, DateTime>()
            .Name("CreatedAt")
            .Description("The timestamp of content page creation")
            .Resolve(ctx => ctx.Source.CreatedAt.ToDateTime());

            Field <DateTimeGraphType, DateTime>()
            .Name("UpdatedAt")
            .Description("The timestamp of the latest content page update")
            .Resolve(ctx => ctx.Source.UpdatedAt.ToDateTime());

            Field <ImageGraphType, Image>()
            .Name("PrimaryImage")
            .Description("The primary image of the content page")
            .Resolve(ctx => ctx.Source.PrimaryImage);

            #region Meta-fields

            Field <MetaFieldGraphType, MetaField>()
            .Name("MetaField")
            .Description("Connection to a specific meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("namespace", "Namespace of the meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("name", "Name of the meta-field")
            .ResolveAsync(async ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var result = await metaFieldService.GetBySearchAsync(
                    ctx.Source.Id,
                    ctx.GetArgument <string>("namespace"),
                    ctx.GetArgument <string>("name"));

                return(result.FirstOrDefault());
            });

            Field <ListGraphType <MetaFieldGraphType>, IList <MetaField> >()
            .Name("MetaFields")
            .Description("Connection to a all meta-fields")
            .ResolveAsync(ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, IList <MetaField> >("MetaField.LookupByParentIdsAsync", metaFieldLookupService.LookupByParentIdsAsync);
                return(loader.LoadAsync(ctx.Source.Id));
            });

            #endregion Meta-fields

            #region Content pages

            Field <ContentPageGraphType, ContentPage>()
            .Name("Parent")
            .ResolveAsync(ctx =>
            {
                if (string.IsNullOrEmpty(ctx.Source.ParentId))
                {
                    return(null);
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, ContentPage>("ContentPage.LookupByIdAsync", contentPageLookupService.LookupByIdAsync);
                return(loader.LoadAsync(ctx.Source.ParentId));
            });
            Connection <ContentPageGraphType>()
            .Name("Children")
            .Unidirectional()
            .Argument <StringGraphType>("query", "The search query to filter children by")
            .Argument <ContentPageSortKeyGraphType>("sortKey", "The key to sort the underlying list by")
            .Argument <StringGraphType>("reverse", "Reverse the order of the underlying list")
            .ResolveAsync(async ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                var result = await contentPageService.GetBySearchAsync(
                    ctx.GetArgument <string>("query"),
                    userContext.LanguageCode,
                    ctx.Source.Id,
                    ctx.GetArgument <string>("after"),
                    ctx.GetArgument <int>("first", 24),
                    ctx.GetArgument <ContentPageSortKey>("sortKey"),
                    ctx.GetArgument <bool>("reverse"));

                return(result.ToGraphConnection());
            });

            #endregion Content pages
        }
        public ProductGraphType(
            IDataLoaderContextAccessor dataLoaderContextAccessor,
            IMetaFieldServiceProvider metaFieldServiceProvider,
            IMetaFieldService metaFieldService,
            IMetaFieldLookupService metaFieldLookupService,
            ICategoryServiceProvider categoryServiceProvider,
            ICategoryLookupService categoryLookupService,
            IMappingService mappingService
            )
        {
            Name = "Product";

            Field <StringGraphType, string>()
            .Name("Id")
            .Description("Globally unique identifier, eg: gid://Product/1000")
            .Resolve(ctx => ctx.Source.Id);

            Field <StringGraphType, string>()
            .Name("ParentId")
            .Description("Globally unique identifier of parent, 'gid://' if none")
            .Resolve(ctx => ctx.Source.ParentId);

            Field <StringGraphType, string>()
            .Name("Handle")
            .Description("A human-friendly unique string for the product")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Handles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Title")
            .Description("The title of the product")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Titles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Url")
            .Description("The url of the product")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Urls
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Type")
            .Description("The type of the product")
            .Resolve(ctx => ctx.Source.Type);

            Field <StringGraphType, string>()
            .Name("Description")
            .Description("The description of the product")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Descriptions
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <DateTimeGraphType, DateTime>()
            .Name("CreatedAt")
            .Description("The timestamp of product creation")
            .Resolve(ctx => ctx.Source.CreatedAt.ToDateTime());

            Field <DateTimeGraphType, DateTime>()
            .Name("UpdatedAt")
            .Description("The timestamp of the latest product update")
            .Resolve(ctx => ctx.Source.UpdatedAt.ToDateTime());

            Field <StringGraphType, string>()
            .Name("PrimaryCategoryId")
            .Description("Globally unique identifier of the primary category the product belong to")
            .Resolve(ctx => ctx.Source.PrimaryCategoryId);

            Field <ListGraphType <StringGraphType>, IList <string> >()
            .Name("CategoryIds")
            .Description("Globally unique identifiers of categories the product belong to")
            .Resolve(ctx => ctx.Source.CategoryIds);

            Field <ListGraphType <ProductVariantGraphType>, IList <ProductVariant> >()
            .Name("Variants")
            .Description("The variants of the product")
            .Resolve(ctx => ctx.Source.Variants
                     .OrderBy(x => x.SortOrder)
                     .ToList());

            Field <ListGraphType <ImageGraphType>, IList <Image> >()
            .Name("Images")
            .Description("The images of the product")
            .Resolve(ctx => ctx.Source.Images);

            Field <ImageGraphType, Image>()
            .Name("PrimaryImage")
            .Description("The primary image of the product")
            .Resolve(ctx =>
            {
                if (ctx.Source.Images.Any())
                {
                    // First image of product
                    return(ctx.Source.Images.First());
                }

                foreach (var productVariant in ctx.Source.Variants)
                {
                    if (productVariant.Images.Any())
                    {
                        // First image of product product
                        return(ctx.Source.Images.First());
                    }
                }

                // No images
                return(null);
            });

            Field <MoneyGraphType, NodaMoney.Money>()
            .Name("UnitPriceFrom")
            .Description("The unit price of the cheapest variant")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                // Join unit prices for currency code and map to NodaMoney, return smallest
                return(mappingService
                       .Map <Proto.Types.Money, NodaMoney.Money>(
                           ctx.Source.Variants
                           .SelectMany(x =>
                                       x.UnitPrices.Where(p => p.CurrencyCode == userContext.CurrencyCode)))
                       .Min());
            });
            #region Meta-fields

            Field <MetaFieldGraphType, MetaField>()
            .Name("MetaField")
            .Description("Connection to a specific meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("namespace", "Namespace of the meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("name", "Name of the meta-field")
            .ResolveAsync(async ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var result = await metaFieldService.GetBySearchAsync(
                    ctx.Source.Id,
                    ctx.GetArgument <string>("namespace"),
                    ctx.GetArgument <string>("name"));

                return(result.FirstOrDefault());
            });

            Field <ListGraphType <MetaFieldGraphType>, IList <MetaField> >()
            .Name("MetaFields")
            .Description("Connection to a all meta-fields")
            .ResolveAsync(ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, IList <MetaField> >("MetaField.LookupByParentIdsAsync", metaFieldLookupService.LookupByParentIdsAsync);
                return(loader.LoadAsync(ctx.Source.Id));
            });

            #endregion Meta-fields

            #region Categories

            Field <CategoryGraphType, Category>()
            .Name("PrimaryCategory")
            .ResolveAsync(ctx =>
            {
                if (!categoryServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Categories not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, Category>("Category.LookupByIdAsync", categoryLookupService.LookupByIdAsync);
                return(loader.LoadAsync(ctx.Source.PrimaryCategoryId));
            });

            Field <ListGraphType <CategoryGraphType>, Category[]>()
            .Name("Categories")
            .ResolveAsync(ctx =>
            {
                if (!categoryServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Categories not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, Category>("Category.LookupByIdAsync", categoryLookupService.LookupByIdAsync);
                return(loader.LoadAsync(ctx.Source.CategoryIds));
            });

            #endregion Categories
        }
Ejemplo n.º 4
0
        public NavigationGraphType(
            IDataLoaderContextAccessor dataLoaderContextAccessor,
            IMetaFieldServiceProvider metaFieldServiceProvider,
            IMetaFieldService metaFieldService,
            IMetaFieldLookupService metaFieldLookupService
            )
        {
            Name = "Navigation";

            Field <StringGraphType, string>()
            .Name("Id")
            .Description("Globally unique identifier, eg: gid://Navigation/1000")
            .Resolve(ctx => ctx.Source.Id);

            Field <StringGraphType, string>()
            .Name("ParentId")
            .Description("Globally unique identifier of parent, 'gid://' if none")
            .Resolve(ctx => ctx.Source.ParentId);

            Field <StringGraphType, string>()
            .Name("Handle")
            .Description("A human-friendly unique string for the navigation")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Handles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Type")
            .Description("The type of the navigation")
            .Resolve(ctx => ctx.Source.Type);

            Field <DateTimeGraphType, DateTime>()
            .Name("CreatedAt")
            .Description("The timestamp of navigation creation")
            .Resolve(ctx => ctx.Source.CreatedAt.ToDateTime());

            Field <DateTimeGraphType, DateTime>()
            .Name("UpdatedAt")
            .Description("The timestamp of the latest navigation update")
            .Resolve(ctx => ctx.Source.UpdatedAt.ToDateTime());

            Field <NavigationLinkGraphType, NavigationLink>()
            .Name("Header")
            .Description("The header link of the navigation")
            .Resolve(ctx => ctx.Source.Header);

            Field <ListGraphType <NavigationLinkGraphType>, IList <NavigationLink> >()
            .Name("Links")
            .Description("The links in the navigation")
            .Resolve(ctx => ctx.Source.Links);

            Field <ListGraphType <SubNavigationGraphType>, IList <SubNavigation> >()
            .Name("SubNavigations")
            .Description("The embedded sub-navigations")
            .Resolve(ctx => ctx.Source.SubNavigations);

            #region Meta-fields

            Field <MetaFieldGraphType, MetaField>()
            .Name("MetaField")
            .Description("Connection to a specific meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("namespace", "Namespace of the meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("name", "Name of the meta-field")
            .ResolveAsync(async ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var result = await metaFieldService.GetBySearchAsync(
                    ctx.Source.Id,
                    ctx.GetArgument <string>("namespace"),
                    ctx.GetArgument <string>("name"));

                return(result.FirstOrDefault());
            });

            Field <ListGraphType <MetaFieldGraphType>, IList <MetaField> >()
            .Name("MetaFields")
            .Description("Connection to a all meta-fields")
            .ResolveAsync(ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, IList <MetaField> >("MetaField.LookupByParentIdsAsync", metaFieldLookupService.LookupByParentIdsAsync);
                return(loader.LoadAsync(ctx.Source.Id));
            });

            #endregion Meta-fields
        }
Ejemplo n.º 5
0
        public ProductVariantGraphType(
            IDataLoaderContextAccessor dataLoaderContextAccessor,
            IMetaFieldServiceProvider metaFieldServiceProvider,
            IMetaFieldService metaFieldService,
            IMetaFieldLookupService metaFieldLookupService,
            IMappingService mappingService
            )
        {
            Name = "ProductVariant";

            Field <StringGraphType, string>()
            .Name("Id")
            .Description("Globally unique identifier, eg: gid://ProductVariant/1000")
            .Resolve(ctx => ctx.Source.Id);

            Field <StringGraphType, string>()
            .Name("ProductId")
            .Description("Globally unique identifier of the parent product")
            .Resolve(ctx => ctx.Source.ProductId);

            Field <StringGraphType, string>()
            .Name("Title")
            .Description("The title of the product variant")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(ctx.Source.Titles
                       .FirstOrDefault(x => x.LanguageCode == userContext.LanguageCode)
                       ?.Value);
            });

            Field <StringGraphType, string>()
            .Name("Sku")
            .Description("The stock keeping unit of the product variant")
            .Resolve(ctx => ctx.Source.Sku);

            Field <MoneyGraphType, NodaMoney.Money>()
            .Name("UnitPrice")
            .Description("The unit price of the product variant")
            .Resolve(ctx =>
            {
                var userContext = (StorefrontGraphUserContext)ctx.UserContext;

                return(mappingService
                       .Map <Proto.Types.Money, NodaMoney.Money>(
                           ctx.Source.UnitPrices.FirstOrDefault(p => p.CurrencyCode == userContext.CurrencyCode)));
            });

            Field <ListGraphType <ImageGraphType>, IList <Image> >()
            .Name("Images")
            .Description("The images of the product variant")
            .Resolve(ctx => ctx.Source.Images);

            Field <ImageGraphType, Image>()
            .Name("PrimaryImage")
            .Description("The primary image of the product variant")
            .Resolve(ctx => ctx.Source.Images.FirstOrDefault());

            #region Meta-fields

            Field <MetaFieldGraphType, MetaField>()
            .Name("MetaField")
            .Description("Connection to a specific meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("namespace", "Namespace of the meta-field")
            .Argument <NonNullGraphType <StringGraphType> >("name", "Name of the meta-field")
            .ResolveAsync(async ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var result = await metaFieldService.GetBySearchAsync(
                    ctx.Source.Id,
                    ctx.GetArgument <string>("namespace"),
                    ctx.GetArgument <string>("name"));

                return(result.FirstOrDefault());
            });

            Field <ListGraphType <MetaFieldGraphType>, IList <MetaField> >()
            .Name("MetaFields")
            .Description("Connection to a all meta-fields")
            .ResolveAsync(ctx =>
            {
                if (!metaFieldServiceProvider.IsEnabled)
                {
                    throw new ExecutionError("Meta-fields not supported.");
                }

                var loader = dataLoaderContextAccessor.Context
                             .GetOrAddBatchLoader <string, IList <MetaField> >("MetaField.LookupByParentIdsAsync", metaFieldLookupService.LookupByParentIdsAsync);
                return(loader.LoadAsync(ctx.Source.Id));
            });

            #endregion Meta-fields
        }