mirror of https://github.com/Squidex/squidex.git
9 changed files with 540 additions and 202 deletions
@ -0,0 +1,246 @@ |
|||||
|
// ==========================================================================
|
||||
|
// 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.Linq; |
||||
|
using GraphQL.Resolvers; |
||||
|
using GraphQL.Types; |
||||
|
using Squidex.Domain.Apps.Entities.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types |
||||
|
{ |
||||
|
public sealed class AppQueriesGraphType : ObjectGraphType |
||||
|
{ |
||||
|
public AppQueriesGraphType(IGraphQLContext ctx, IEnumerable<ISchemaEntity> schemas) |
||||
|
{ |
||||
|
var assetType = ctx.GetAssetType(); |
||||
|
|
||||
|
AddAssetFind(assetType); |
||||
|
AddAssetsQueries(assetType); |
||||
|
|
||||
|
foreach (var schema in schemas) |
||||
|
{ |
||||
|
var schemaName = schema.SchemaDef.Properties.Label.WithFallback(schema.SchemaDef.Name); |
||||
|
var schemaType = ctx.GetSchemaType(schema.Id); |
||||
|
|
||||
|
AddContentFind(schema, schemaType, schemaName); |
||||
|
AddContentQueries(ctx, schema, schemaType, schemaName); |
||||
|
} |
||||
|
|
||||
|
Description = "The app queries."; |
||||
|
} |
||||
|
|
||||
|
private void AddAssetFind(IGraphType assetType) |
||||
|
{ |
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "findAsset", |
||||
|
Arguments = CreateAssetFindArguments(), |
||||
|
ResolvedType = assetType, |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString())); |
||||
|
|
||||
|
return context.FindAssetAsync(contentId); |
||||
|
}), |
||||
|
Description = "Find an asset by id." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AddContentFind(ISchemaEntity schema, IGraphType schemaType, string schemaName) |
||||
|
{ |
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = $"find{schema.Name.ToPascalCase()}Content", |
||||
|
Arguments = CreateContentFindTypes(schemaName), |
||||
|
ResolvedType = schemaType, |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString())); |
||||
|
|
||||
|
return context.FindContentAsync(schema.Id, contentId); |
||||
|
}), |
||||
|
Description = $"Find an {schemaName} content by id." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AddAssetsQueries(IGraphType assetType) |
||||
|
{ |
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "queryAssets", |
||||
|
Arguments = CreateAssetQueryArguments(), |
||||
|
ResolvedType = new ListGraphType(new NonNullGraphType(assetType)), |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
|
||||
|
var argTop = c.GetArgument("top", 20); |
||||
|
var argSkip = c.GetArgument("skip", 0); |
||||
|
var argQuery = c.GetArgument("search", string.Empty); |
||||
|
|
||||
|
return context.QueryAssetsAsync(argQuery, argSkip, argTop); |
||||
|
}), |
||||
|
Description = "Query assets items." |
||||
|
}); |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "queryAssetsWithTotal", |
||||
|
Arguments = CreateAssetQueryArguments(), |
||||
|
ResolvedType = new AssetResultGraphType(assetType), |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
|
||||
|
var argTop = c.GetArgument("top", 20); |
||||
|
var argSkip = c.GetArgument("skip", 0); |
||||
|
var argQuery = c.GetArgument("search", string.Empty); |
||||
|
|
||||
|
return context.QueryAssetsAsync(argQuery, argSkip, argTop); |
||||
|
}), |
||||
|
Description = "Query assets items with total count." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AddContentQueries(IGraphQLContext ctx, ISchemaEntity schema, IGraphType schemaType, string schemaName) |
||||
|
{ |
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = $"query{schema.Name.ToPascalCase()}Contents", |
||||
|
Arguments = CreateContentQueryArguments(), |
||||
|
ResolvedType = new ListGraphType(new NonNullGraphType(schemaType)), |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
var contentQuery = BuildODataQuery(c); |
||||
|
|
||||
|
return context.QueryContentsAsync(schema.Id.ToString(), contentQuery); |
||||
|
}), |
||||
|
Description = $"Query {schemaName} content items." |
||||
|
}); |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = $"query{schema.Name.ToPascalCase()}ContentsWithTotal", |
||||
|
Arguments = CreateContentQueryArguments(), |
||||
|
ResolvedType = new ContentResultGraphType(ctx, schema, schemaName), |
||||
|
Resolver = new FuncFieldResolver<object>(c => |
||||
|
{ |
||||
|
var context = (GraphQLQueryContext)c.UserContext; |
||||
|
var contentQuery = BuildODataQuery(c); |
||||
|
|
||||
|
return context.QueryContentsAsync(schema.Id.ToString(), contentQuery); |
||||
|
}), |
||||
|
Description = $"Query {schemaName} content items with total count." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static QueryArguments CreateAssetFindArguments() |
||||
|
{ |
||||
|
return new QueryArguments |
||||
|
{ |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "id", |
||||
|
Description = "The id of the asset.", |
||||
|
DefaultValue = string.Empty |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static QueryArguments CreateContentFindTypes(string schemaName) |
||||
|
{ |
||||
|
return new QueryArguments |
||||
|
{ |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "id", |
||||
|
Description = $"The id of the {schemaName} content.", |
||||
|
DefaultValue = string.Empty |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static QueryArguments CreateAssetQueryArguments() |
||||
|
{ |
||||
|
return new QueryArguments |
||||
|
{ |
||||
|
new QueryArgument(typeof(IntGraphType)) |
||||
|
{ |
||||
|
Name = "top", |
||||
|
Description = "Optional number of assets to take.", |
||||
|
DefaultValue = 20 |
||||
|
}, |
||||
|
new QueryArgument(typeof(IntGraphType)) |
||||
|
{ |
||||
|
Name = "skip", |
||||
|
Description = "Optional number of assets to skip.", |
||||
|
DefaultValue = 0 |
||||
|
}, |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "search", |
||||
|
Description = "Optional query.", |
||||
|
DefaultValue = string.Empty |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static QueryArguments CreateContentQueryArguments() |
||||
|
{ |
||||
|
return new QueryArguments |
||||
|
{ |
||||
|
new QueryArgument(typeof(IntGraphType)) |
||||
|
{ |
||||
|
Name = "top", |
||||
|
Description = "Optional number of contents to take.", |
||||
|
DefaultValue = 20 |
||||
|
}, |
||||
|
new QueryArgument(typeof(IntGraphType)) |
||||
|
{ |
||||
|
Name = "skip", |
||||
|
Description = "Optional number of contents to skip.", |
||||
|
DefaultValue = 0 |
||||
|
}, |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "filter", |
||||
|
Description = "Optional OData filter.", |
||||
|
DefaultValue = string.Empty |
||||
|
}, |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "search", |
||||
|
Description = "Optional OData full text search.", |
||||
|
DefaultValue = string.Empty |
||||
|
}, |
||||
|
new QueryArgument(typeof(StringGraphType)) |
||||
|
{ |
||||
|
Name = "orderby", |
||||
|
Description = "Optional OData order definition.", |
||||
|
DefaultValue = string.Empty |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private static string BuildODataQuery(ResolveFieldContext c) |
||||
|
{ |
||||
|
var odataQuery = "?" + |
||||
|
string.Join("&", |
||||
|
c.Arguments |
||||
|
.Select(x => new { x.Key, Value = x.Value.ToString() }).Where(x => !string.IsNullOrWhiteSpace(x.Value)) |
||||
|
.Select(x => $"${x.Key}={x.Value}")); |
||||
|
|
||||
|
return odataQuery; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using GraphQL.Resolvers; |
||||
|
using GraphQL.Types; |
||||
|
using Squidex.Domain.Apps.Entities.Assets; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types |
||||
|
{ |
||||
|
public sealed class AssetResultGraphType : ObjectGraphType<IResultList<IAssetEntity>> |
||||
|
{ |
||||
|
public AssetResultGraphType(IGraphType assetType) |
||||
|
{ |
||||
|
Name = $"AssetResultDto"; |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "total", |
||||
|
Resolver = Resolver(x => x.Total), |
||||
|
ResolvedType = new NonNullGraphType(new IntGraphType()), |
||||
|
Description = $"The total number of asset." |
||||
|
}); |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "items", |
||||
|
Resolver = Resolver(x => x), |
||||
|
ResolvedType = new ListGraphType(new NonNullGraphType(assetType)), |
||||
|
Description = $"The assets." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static IFieldResolver Resolver(Func<IResultList<IAssetEntity>, object> action) |
||||
|
{ |
||||
|
return new FuncFieldResolver<IResultList<IAssetEntity>, object>(c => action(c.Source)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,191 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// 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.Linq; |
|
||||
using GraphQL.Resolvers; |
|
||||
using GraphQL.Types; |
|
||||
using Squidex.Domain.Apps.Entities.Schemas; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types |
|
||||
{ |
|
||||
public sealed class ContentQueryGraphType : ObjectGraphType |
|
||||
{ |
|
||||
public ContentQueryGraphType(IGraphQLContext graphQLContext, IEnumerable<ISchemaEntity> schemas) |
|
||||
{ |
|
||||
AddAssetFind(graphQLContext); |
|
||||
AddAssetsQuery(graphQLContext); |
|
||||
|
|
||||
foreach (var schema in schemas) |
|
||||
{ |
|
||||
var schemaName = schema.SchemaDef.Properties.Label.WithFallback(schema.SchemaDef.Name); |
|
||||
var schemaType = graphQLContext.GetSchemaType(schema.Id); |
|
||||
|
|
||||
AddContentFind(schema, schemaType, schemaName); |
|
||||
AddContentQuery(schema, schemaType, schemaName); |
|
||||
} |
|
||||
|
|
||||
Description = "The app queries."; |
|
||||
} |
|
||||
|
|
||||
private void AddAssetFind(IGraphQLContext graphQLContext) |
|
||||
{ |
|
||||
AddField(new FieldType |
|
||||
{ |
|
||||
Name = "findAsset", |
|
||||
Arguments = new QueryArguments |
|
||||
{ |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "id", |
|
||||
Description = "The id of the asset.", |
|
||||
DefaultValue = string.Empty |
|
||||
} |
|
||||
}, |
|
||||
ResolvedType = graphQLContext.GetAssetType(), |
|
||||
Resolver = new FuncFieldResolver<object>(c => |
|
||||
{ |
|
||||
var context = (GraphQLQueryContext)c.UserContext; |
|
||||
var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString())); |
|
||||
|
|
||||
return context.FindAssetAsync(contentId); |
|
||||
}), |
|
||||
Description = "Find an asset by id." |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void AddContentFind(ISchemaEntity schema, IGraphType schemaType, string schemaName) |
|
||||
{ |
|
||||
AddField(new FieldType |
|
||||
{ |
|
||||
Name = $"find{schema.Name.ToPascalCase()}Content", |
|
||||
Arguments = new QueryArguments |
|
||||
{ |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "id", |
|
||||
Description = $"The id of the {schemaName} content.", |
|
||||
DefaultValue = string.Empty |
|
||||
} |
|
||||
}, |
|
||||
ResolvedType = schemaType, |
|
||||
Resolver = new FuncFieldResolver<object>(c => |
|
||||
{ |
|
||||
var context = (GraphQLQueryContext)c.UserContext; |
|
||||
var contentId = Guid.Parse(c.GetArgument("id", Guid.Empty.ToString())); |
|
||||
|
|
||||
return context.FindContentAsync(schema.Id, contentId); |
|
||||
}), |
|
||||
Description = $"Find an {schemaName} content by id." |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void AddAssetsQuery(IGraphQLContext graphQLContext) |
|
||||
{ |
|
||||
AddField(new FieldType |
|
||||
{ |
|
||||
Name = "queryAssets", |
|
||||
Arguments = new QueryArguments |
|
||||
{ |
|
||||
new QueryArgument(typeof(IntGraphType)) |
|
||||
{ |
|
||||
Name = "top", |
|
||||
Description = "Optional number of assets to take.", |
|
||||
DefaultValue = 20 |
|
||||
}, |
|
||||
new QueryArgument(typeof(IntGraphType)) |
|
||||
{ |
|
||||
Name = "skip", |
|
||||
Description = "Optional number of assets to skip.", |
|
||||
DefaultValue = 0 |
|
||||
}, |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "search", |
|
||||
Description = "Optional query.", |
|
||||
DefaultValue = string.Empty |
|
||||
} |
|
||||
}, |
|
||||
ResolvedType = new ListGraphType(new NonNullGraphType(graphQLContext.GetAssetType())), |
|
||||
Resolver = new FuncFieldResolver<object>(c => |
|
||||
{ |
|
||||
var context = (GraphQLQueryContext)c.UserContext; |
|
||||
|
|
||||
var argTop = c.GetArgument("top", 20); |
|
||||
var argSkip = c.GetArgument("skip", 0); |
|
||||
var argQuery = c.GetArgument("search", string.Empty); |
|
||||
|
|
||||
return context.QueryAssetsAsync(argQuery, argSkip, argTop); |
|
||||
}), |
|
||||
Description = "Query assets items." |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void AddContentQuery(ISchemaEntity schema, IGraphType schemaType, string schemaName) |
|
||||
{ |
|
||||
AddField(new FieldType |
|
||||
{ |
|
||||
Name = $"query{schema.Name.ToPascalCase()}Contents", |
|
||||
Arguments = new QueryArguments |
|
||||
{ |
|
||||
new QueryArgument(typeof(IntGraphType)) |
|
||||
{ |
|
||||
Name = "top", |
|
||||
Description = "Optional number of contents to take.", |
|
||||
DefaultValue = 20 |
|
||||
}, |
|
||||
new QueryArgument(typeof(IntGraphType)) |
|
||||
{ |
|
||||
Name = "skip", |
|
||||
Description = "Optional number of contents to skip.", |
|
||||
DefaultValue = 0 |
|
||||
}, |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "filter", |
|
||||
Description = "Optional OData filter.", |
|
||||
DefaultValue = string.Empty |
|
||||
}, |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "search", |
|
||||
Description = "Optional OData full text search.", |
|
||||
DefaultValue = string.Empty |
|
||||
}, |
|
||||
new QueryArgument(typeof(StringGraphType)) |
|
||||
{ |
|
||||
Name = "orderby", |
|
||||
Description = "Optional OData order definition.", |
|
||||
DefaultValue = string.Empty |
|
||||
} |
|
||||
}, |
|
||||
ResolvedType = new ListGraphType(new NonNullGraphType(schemaType)), |
|
||||
Resolver = new FuncFieldResolver<object>(c => |
|
||||
{ |
|
||||
var context = (GraphQLQueryContext)c.UserContext; |
|
||||
var contentQuery = BuildODataQuery(c); |
|
||||
|
|
||||
return context.QueryContentsAsync(schema.Id.ToString(), contentQuery); |
|
||||
}), |
|
||||
Description = $"Query {schemaName} content items." |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private static string BuildODataQuery(ResolveFieldContext c) |
|
||||
{ |
|
||||
var odataQuery = "?" + |
|
||||
string.Join("&", |
|
||||
c.Arguments |
|
||||
.Select(x => new { x.Key, Value = x.Value.ToString() }).Where(x => !string.IsNullOrWhiteSpace(x.Value)) |
|
||||
.Select(x => $"${x.Key}={x.Value}")); |
|
||||
|
|
||||
return odataQuery; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,46 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using GraphQL.Resolvers; |
||||
|
using GraphQL.Types; |
||||
|
using Squidex.Domain.Apps.Entities.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types |
||||
|
{ |
||||
|
public sealed class ContentResultGraphType : ObjectGraphType<IResultList<IContentEntity>> |
||||
|
{ |
||||
|
public ContentResultGraphType(IGraphQLContext ctx, ISchemaEntity schema, string schemaName) |
||||
|
{ |
||||
|
Name = $"{schema.Name.ToPascalCase()}ResultDto"; |
||||
|
|
||||
|
var schemaType = ctx.GetSchemaType(schema.Id); |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "total", |
||||
|
Resolver = Resolver(x => x.Total), |
||||
|
ResolvedType = new NonNullGraphType(new IntGraphType()), |
||||
|
Description = $"The total number of {schemaName} items." |
||||
|
}); |
||||
|
|
||||
|
AddField(new FieldType |
||||
|
{ |
||||
|
Name = "items", |
||||
|
Resolver = Resolver(x => x), |
||||
|
ResolvedType = new ListGraphType(new NonNullGraphType(schemaType)), |
||||
|
Description = $"The {schemaName} items." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private static IFieldResolver Resolver(Func<IResultList<IContentEntity>, object> action) |
||||
|
{ |
||||
|
return new FuncFieldResolver<IResultList<IContentEntity>, object>(c => action(c.Source)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue