diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs index 177cfcb0d..833f42278 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs @@ -5,22 +5,14 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Threading.Tasks; using GraphQL; -using GraphQL.Resolvers; -using GraphQL.Types; -using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types; -using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; -using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Primitives; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json.Objects; using Squidex.Log; using GraphQLSchema = GraphQL.Types.Schema; @@ -29,137 +21,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL public sealed class GraphQLModel { private static readonly IDocumentExecuter Executor = new DocumentExecuter(); - private readonly Dictionary contentTypes = new Dictionary(ReferenceEqualityComparer.Instance); - private readonly Dictionary contentResultTypes = new Dictionary(ReferenceEqualityComparer.Instance); private readonly GraphQLSchema schema; - private readonly GraphQLTypeFactory typeFactory; private readonly ISemanticLog log; -#pragma warning disable IDE0044 // Add readonly modifier - private GraphQLFieldVisitor fieldVisitor; - private GraphQLFieldInputVisitor fieldInputVisitor; - private PartitionResolver partitionResolver; -#pragma warning restore IDE0044 // Add readonly modifier - - static GraphQLModel() - { - ValueConverter.Register(x => x.Value); - ValueConverter.Register(x => x.Value); - ValueConverter.Register(x => x.Value); - ValueConverter.Register(x => DateTimeOffset.Parse(x.Value, CultureInfo.InvariantCulture)); - ValueConverter.Register(DomainId.Create); - } - - public GraphQLTypeFactory TypeFactory - { - get { return typeFactory; } - } public GraphQLModel(IAppEntity app, IEnumerable schemas, GraphQLTypeFactory typeFactory, ISemanticLog log) { - this.typeFactory = typeFactory; - this.log = log; - partitionResolver = app.PartitionResolver(); - - fieldVisitor = new GraphQLFieldVisitor(this); - fieldInputVisitor = new GraphQLFieldInputVisitor(this); - - var allSchemas = schemas.Where(x => x.SchemaDef.IsPublished).Select(SchemaInfo.Build).ToList(); - - BuildSchemas(allSchemas); - - schema = BuildSchema(allSchemas); - schema.RegisterValueConverter(JsonConverter.Instance); - schema.RegisterValueConverter(InstantConverter.Instance); - - InitializeContentTypes(allSchemas); - - partitionResolver = null!; - - fieldVisitor = null!; - fieldInputVisitor = null!; - } - - private void BuildSchemas(List allSchemas) - { - foreach (var schemaInfo in allSchemas) - { - var contentType = new ContentGraphType(schemaInfo); - - contentTypes[schemaInfo] = contentType; - contentResultTypes[schemaInfo] = new ContentResultGraphType(contentType, schemaInfo); - } - } - - private void InitializeContentTypes(List allSchemas) - { - foreach (var (schemaInfo, contentType) in contentTypes) - { - contentType.Initialize(this, schemaInfo, allSchemas); - } - - foreach (var contentType in contentTypes.Values) - { - schema.RegisterType(contentType); - } - - schema.Initialize(); - schema.CleanupMetadata(); - } - - private GraphQLSchema BuildSchema(List schemas) - { - var newSchema = new GraphQLSchema - { - Query = new AppQueriesGraphType(this, schemas) - }; - - newSchema.RegisterType(ContentInterfaceGraphType.Instance); - - var schemasWithFields = schemas.Where(x => x.Fields.Count > 0); - - if (schemasWithFields.Any()) - { - newSchema.Mutation = new AppMutationsGraphType(this, schemasWithFields); - } - - return newSchema; - } - - internal IFieldPartitioning ResolvePartition(Partitioning key) - { - return partitionResolver(key); - } - - internal IGraphType? GetInputGraphType(FieldInfo fieldInfo) - { - return fieldInfo.Field.Accept(fieldInputVisitor, fieldInfo); - } - - internal (IGraphType?, IFieldResolver?, QueryArguments?) GetGraphType(FieldInfo fieldInfo) - { - return fieldInfo.Field.Accept(fieldVisitor, fieldInfo); - } - - internal IObjectGraphType? GetContentType(DomainId schemaId) - { - return contentTypes.FirstOrDefault(x => x.Key.Schema.Id == schemaId).Value; - } - - internal IObjectGraphType GetContentType(SchemaInfo schemaId) - { - return contentTypes.GetOrDefault(schemaId); - } - - internal IObjectGraphType GetContentResultType(SchemaInfo schemaId) - { - return contentResultTypes.GetOrDefault(schemaId); - } - - internal IEnumerable> GetAllContentTypes() - { - return contentTypes; + schema = new Builder(app, typeFactory).BuildSchema(schemas); } public async Task<(object Data, object[]? Errors)> ExecuteAsync(GraphQLExecutionContext context, GraphQLQuery query) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/IGraphModel.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/IGraphModel.cs deleted file mode 100644 index 73e978fe0..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/IGraphModel.cs +++ /dev/null @@ -1,29 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschränkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using GraphQL.Types; -using Squidex.Domain.Apps.Core; -using Squidex.Domain.Apps.Core.Schemas; -using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types; -using Squidex.Domain.Apps.Entities.Schemas; -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Entities.Contents.GraphQL -{ - public interface IGraphModel - { - IFieldPartitioning ResolvePartition(Partitioning key); - - GraphQLTypeFactory TypeFactory { get; } - - IGraphType GetContentType(DomainId schemaId); - - IGraphType? GetInputGraphType(ISchemaEntity schema, IField field, string fieldName); - - (IGraphType?, ValueResolver?, QueryArguments?) GetGraphType(ISchemaEntity schema, IField field, string fieldName); - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs index 44d99e22d..9070b63b8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs @@ -16,8 +16,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { public static readonly Type None = typeof(NoopGraphType); - public static readonly Type NonNullTagsType = typeof(NonNullGraphType>>); - public static readonly IGraphType Int = new IntGraphType(); public static readonly IGraphType DomainId = new StringGraphType(); @@ -28,20 +26,18 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public static readonly IGraphType Date = new InstantGraphType(); - public static readonly IGraphType Tags = new ListGraphType(new NonNullGraphType(new StringGraphType())); - public static readonly IGraphType Json = new JsonGraphType(); public static readonly IGraphType Float = new FloatGraphType(); public static readonly IGraphType String = new StringGraphType(); + public static readonly IGraphType Strings = new ListGraphType(new NonNullGraphType(new StringGraphType())); + public static readonly IGraphType Boolean = new BooleanGraphType(); public static readonly IGraphType AssetType = new EnumerationGraphType(); - public static readonly IGraphType References = new ListGraphType(new NonNullGraphType(new StringGraphType())); - public static readonly IGraphType NonNullInt = new NonNullGraphType(Int); public static readonly IGraphType NonNullDomainId = new NonNullGraphType(DomainId); @@ -56,6 +52,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public static readonly IGraphType NonNullString = new NonNullGraphType(String); + public static readonly IGraphType NonNullStrings = new NonNullGraphType(Strings); + public static readonly IGraphType NonNullBoolean = new NonNullGraphType(Boolean); public static readonly IGraphType NonNullAssetType = new NonNullGraphType(AssetType); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppMutationsGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppMutationsGraphType.cs index 17f4fc9b6..4f2924886 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppMutationsGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppMutationsGraphType.cs @@ -10,19 +10,18 @@ using System.Linq; using GraphQL.Types; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils; -using Squidex.Domain.Apps.Entities.Schemas; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { - public sealed class AppMutationsGraphType : ObjectGraphType + internal sealed class AppMutationsGraphType : ObjectGraphType { - public AppMutationsGraphType(GraphQLModel model, IEnumerable schemas) + public AppMutationsGraphType(Builder builder, IEnumerable schemas) { foreach (var schemaInfo in schemas.Where(x => x.Fields.Count > 0)) { - var contentType = model.GetContentType(schemaInfo); + var contentType = builder.GetContentType(schemaInfo); - var inputType = new DataInputGraphType(model, schemaInfo); + var inputType = new DataInputGraphType(builder, schemaInfo); AddField(new FieldType { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppQueriesGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppQueriesGraphType.cs index 813f9d14f..e43e36059 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppQueriesGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppQueriesGraphType.cs @@ -11,20 +11,20 @@ using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { - public sealed class AppQueriesGraphType : ObjectGraphType + internal sealed class AppQueriesGraphType : ObjectGraphType { - public AppQueriesGraphType(GraphQLModel model, IEnumerable schemaInfos) + public AppQueriesGraphType(Builder builder, IEnumerable schemaInfos) { - AddField(model.TypeFactory.FindAsset); - AddField(model.TypeFactory.QueryAssets); - AddField(model.TypeFactory.QueryAssetsWithTotal); + AddField(builder.TypeFactory.FindAsset); + AddField(builder.TypeFactory.QueryAssets); + AddField(builder.TypeFactory.QueryAssetsWithTotal); foreach (var schemaInfo in schemaInfos) { - var contentType = model.GetContentType(schemaInfo); + var contentType = builder.GetContentType(schemaInfo); AddContentFind(schemaInfo, contentType); - AddContentQueries(model, schemaInfo, contentType); + AddContentQueries(builder, schemaInfo, contentType); } Description = "The app queries."; @@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types }).WithSchemaId(schemaInfo); } - private void AddContentQueries(GraphQLModel model, SchemaInfo schemaInfo, IGraphType contentType) + private void AddContentQueries(Builder builder, SchemaInfo schemaInfo, IGraphType contentType) { AddField(new FieldType { @@ -53,7 +53,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types Description = $"Query {schemaInfo.DisplayName} content items." }).WithSchemaId(schemaInfo); - var resultType = model.GetContentResultType(schemaInfo); + var resultType = builder.GetContentResultType(schemaInfo); AddField(new FieldType { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs index ba2b08185..656923e68 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs @@ -196,10 +196,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Assets AddField(new FieldType { Name = "tags", - ResolvedType = null, + ResolvedType = AllTypes.NonNullStrings, Resolver = Resolve(x => x.TagNames), Description = "The asset tags.", - Type = AllTypes.NonNullTagsType }); AddField(new FieldType diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Builder.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Builder.cs new file mode 100644 index 000000000..63a175bb8 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Builder.cs @@ -0,0 +1,143 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using GraphQL; +using GraphQL.Resolvers; +using GraphQL.Types; +using Squidex.Domain.Apps.Core; +using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Entities.Apps; +using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; +using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Primitives; +using Squidex.Domain.Apps.Entities.Schemas; +using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; +using GraphQLSchema = GraphQL.Types.Schema; + +namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types +{ + internal sealed class Builder + { + private readonly Dictionary contentTypes = new Dictionary(ReferenceEqualityComparer.Instance); + private readonly Dictionary contentResultTypes = new Dictionary(ReferenceEqualityComparer.Instance); + private readonly GraphQLTypeFactory typeFactory; + private readonly GraphQLFieldVisitor fieldVisitor; + private readonly GraphQLFieldInputVisitor fieldInputVisitor; + private readonly PartitionResolver partitionResolver; + + public GraphQLTypeFactory TypeFactory + { + get { return typeFactory; } + } + + static Builder() + { + ValueConverter.Register(x => x.Value); + ValueConverter.Register(x => x.Value); + ValueConverter.Register(x => x.Value); + ValueConverter.Register(x => DateTimeOffset.Parse(x.Value, CultureInfo.InvariantCulture)); + ValueConverter.Register(DomainId.Create); + ValueConverter.Register(x => new Status(x)); + } + + public Builder(IAppEntity app, GraphQLTypeFactory typeFactory) + { + this.typeFactory = typeFactory; + + partitionResolver = app.PartitionResolver(); + + fieldVisitor = new GraphQLFieldVisitor(this); + fieldInputVisitor = new GraphQLFieldInputVisitor(this); + } + + public GraphQLSchema BuildSchema(IEnumerable schemas) + { + var schemaInfos = + schemas + .Where(x => x.SchemaDef.IsPublished).Select(SchemaInfo.Build) + .Where(x => x.Fields.Count > 0) + .ToList(); + + foreach (var schemaInfo in schemaInfos) + { + var contentType = new ContentGraphType(schemaInfo); + + contentTypes[schemaInfo] = contentType; + contentResultTypes[schemaInfo] = new ContentResultGraphType(contentType, schemaInfo); + } + + var newSchema = new GraphQLSchema + { + Query = new AppQueriesGraphType(this, schemaInfos) + }; + + newSchema.RegisterValueConverter(JsonConverter.Instance); + newSchema.RegisterValueConverter(InstantConverter.Instance); + + newSchema.RegisterType(ContentInterfaceGraphType.Instance); + + if (schemas.Any()) + { + newSchema.Mutation = new AppMutationsGraphType(this, schemaInfos); + } + + foreach (var (schemaInfo, contentType) in contentTypes) + { + contentType.Initialize(this, schemaInfo, schemaInfos); + } + + foreach (var contentType in contentTypes.Values) + { + newSchema.RegisterType(contentType); + } + + newSchema.Initialize(); + newSchema.CleanupMetadata(); + + return newSchema; + } + + public IFieldPartitioning ResolvePartition(Partitioning key) + { + return partitionResolver(key); + } + + public IGraphType? GetInputGraphType(FieldInfo fieldInfo) + { + return fieldInfo.Field.Accept(fieldInputVisitor, fieldInfo); + } + + public (IGraphType?, IFieldResolver?, QueryArguments?) GetGraphType(FieldInfo fieldInfo) + { + return fieldInfo.Field.Accept(fieldVisitor, fieldInfo); + } + + public IObjectGraphType? GetContentType(DomainId schemaId) + { + return contentTypes.FirstOrDefault(x => x.Key.Schema.Id == schemaId).Value; + } + + public IObjectGraphType GetContentType(SchemaInfo schemaId) + { + return contentTypes.GetOrDefault(schemaId); + } + + public IObjectGraphType GetContentResultType(SchemaInfo schemaId) + { + return contentResultTypes.GetOrDefault(schemaId); + } + + public IEnumerable> GetAllContentTypes() + { + return contentTypes; + } + } +} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs index 6fac327cd..5647b4810 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs @@ -44,7 +44,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents return value is IContentEntity content && content.SchemaId?.Id == schemaId; } - public void Initialize(GraphQLModel model, SchemaInfo schemaInfo, IEnumerable all) + public void Initialize(Builder builder, SchemaInfo schemaInfo, IEnumerable all) { AddField(new FieldType { @@ -54,7 +54,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Description = $"The url to the content." }); - var contentDataType = new DataGraphType(model, schemaInfo); + var contentDataType = new DataGraphType(builder, schemaInfo); if (contentDataType.Fields.Any()) { @@ -67,7 +67,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents }); } - var contentDataTypeFlat = new DataFlatGraphType(model, schemaInfo); + var contentDataTypeFlat = new DataFlatGraphType(builder, schemaInfo); if (contentDataTypeFlat.Fields.Any()) { @@ -82,13 +82,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents foreach (var other in all.Where(x => References(x, schemaInfo))) { - AddReferencingQueries(model, other); + AddReferencingQueries(builder, other); } } - private void AddReferencingQueries(GraphQLModel model, SchemaInfo referencingSchemaInfo) + private void AddReferencingQueries(Builder builder, SchemaInfo referencingSchemaInfo) { - var contentType = model.GetContentType(referencingSchemaInfo); + var contentType = builder.GetContentType(referencingSchemaInfo); AddField(new FieldType { @@ -99,7 +99,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Description = $"Query {referencingSchemaInfo.DisplayName} content items." }).WithSchemaId(referencingSchemaInfo); - var contentResultsTyp = model.GetContentResultType(referencingSchemaInfo); + var contentResultsTyp = builder.GetContentResultType(referencingSchemaInfo); AddField(new FieldType { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentUnionGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentUnionGraphType.cs index 03a459a91..a8de9e198 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentUnionGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentUnionGraphType.cs @@ -13,11 +13,11 @@ using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { - public sealed class ContentUnionGraphType : UnionGraphType + internal sealed class ContentUnionGraphType : UnionGraphType { private readonly Dictionary types = new Dictionary(); - public ContentUnionGraphType(GraphQLModel model, FieldInfo fieldInfo, ReferencesFieldProperties properties) + public ContentUnionGraphType(Builder builder, FieldInfo fieldInfo, ReferencesFieldProperties properties) { Name = fieldInfo.UnionType; @@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { foreach (var schemaId in properties.SchemaIds) { - var contentType = model.GetContentType(schemaId); + var contentType = builder.GetContentType(schemaId); if (contentType != null) { @@ -35,7 +35,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents } else { - foreach (var (key, value) in model.GetAllContentTypes()) + foreach (var (key, value) in builder.GetAllContentTypes()) { types[key.Schema.Id] = value; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs index d646059d2..13052c015 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs @@ -10,15 +10,15 @@ using Squidex.Domain.Apps.Core.Contents; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { - public sealed class DataFlatGraphType : ObjectGraphType + internal sealed class DataFlatGraphType : ObjectGraphType { - public DataFlatGraphType(GraphQLModel model, SchemaInfo schemaInfo) + public DataFlatGraphType(Builder builder, SchemaInfo schemaInfo) { Name = schemaInfo.DataFlatType; foreach (var fieldInfo in schemaInfo.Fields) { - var (resolvedType, resolver, args) = model.GetGraphType(fieldInfo); + var (resolvedType, resolver, args) = builder.GetGraphType(fieldInfo); if (resolver != null) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs index 42042efc1..4b868022f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs @@ -14,13 +14,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { internal sealed class DataGraphType : ObjectGraphType { - public DataGraphType(GraphQLModel model, SchemaInfo schemaInfo) + public DataGraphType(Builder builder, SchemaInfo schemaInfo) { Name = schemaInfo.DataType; foreach (var fieldInfo in schemaInfo.Fields) { - var (resolvedType, resolver, args) = model.GetGraphType(fieldInfo); + var (resolvedType, resolver, args) = builder.GetGraphType(fieldInfo); if (resolver != null) { @@ -29,7 +29,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Name = fieldInfo.TypeName }; - var partitioning = model.ResolvePartition(((RootField)fieldInfo.Field).Partitioning); + var partitioning = builder.ResolvePartition(((RootField)fieldInfo.Field).Partitioning); foreach (var partitionKey in partitioning.AllKeys) { @@ -49,8 +49,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { Name = fieldInfo.FieldName, ResolvedType = fieldGraphType, - Resolver = ContentResolvers.Field, - Description = $"The {fieldInfo.DisplayName} field." + Resolver = ContentResolvers.Field }).WithSourceName(fieldInfo); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs index 95811800b..1fa493d5e 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs @@ -13,13 +13,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { internal sealed class DataInputGraphType : InputObjectGraphType { - public DataInputGraphType(GraphQLModel model, SchemaInfo schemaInfo) + public DataInputGraphType(Builder builder, SchemaInfo schemaInfo) { Name = schemaInfo.DataInputType; foreach (var fieldInfo in schemaInfo.Fields) { - var resolvedType = model.GetInputGraphType(fieldInfo); + var resolvedType = builder.GetInputGraphType(fieldInfo); if (resolvedType != null) { @@ -28,7 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Name = fieldInfo.LocalizedInputType }; - var partitioning = model.ResolvePartition(((RootField)fieldInfo.Field).Partitioning); + var partitioning = builder.ResolvePartition(((RootField)fieldInfo.Field).Partitioning); foreach (var partitionKey in partitioning.AllKeys) { @@ -48,7 +48,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Name = fieldInfo.FieldName, ResolvedType = fieldGraphType, Resolver = null, - Description = $"The {fieldInfo.DisplayName} field." }).WithSourceName(fieldInfo); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs index 28b3e4445..280878321 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs @@ -10,15 +10,15 @@ using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { - public sealed class NestedGraphType : ObjectGraphType + internal sealed class NestedGraphType : ObjectGraphType { - public NestedGraphType(GraphQLModel model, FieldInfo fieldInfo) + public NestedGraphType(Builder builder, FieldInfo fieldInfo) { Name = fieldInfo.NestedType; foreach (var nestedFieldInfo in fieldInfo.Fields) { - var (resolvedType, resolver, args) = model.GetGraphType(nestedFieldInfo); + var (resolvedType, resolver, args) = builder.GetGraphType(nestedFieldInfo); if (resolvedType != null && resolver != null) { @@ -28,7 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Arguments = args, ResolvedType = resolvedType, Resolver = resolver, - Description = $"The {fieldInfo.DisplayName}/{nestedFieldInfo.DisplayName} nested field." + Description = nestedFieldInfo.Field.RawProperties.Hints }).WithSourceName(nestedFieldInfo); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs index 28834bcc7..1abd5d330 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs @@ -11,13 +11,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents { internal sealed class NestedInputGraphType : InputObjectGraphType { - public NestedInputGraphType(GraphQLModel model, FieldInfo fieldInfo) + public NestedInputGraphType(Builder builder, FieldInfo fieldInfo) { Name = fieldInfo.NestedInputType; foreach (var nestedFieldInfo in fieldInfo.Fields) { - var resolvedType = model.GetInputGraphType(nestedFieldInfo); + var resolvedType = builder.GetInputGraphType(nestedFieldInfo); if (resolvedType != null) { @@ -26,7 +26,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents Name = nestedFieldInfo.FieldName, ResolvedType = resolvedType, Resolver = null, - Description = $"The {fieldInfo.DisplayName}/{nestedFieldInfo.DisplayName} nested field." + Description = nestedFieldInfo.Field.RawProperties.Hints }).WithSourceName(nestedFieldInfo); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldInputVisitor.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldInputVisitor.cs index 72ba24d81..a628db17b 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldInputVisitor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldInputVisitor.cs @@ -11,13 +11,13 @@ using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { - public sealed class GraphQLFieldInputVisitor : IFieldVisitor + internal sealed class GraphQLFieldInputVisitor : IFieldVisitor { - private readonly GraphQLModel model; + private readonly Builder builder; - public GraphQLFieldInputVisitor(GraphQLModel model) + public GraphQLFieldInputVisitor(Builder builder) { - this.model = model; + this.builder = builder; } public IGraphType? Visit(IArrayField field, FieldInfo args) @@ -25,14 +25,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types var schemaFieldType = new ListGraphType( new NonNullGraphType( - new NestedInputGraphType(model, args))); + new NestedInputGraphType(builder, args))); return schemaFieldType; } public IGraphType? Visit(IField field, FieldInfo args) { - return AllTypes.References; + return AllTypes.Strings; } public IGraphType? Visit(IField field, FieldInfo args) @@ -62,7 +62,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public IGraphType? Visit(IField field, FieldInfo args) { - return AllTypes.Json; + return AllTypes.Strings; } public IGraphType? Visit(IField field, FieldInfo args) @@ -72,7 +72,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public IGraphType? Visit(IField field, FieldInfo args) { - return AllTypes.Tags; + return AllTypes.Strings; } public IGraphType? Visit(IField field, FieldInfo args) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldVisitor.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldVisitor.cs index 31194a82b..678a844fb 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldVisitor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldVisitor.cs @@ -33,11 +33,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types return context.GetReferencedContentsAsync(value); }); - private readonly GraphQLModel model; + private readonly Builder builder; - public GraphQLFieldVisitor(GraphQLModel model) + public GraphQLFieldVisitor(Builder builder) { - this.model = model; + this.builder = builder; } public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IArrayField field, FieldInfo args) @@ -45,14 +45,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types var schemaFieldType = new ListGraphType( new NonNullGraphType( - new NestedGraphType(model, args))); + new NestedGraphType(builder, args))); return (schemaFieldType, Noop, null); } public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField field, FieldInfo args) { - return (model.TypeFactory.AssetsList, Assets, null); + return (builder.TypeFactory.AssetsList, Assets, null); } public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField field, FieldInfo args) @@ -92,7 +92,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField field, FieldInfo args) { - return (AllTypes.Tags, Noop, null); + return (AllTypes.Strings, Noop, null); } public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField field, FieldInfo args) @@ -102,11 +102,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types private (IGraphType?, IFieldResolver?, QueryArguments?) ResolveReferences(IField field, FieldInfo args) { - IGraphType? contentType = model.GetContentType(field.Properties.SingleId()); + IGraphType? contentType = builder.GetContentType(field.Properties.SingleId()); if (contentType == null) { - var union = new ContentUnionGraphType(model, args, field.Properties); + var union = new ContentUnionGraphType(builder, args, field.Properties); if (!union.PossibleTypes.Any()) { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs index 835c6f707..8e9dc39aa 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using FakeItEasy; using GraphQL; using GraphQL.NewtonsoftJson; +using GraphQL.Types; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NodaTime; @@ -38,6 +39,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL [Fact] public async Task Should_return_single_content_when_creating_content() { + var f = new FloatGraphType().ParseValue("12.0"); + var query = @" mutation { createMySchemaContent(data: , publish: true) { @@ -478,9 +481,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL { var data = TestContent.Data(content, schemaRefId1.Id, schemaRefId2.Id); - var json = JsonConvert.SerializeObject(data); + var json = JsonConvert.SerializeObject(data, Formatting.Indented); - return Regex.Replace(json, "\"([^\"]+)\":", x => x.Groups[1].Value + ":"); + return Regex.Replace(json, "\"([^\"]+)\":", x => x.Groups[1].Value + ":").Replace(".0", string.Empty); } } }