Browse Source

Finalized

pull/630/head
Sebastian 5 years ago
parent
commit
9fe052bd0d
  1. 133
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs
  2. 29
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/IGraphModel.cs
  3. 10
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs
  4. 9
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppMutationsGraphType.cs
  5. 18
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AppQueriesGraphType.cs
  6. 3
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs
  7. 143
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Builder.cs
  8. 14
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentGraphType.cs
  9. 8
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentUnionGraphType.cs
  10. 6
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataFlatGraphType.cs
  11. 9
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataGraphType.cs
  12. 7
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/DataInputGraphType.cs
  13. 8
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedGraphType.cs
  14. 6
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/NestedInputGraphType.cs
  15. 16
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldInputVisitor.cs
  16. 16
      backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/GraphQLFieldVisitor.cs
  17. 7
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs

133
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<SchemaInfo, ContentGraphType> contentTypes = new Dictionary<SchemaInfo, ContentGraphType>(ReferenceEqualityComparer.Instance);
private readonly Dictionary<SchemaInfo, ContentResultGraphType> contentResultTypes = new Dictionary<SchemaInfo, ContentResultGraphType>(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<JsonBoolean, bool>(x => x.Value);
ValueConverter.Register<JsonNumber, double>(x => x.Value);
ValueConverter.Register<JsonString, string>(x => x.Value);
ValueConverter.Register<JsonString, DateTimeOffset>(x => DateTimeOffset.Parse(x.Value, CultureInfo.InvariantCulture));
ValueConverter.Register<string, DomainId>(DomainId.Create);
}
public GraphQLTypeFactory TypeFactory
{
get { return typeFactory; }
}
public GraphQLModel(IAppEntity app, IEnumerable<ISchemaEntity> 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<SchemaInfo> allSchemas)
{
foreach (var schemaInfo in allSchemas)
{
var contentType = new ContentGraphType(schemaInfo);
contentTypes[schemaInfo] = contentType;
contentResultTypes[schemaInfo] = new ContentResultGraphType(contentType, schemaInfo);
}
}
private void InitializeContentTypes(List<SchemaInfo> 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<SchemaInfo> 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<KeyValuePair<SchemaInfo, ContentGraphType>> GetAllContentTypes()
{
return contentTypes;
schema = new Builder(app, typeFactory).BuildSchema(schemas);
}
public async Task<(object Data, object[]? Errors)> ExecuteAsync(GraphQLExecutionContext context, GraphQLQuery query)

29
backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/IGraphModel.cs

@ -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);
}
}

10
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<ListGraphType<NonNullGraphType<StringGraphType>>>);
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<AssetType>();
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);

9
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<SchemaInfo> schemas)
public AppMutationsGraphType(Builder builder, IEnumerable<SchemaInfo> 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
{

18
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<SchemaInfo> schemaInfos)
public AppQueriesGraphType(Builder builder, IEnumerable<SchemaInfo> 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
{

3
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

143
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<SchemaInfo, ContentGraphType> contentTypes = new Dictionary<SchemaInfo, ContentGraphType>(ReferenceEqualityComparer.Instance);
private readonly Dictionary<SchemaInfo, ContentResultGraphType> contentResultTypes = new Dictionary<SchemaInfo, ContentResultGraphType>(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<JsonBoolean, bool>(x => x.Value);
ValueConverter.Register<JsonNumber, double>(x => x.Value);
ValueConverter.Register<JsonString, string>(x => x.Value);
ValueConverter.Register<JsonString, DateTimeOffset>(x => DateTimeOffset.Parse(x.Value, CultureInfo.InvariantCulture));
ValueConverter.Register<string, DomainId>(DomainId.Create);
ValueConverter.Register<string, Status>(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<ISchemaEntity> 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<KeyValuePair<SchemaInfo, ContentGraphType>> GetAllContentTypes()
{
return contentTypes;
}
}
}

14
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<SchemaInfo> all)
public void Initialize(Builder builder, SchemaInfo schemaInfo, IEnumerable<SchemaInfo> 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
{

8
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<DomainId, IObjectGraphType> types = new Dictionary<DomainId, IObjectGraphType>();
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;
}

6
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<FlatContentData>
internal sealed class DataFlatGraphType : ObjectGraphType<FlatContentData>
{
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)
{

9
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<ContentData>
{
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);
}
}

7
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);
}
}

8
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<JsonObject>
internal sealed class NestedGraphType : ObjectGraphType<JsonObject>
{
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);
}
}

6
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);
}
}

16
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<IGraphType?, FieldInfo>
internal sealed class GraphQLFieldInputVisitor : IFieldVisitor<IGraphType?, FieldInfo>
{
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<AssetsFieldProperties> field, FieldInfo args)
{
return AllTypes.References;
return AllTypes.Strings;
}
public IGraphType? Visit(IField<BooleanFieldProperties> field, FieldInfo args)
@ -62,7 +62,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public IGraphType? Visit(IField<ReferencesFieldProperties> field, FieldInfo args)
{
return AllTypes.Json;
return AllTypes.Strings;
}
public IGraphType? Visit(IField<StringFieldProperties> field, FieldInfo args)
@ -72,7 +72,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public IGraphType? Visit(IField<TagsFieldProperties> field, FieldInfo args)
{
return AllTypes.Tags;
return AllTypes.Strings;
}
public IGraphType? Visit(IField<UIFieldProperties> field, FieldInfo args)

16
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<AssetsFieldProperties> field, FieldInfo args)
{
return (model.TypeFactory.AssetsList, Assets, null);
return (builder.TypeFactory.AssetsList, Assets, null);
}
public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField<BooleanFieldProperties> field, FieldInfo args)
@ -92,7 +92,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField<TagsFieldProperties> field, FieldInfo args)
{
return (AllTypes.Tags, Noop, null);
return (AllTypes.Strings, Noop, null);
}
public (IGraphType?, IFieldResolver?, QueryArguments?) Visit(IField<UIFieldProperties> field, FieldInfo args)
@ -102,11 +102,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
private (IGraphType?, IFieldResolver?, QueryArguments?) ResolveReferences(IField<ReferencesFieldProperties> 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())
{

7
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: <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);
}
}
}

Loading…
Cancel
Save