Browse Source

Full query support.

pull/297/head
HII 8 years ago
parent
commit
8846097efe
  1. 10
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs
  2. 24
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs
  3. 18
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/InputFieldVisitor.cs
  4. 73
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/InputConverter.cs
  5. 32
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/JTokenConverter.cs
  6. 25
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/JTokenValue.cs
  7. 3
      src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/NoopGraphType.cs
  8. 1
      src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs
  9. 1
      src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
  10. 1
      src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj
  11. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs
  12. 12
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs
  13. 1
      tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj

10
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs

@ -18,6 +18,7 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Apps;
using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Assets;
using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types;
using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils;
using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using GraphQLSchema = GraphQL.Types.Schema; using GraphQLSchema = GraphQL.Types.Schema;
@ -53,6 +54,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
schemasById = schemas.ToDictionary(x => x.Id); schemasById = schemas.ToDictionary(x => x.Id);
graphQLSchema = BuildSchema(this); graphQLSchema = BuildSchema(this);
graphQLSchema.RegisterValueConverter(JTokenConverter.Instance);
InitializeContentTypes(); InitializeContentTypes();
} }
@ -178,13 +180,15 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
{ {
Guard.NotNull(context, nameof(context)); Guard.NotNull(context, nameof(context));
var inputs = InputConverter.ToInputs(query.Variables);
var result = await new DocumentExecuter().ExecuteAsync(options => var result = await new DocumentExecuter().ExecuteAsync(options =>
{ {
options.Inputs = query.Variables?.ToInputs() ?? new Inputs();
options.Query = query.Query;
options.OperationName = query.OperationName; options.OperationName = query.OperationName;
options.Schema = graphQLSchema;
options.UserContext = context; options.UserContext = context;
options.Schema = graphQLSchema;
options.Inputs = inputs;
options.Query = query.Query;
}).ConfigureAwait(false); }).ConfigureAwait(false);
return (result.Data, result.Errors?.Select(x => (object)new { x.Message, x.Locations }).ToArray()); return (result.Data, result.Errors?.Select(x => (object)new { x.Message, x.Locations }).ToArray());

24
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AllTypes.cs

@ -30,27 +30,21 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public static readonly IGraphType StatusType = new EnumerationGraphType<Status>(); public static readonly IGraphType StatusType = new EnumerationGraphType<Status>();
public static readonly IGraphType NonNullInt = new NonNullGraphType(new IntGraphType()); public static readonly IGraphType NonNullInt = new NonNullGraphType(Int);
public static readonly IGraphType NonNullGuid = new NonNullGraphType(new GuidGraphType()); public static readonly IGraphType NonNullGuid = new NonNullGraphType(Guid);
public static readonly IGraphType NonNullDate = new NonNullGraphType(new DateGraphType()); public static readonly IGraphType NonNullDate = new NonNullGraphType(Date);
public static readonly IGraphType NonNullFloat = new NonNullGraphType(new FloatGraphType()); public static readonly IGraphType NonNullFloat = new NonNullGraphType(Float);
public static readonly IGraphType NonNullString = new NonNullGraphType(new StringGraphType()); public static readonly IGraphType NonNullString = new NonNullGraphType(String);
public static readonly IGraphType NonNullBoolean = new NonNullGraphType(new BooleanGraphType()); public static readonly IGraphType NonNullBoolean = new NonNullGraphType(Boolean);
public static readonly IGraphType NonNullStatusType = new NonNullGraphType(new EnumerationGraphType<Status>()); public static readonly IGraphType NonNullStatusType = new NonNullGraphType(StatusType);
public static readonly IGraphType ListOfNonNullGuid = new ListGraphType(new NonNullGraphType(new GuidGraphType())); public static readonly IGraphType NoopArray = new NoopGraphType("Array");
public static readonly IGraphType ListOfNonNullString = new ListGraphType(new NonNullGraphType(new StringGraphType()));
public static readonly IGraphType NoopInt = new NoopGraphType("Int");
public static readonly IGraphType NoopGuid = new NoopGraphType("Guid");
public static readonly IGraphType NoopDate = new NoopGraphType("Date"); public static readonly IGraphType NoopDate = new NoopGraphType("Date");
@ -66,6 +60,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public static readonly IGraphType NoopGeolocation = new NoopGraphType("Geolocation"); public static readonly IGraphType NoopGeolocation = new NoopGraphType("Geolocation");
public static readonly IGraphType NoopReferences = new NoopGraphType("References");
public static readonly IGraphType CommandVersion = new CommandVersionGraphType(); public static readonly IGraphType CommandVersion = new CommandVersionGraphType();
public static readonly IGraphType GeolocationInput = new GeolocationInputGraphType(); public static readonly IGraphType GeolocationInput = new GeolocationInputGraphType();

18
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/InputFieldVisitor.cs

@ -20,27 +20,27 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public IGraphType Visit(IArrayField field) public IGraphType Visit(IArrayField field)
{ {
return AllTypes.NoopJson; return AllTypes.NoopArray;
} }
public IGraphType Visit(IField<AssetsFieldProperties> field) public IGraphType Visit(IField<AssetsFieldProperties> field)
{ {
return AllTypes.ListOfNonNullGuid; return AllTypes.NoopReferences;
} }
public IGraphType Visit(IField<BooleanFieldProperties> field) public IGraphType Visit(IField<BooleanFieldProperties> field)
{ {
return AllTypes.Boolean; return AllTypes.NoopBoolean;
} }
public IGraphType Visit(IField<DateTimeFieldProperties> field) public IGraphType Visit(IField<DateTimeFieldProperties> field)
{ {
return AllTypes.Date; return AllTypes.NoopDate;
} }
public IGraphType Visit(IField<GeolocationFieldProperties> field) public IGraphType Visit(IField<GeolocationFieldProperties> field)
{ {
return AllTypes.GeolocationInput; return AllTypes.NoopGeolocation;
} }
public IGraphType Visit(IField<JsonFieldProperties> field) public IGraphType Visit(IField<JsonFieldProperties> field)
@ -50,22 +50,22 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types
public IGraphType Visit(IField<NumberFieldProperties> field) public IGraphType Visit(IField<NumberFieldProperties> field)
{ {
return AllTypes.Float; return AllTypes.NoopFloat;
} }
public IGraphType Visit(IField<ReferencesFieldProperties> field) public IGraphType Visit(IField<ReferencesFieldProperties> field)
{ {
return AllTypes.ListOfNonNullGuid; return AllTypes.NoopReferences;
} }
public IGraphType Visit(IField<StringFieldProperties> field) public IGraphType Visit(IField<StringFieldProperties> field)
{ {
return AllTypes.String; return AllTypes.NoopString;
} }
public IGraphType Visit(IField<TagsFieldProperties> field) public IGraphType Visit(IField<TagsFieldProperties> field)
{ {
return AllTypes.ListOfNonNullString; return AllTypes.NoopTags;
} }
} }
} }

73
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/InputConverter.cs

@ -0,0 +1,73 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using GraphQL;
using Newtonsoft.Json.Linq;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils
{
public static class InputConverter
{
public static Inputs ToInputs(JObject input)
{
var result = new Inputs();
if (input != null)
{
foreach (var kvp in input)
{
result.Add(kvp.Key, GetValue(kvp.Value, 1));
}
}
return result;
}
private static object GetValue(object value, int level)
{
if (level == 3)
{
return value;
}
switch (value)
{
case JObject jObject:
{
var result = new Dictionary<string, object>();
foreach (var kvp in jObject)
{
result.Add(kvp.Key, GetValue(kvp.Value, level + 1));
}
return result;
}
case JArray jArray:
{
var result = new List<object>();
foreach (var item in jArray)
{
result.Add(GetValue(item, level + 1));
}
return result;
}
case JValue jValue:
{
return jValue.Value;
}
}
return value;
}
}
}

32
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/JTokenConverter.cs

@ -0,0 +1,32 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using GraphQL.Language.AST;
using GraphQL.Types;
using Newtonsoft.Json.Linq;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils
{
public sealed class JTokenConverter : IAstFromValueConverter
{
public static readonly JTokenConverter Instance = new JTokenConverter();
private JTokenConverter()
{
}
public IValue Convert(object value, IGraphType type)
{
return new JTokenValue(value as JToken);
}
public bool Matches(object value, IGraphType type)
{
return value is JToken;
}
}
}

25
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/JTokenValue.cs

@ -0,0 +1,25 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using GraphQL.Language.AST;
using Newtonsoft.Json.Linq;
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils
{
public sealed class JTokenValue : ValueNode<JToken>
{
public JTokenValue(JToken value)
{
Value = value;
}
protected override bool Equals(ValueNode<JToken> node)
{
return node.Value.Equals(Value);
}
}
}

3
src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Utils/NoopGraphType.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using GraphQL.Language.AST; using GraphQL.Language.AST;
using GraphQL.Types; using GraphQL.Types;
@ -30,7 +29,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Utils
public override object ParseLiteral(IValue value) public override object ParseLiteral(IValue value)
{ {
throw new NotSupportedException(); return value.Value;
} }
} }
} }

1
src/Squidex.Domain.Apps.Entities/Schemas/SchemaGrain.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Domain.Apps.Entities.Schemas.Commands;

1
src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj

@ -14,6 +14,7 @@
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" /> <ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="GraphQL" Version="2.0.0-alpha-912" />
<PackageReference Include="Microsoft.Orleans.OrleansCodeGenerator.Build" Version="2.0.0-ci.20180515.5" /> <PackageReference Include="Microsoft.Orleans.OrleansCodeGenerator.Build" Version="2.0.0-ci.20180515.5" />
<PackageReference Include="Microsoft.Orleans.Core" Version="2.0.0-ci.20180515.5" /> <PackageReference Include="Microsoft.Orleans.Core" Version="2.0.0-ci.20180515.5" />
<PackageReference Include="NodaTime" Version="2.2.5" /> <PackageReference Include="NodaTime" Version="2.2.5" />

1
src/Squidex.Domain.Apps.Events/Squidex.Domain.Apps.Events.csproj

@ -11,7 +11,6 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" /> <ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="GraphQL" Version="0.17.3" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.1" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.1" />
<PackageReference Include="NodaTime" Version="2.2.5" /> <PackageReference Include="NodaTime" Version="2.2.5" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" />

2
tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs

@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
public GraphQLMutationTests() public GraphQLMutationTests()
{ {
content = CreateContent(contentId, Guid.Empty, Guid.Empty, null, true); content = CreateContent(contentId, Guid.NewGuid(), Guid.NewGuid(), null);
A.CallTo(() => commandBus.PublishAsync(A<ICommand>.Ignored)) A.CallTo(() => commandBus.PublishAsync(A<ICommand>.Ignored))
.Returns(commandContext); .Returns(commandContext);

12
tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs

@ -96,7 +96,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
sut = new CachingGraphQLService(cache, appProvider, assetRepository, commandBus, contentQuery, new FakeUrlGenerator()); sut = new CachingGraphQLService(cache, appProvider, assetRepository, commandBus, contentQuery, new FakeUrlGenerator());
} }
protected static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null, bool noJson = false) protected static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null)
{ {
var now = DateTime.UtcNow.ToInstant(); var now = DateTime.UtcNow.ToInstant();
@ -126,6 +126,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
.AddField("my-geolocation", .AddField("my-geolocation",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 }))) .AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 })))
.AddField("my-json",
new ContentFieldData()
.AddValue("iv", JToken.FromObject(new { value = 1 })))
.AddField("my-array", .AddField("my-array",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray( .AddValue("iv", new JArray(
@ -136,13 +139,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL
new JProperty("nested-boolean", false), new JProperty("nested-boolean", false),
new JProperty("nested-number", 2))))); new JProperty("nested-number", 2)))));
if (!noJson)
{
data.AddField("my-json",
new ContentFieldData()
.AddValue("iv", JToken.FromObject(new { value = 1 })));
}
var content = new ContentEntity var content = new ContentEntity
{ {
Id = id, Id = id,

1
tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj

@ -21,6 +21,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="FakeItEasy" Version="4.5.1" /> <PackageReference Include="FakeItEasy" Version="4.5.1" />
<PackageReference Include="FluentAssertions" Version="4.19.4" /> <PackageReference Include="FluentAssertions" Version="4.19.4" />
<PackageReference Include="GraphQL" Version="2.0.0-alpha-912" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="MongoDB.Driver" Version="2.5.1" /> <PackageReference Include="MongoDB.Driver" Version="2.5.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" />

Loading…
Cancel
Save