diff --git a/benchmarks/graphql.benchmarks/ExecutionBenchmarks.cs b/benchmarks/graphql.benchmarks/ExecutionBenchmarks.cs index ad2da9a03..aa3b1c83e 100644 --- a/benchmarks/graphql.benchmarks/ExecutionBenchmarks.cs +++ b/benchmarks/graphql.benchmarks/ExecutionBenchmarks.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Tanka.GraphQL.Fields; using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; using Tanka.GraphQL.SelectionSets; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.Validation; diff --git a/dev/graphql.dev.chat.data/ChatResolvers.cs b/dev/graphql.dev.chat.data/ChatResolvers.cs index e02a1bd2b..3fd43b6b5 100644 --- a/dev/graphql.dev.chat.data/ChatResolvers.cs +++ b/dev/graphql.dev.chat.data/ChatResolvers.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Samples.Chat.Data.Domain; +using Tanka.GraphQL.Executable; +using Tanka.GraphQL.Samples.Chat.Data.Domain; using Tanka.GraphQL.Server; using Tanka.GraphQL.ValueResolution; diff --git a/dev/graphql.dev.chat.data/IChat.cs b/dev/graphql.dev.chat.data/IChat.cs index 494c2364e..ae58358a3 100644 --- a/dev/graphql.dev.chat.data/IChat.cs +++ b/dev/graphql.dev.chat.data/IChat.cs @@ -5,7 +5,6 @@ using System.Threading.Channels; using System.Threading.Tasks; using Tanka.GraphQL.Samples.Chat.Data.Domain; -using Tanka.GraphQL.Subscriptions; namespace Tanka.GraphQL.Samples.Chat.Data; diff --git a/src/GraphQL.Extensions.ApolloFederation/FederationExecutableSchemaBuilderExtensions.cs b/src/GraphQL.Extensions.ApolloFederation/FederationExecutableSchemaBuilderExtensions.cs index 77f35a847..0dd990b44 100644 --- a/src/GraphQL.Extensions.ApolloFederation/FederationExecutableSchemaBuilderExtensions.cs +++ b/src/GraphQL.Extensions.ApolloFederation/FederationExecutableSchemaBuilderExtensions.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL.Extensions.ApolloFederation; +using Tanka.GraphQL.Executable; + +namespace Tanka.GraphQL.Extensions.ApolloFederation; public static class FederationExecutableSchemaBuilderExtensions { diff --git a/src/GraphQL.Extensions.ApolloFederation/SubgraphConfiguration.cs b/src/GraphQL.Extensions.ApolloFederation/SubgraphConfiguration.cs index 7cc8d18a3..524c7a5ed 100644 --- a/src/GraphQL.Extensions.ApolloFederation/SubgraphConfiguration.cs +++ b/src/GraphQL.Extensions.ApolloFederation/SubgraphConfiguration.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Fields; using Tanka.GraphQL.Language; using Tanka.GraphQL.Language.Nodes; diff --git a/src/GraphQL/Subscriptions/BroadcastChannel.cs b/src/GraphQL/BroadcastChannel.cs similarity index 98% rename from src/GraphQL/Subscriptions/BroadcastChannel.cs rename to src/GraphQL/BroadcastChannel.cs index 71f12adb9..09630f5b3 100644 --- a/src/GraphQL/Subscriptions/BroadcastChannel.cs +++ b/src/GraphQL/BroadcastChannel.cs @@ -1,7 +1,7 @@ using System.Collections.Immutable; using System.Threading.Channels; -namespace Tanka.GraphQL.Subscriptions; +namespace Tanka.GraphQL; public class BroadcastChannel : IAsyncDisposable { diff --git a/src/GraphQL/DefaultOperationPipelineBuilderExtensions.cs b/src/GraphQL/DefaultOperationPipelineBuilderExtensions.cs index e3809eceb..73f021633 100644 --- a/src/GraphQL/DefaultOperationPipelineBuilderExtensions.cs +++ b/src/GraphQL/DefaultOperationPipelineBuilderExtensions.cs @@ -1,6 +1,8 @@ -using Tanka.GraphQL.Extensions.Trace; +using Tanka.GraphQL.Execution; +using Tanka.GraphQL.Extensions.Trace; using Tanka.GraphQL.Features; -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; +using Tanka.GraphQL.SelectionSets; using Tanka.GraphQL.Validation; using Tanka.GraphQL.ValueResolution; @@ -8,37 +10,34 @@ namespace Tanka.GraphQL; public static class DefaultOperationDelegateBuilderExtensions { - public static OperationDelegateBuilder AddFeature(this OperationDelegateBuilder builder, TFeature feature) + public static OperationDelegateBuilder AddDefaultFeatures( + this OperationDelegateBuilder builder) { + var errorFeature = new ConcurrentBagErrorCollectorFeature(); + var argumentBinderFeature = new ArgumentBinderFeature(); + var defaultSelectionSetExecutorFeature = new DefaultSelectionSetExecutorFeature(); + var fieldExecutorFeature = new FieldExecutorFeature(); + var valueCompletionFeature = new ValueCompletionFeature(); + return builder.Use(next => context => { - context.Features.Set(feature); + context.Features.Set(errorFeature); + context.Features.Set(argumentBinderFeature); + context.Features.Set(defaultSelectionSetExecutorFeature); + context.Features.Set(fieldExecutorFeature); + context.Features.Set(valueCompletionFeature); return next(context); }); } - public static OperationDelegateBuilder AddDefaultErrorCollectorFeature( - this OperationDelegateBuilder builder) + public static OperationDelegateBuilder RunQueryOrMutation(this OperationDelegateBuilder builder) { - var feature = new ConcurrentBagErrorCollectorFeature(); - return builder.Use(next => context => - { - context.Features.Set(feature); - return next(context); - }); + return builder.Use(_ => async context => { await Executor.ExecuteQueryOrMutation(context); }); } - - - public static OperationDelegateBuilder AddDefaultArgumentBinderFeature( - this OperationDelegateBuilder builder) + public static OperationDelegateBuilder RunSubscription(this OperationDelegateBuilder builder) { - var feature = new ArgumentBinderFeature(); - return builder.Use(next => context => - { - context.Features.Set(feature); - return next(context); - }); + return builder.Use(_ => async context => { await Executor.ExecuteSubscription(context); }); } public static OperationDelegateBuilder UseDefaultOperationResolver(this OperationDelegateBuilder builder) @@ -62,39 +61,24 @@ public static OperationDelegateBuilder UseDefaultOperationResolver(this Operatio /// public static OperationDelegateBuilder UseDefaults(this OperationDelegateBuilder builder) { - if (builder.GetProperty("TraceEnabled")) - { - builder.UseTrace(); - } + if (builder.GetProperty("TraceEnabled")) builder.UseTrace(); // extend query context with required features - builder.AddDefaultErrorCollectorFeature(); - - builder.AddDefaultSelectionSetExecutorFeature(); - builder.AddDefaultFieldExecutorFeature(); - builder.AddDefaultValueCompletionFeature(); + builder.AddDefaultFeatures(); // actual flow builder.UseDefaultValidator(); builder.UseDefaultOperationResolver(); builder.UseDefaultVariableCoercer(); - builder.WhenOperationTypeUse(query => - { - query.RunQueryOrMutation(); - }, - mutation => - { - mutation.RunQueryOrMutation(); - }, - subscriptions => - { - subscriptions.RunSubscription(); - }); + builder.WhenOperationTypeIsUse( + query => { query.RunQueryOrMutation(); }, + mutation => { mutation.RunQueryOrMutation(); }, + subscriptions => { subscriptions.RunSubscription(); } + ); return builder; } - public static OperationDelegateBuilder UseDefaultValidator(this OperationDelegateBuilder builder) { @@ -102,7 +86,8 @@ public static OperationDelegateBuilder UseDefaultValidator(this OperationDelegat builder.Use(next => async context => { - var result = await validator.Validate(context.Schema, context.Request.Document, context.Request.Variables); + ValidationResult result = + await validator.Validate(context.Schema, context.Request.Document, context.Request.Variables); if (!result.IsValid) throw new ValidationException(result); @@ -113,17 +98,6 @@ public static OperationDelegateBuilder UseDefaultValidator(this OperationDelegat return builder; } - public static OperationDelegateBuilder AddDefaultValueCompletionFeature( - this OperationDelegateBuilder builder) - { - var feature = new ValueCompletionFeature(); - return builder.Use(next => context => - { - context.Features.Set(feature); - return next(context); - }); - } - public static OperationDelegateBuilder UseDefaultVariableCoercer(this OperationDelegateBuilder builder) { builder.Use(next => context => @@ -138,53 +112,4 @@ public static OperationDelegateBuilder UseDefaultVariableCoercer(this OperationD return builder; } - - public static OperationDelegateBuilder WhenOperationTypeUse( - this OperationDelegateBuilder builder, - Action queryAction, - Action mutationAction, - Action subscriptionAction) - { - var queryBuilder = new OperationDelegateBuilder(builder.ApplicationServices); - queryAction(queryBuilder); - var queryDelegate = queryBuilder.Build(); - - var mutationBuilder = new OperationDelegateBuilder(builder.ApplicationServices); - mutationAction(mutationBuilder); - var mutationDelegate = mutationBuilder.Build(); - - var subscriptionBuilder = new OperationDelegateBuilder(builder.ApplicationServices); - subscriptionAction(subscriptionBuilder); - var subscriptionDelegate = subscriptionBuilder.Build(); - - return builder.Use(_ => async context => - { - Task execute = context.OperationDefinition.Operation switch - { - OperationType.Query => queryDelegate(context), - OperationType.Mutation => mutationDelegate(context), - OperationType.Subscription => subscriptionDelegate(context), - _ => throw new InvalidOperationException( - $"Operation type {context.OperationDefinition.Operation} not supported.") - }; - - await execute; - }); - } - - public static OperationDelegateBuilder RunQueryOrMutation(this OperationDelegateBuilder builder) - { - return builder.Use(_ => async context => - { - await Executor.ExecuteQueryOrMutation(context); - }); - } - - public static OperationDelegateBuilder RunSubscription(this OperationDelegateBuilder builder) - { - return builder.Use(_ => async context => - { - await Executor.ExecuteSubscription(context); - }); - } } \ No newline at end of file diff --git a/src/GraphQL/DefaultResponseStreamFeature.cs b/src/GraphQL/DefaultResponseStreamFeature.cs deleted file mode 100644 index 31c8cfdf1..000000000 --- a/src/GraphQL/DefaultResponseStreamFeature.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Tanka.GraphQL; - -public class DefaultResponseStreamFeature : IResponseStreamFeature -{ - public IAsyncEnumerable Response { get; set; } = AsyncEnumerable.Empty(); -} \ No newline at end of file diff --git a/src/GraphQL/Features/ErrorCollectorFeature.cs b/src/GraphQL/ErrorCollectorFeature.cs similarity index 97% rename from src/GraphQL/Features/ErrorCollectorFeature.cs rename to src/GraphQL/ErrorCollectorFeature.cs index d71b580d9..c886eb3ba 100644 --- a/src/GraphQL/Features/ErrorCollectorFeature.cs +++ b/src/GraphQL/ErrorCollectorFeature.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; +using Tanka.GraphQL.Features; -namespace Tanka.GraphQL.Features; +namespace Tanka.GraphQL; public class ConcurrentBagErrorCollectorFeature : IErrorCollectorFeature { diff --git a/src/GraphQL/ExecutableSchemaBuilder.cs b/src/GraphQL/Executable/ExecutableSchemaBuilder.cs similarity index 98% rename from src/GraphQL/ExecutableSchemaBuilder.cs rename to src/GraphQL/Executable/ExecutableSchemaBuilder.cs index 31fed2758..eab5add9e 100644 --- a/src/GraphQL/ExecutableSchemaBuilder.cs +++ b/src/GraphQL/Executable/ExecutableSchemaBuilder.cs @@ -3,7 +3,7 @@ using Tanka.GraphQL.ValueResolution; using Tanka.GraphQL.ValueSerialization; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Executable; public class ExecutableSchemaBuilder { diff --git a/src/GraphQL/IExecutableSchemaConfiguration.cs b/src/GraphQL/Executable/IExecutableSchemaConfiguration.cs similarity index 81% rename from src/GraphQL/IExecutableSchemaConfiguration.cs rename to src/GraphQL/Executable/IExecutableSchemaConfiguration.cs index f71906aac..148f09cf0 100644 --- a/src/GraphQL/IExecutableSchemaConfiguration.cs +++ b/src/GraphQL/Executable/IExecutableSchemaConfiguration.cs @@ -1,6 +1,6 @@ using Tanka.GraphQL.ValueResolution; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Executable; public interface IExecutableSchemaConfiguration { diff --git a/src/GraphQL/ObjectResolversConfiguration.cs b/src/GraphQL/Executable/ObjectResolversConfiguration.cs similarity index 97% rename from src/GraphQL/ObjectResolversConfiguration.cs rename to src/GraphQL/Executable/ObjectResolversConfiguration.cs index 0cb689564..38179f587 100644 --- a/src/GraphQL/ObjectResolversConfiguration.cs +++ b/src/GraphQL/Executable/ObjectResolversConfiguration.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.ValueResolution; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Executable; public class ObjectResolversConfiguration : IExecutableSchemaConfiguration { diff --git a/src/GraphQL/ObjectSubscribersConfiguration.cs b/src/GraphQL/Executable/ObjectSubscribersConfiguration.cs similarity index 97% rename from src/GraphQL/ObjectSubscribersConfiguration.cs rename to src/GraphQL/Executable/ObjectSubscribersConfiguration.cs index 69e4347af..b203f38a3 100644 --- a/src/GraphQL/ObjectSubscribersConfiguration.cs +++ b/src/GraphQL/Executable/ObjectSubscribersConfiguration.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.ValueResolution; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Executable; public class ObjectSubscribersConfiguration : IExecutableSchemaConfiguration { diff --git a/src/GraphQL/ResolversConfiguration.cs b/src/GraphQL/Executable/ResolversConfiguration.cs similarity index 61% rename from src/GraphQL/ResolversConfiguration.cs rename to src/GraphQL/Executable/ResolversConfiguration.cs index 5c8c7b371..117997ff9 100644 --- a/src/GraphQL/ResolversConfiguration.cs +++ b/src/GraphQL/Executable/ResolversConfiguration.cs @@ -1,6 +1,6 @@ using Tanka.GraphQL.ValueResolution; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Executable; public class ResolversConfiguration : IExecutableSchemaConfiguration { @@ -14,12 +14,12 @@ public ResolversConfiguration(IResolverMap resolversMap) public Task Configure(SchemaBuilder schema, ResolversBuilder resolvers) { foreach (var (typeName, fields) in _resolversMap.GetTypes()) - foreach (var field in fields) - { - var resolver = _resolversMap.GetResolver(typeName, field); - if (resolver is not null) - resolvers.Add(typeName, field, r => r.Run(resolver)); - } + foreach (var field in fields) + { + var resolver = _resolversMap.GetResolver(typeName, field); + if (resolver is not null) + resolvers.Add(typeName, field, r => r.Run(resolver)); + } return Task.CompletedTask; } diff --git a/src/GraphQL/FieldExecutionOperationDelegateBuilderExtensions.cs b/src/GraphQL/Execution/FieldExecutionOperationDelegateBuilderExtensions.cs similarity index 63% rename from src/GraphQL/FieldExecutionOperationDelegateBuilderExtensions.cs rename to src/GraphQL/Execution/FieldExecutionOperationDelegateBuilderExtensions.cs index 5d4093f87..ebe0f3222 100644 --- a/src/GraphQL/FieldExecutionOperationDelegateBuilderExtensions.cs +++ b/src/GraphQL/Execution/FieldExecutionOperationDelegateBuilderExtensions.cs @@ -1,25 +1,16 @@ -namespace Tanka.GraphQL; +using Tanka.GraphQL.Features; + +namespace Tanka.GraphQL.Execution; public static class FieldExecutionOperationDelegateBuilderExtensions { - public static OperationDelegateBuilder AddDefaultFieldExecutorFeature( - this OperationDelegateBuilder builder) - { - var feature = new FieldExecutorFeature(); - return builder.Use(next => context => - { - context.Features.Set(feature); - return next(context); - }); - } - public static OperationDelegateBuilder AddFieldDelegateExecutorFeature( this OperationDelegateBuilder builder, Action configureFieldExecutor) { var fieldDelegateBuilder = new FieldDelegateBuilder(builder.ApplicationServices); configureFieldExecutor(fieldDelegateBuilder); - + var feature = new FieldPipelineExecutorFeature(fieldDelegateBuilder.Build()); return builder.Use(next => context => { diff --git a/src/GraphQL/Features/OperationFeature.cs b/src/GraphQL/Execution/OperationFeature.cs similarity index 69% rename from src/GraphQL/Features/OperationFeature.cs rename to src/GraphQL/Execution/OperationFeature.cs index bdeee09ed..f7f35b03f 100644 --- a/src/GraphQL/Features/OperationFeature.cs +++ b/src/GraphQL/Execution/OperationFeature.cs @@ -1,6 +1,7 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; -namespace Tanka.GraphQL.Features; +namespace Tanka.GraphQL.Execution; public class OperationFeature : IOperationFeature { diff --git a/src/GraphQL/Execution/OperationTypeOperationDelegateBuilderExtensions.cs b/src/GraphQL/Execution/OperationTypeOperationDelegateBuilderExtensions.cs new file mode 100644 index 000000000..7b845378e --- /dev/null +++ b/src/GraphQL/Execution/OperationTypeOperationDelegateBuilderExtensions.cs @@ -0,0 +1,39 @@ +using Tanka.GraphQL.Language.Nodes; + +namespace Tanka.GraphQL.Execution; + +public static class OperationTypeOperationDelegateBuilderExtensions +{ + public static OperationDelegateBuilder WhenOperationTypeIsUse( + this OperationDelegateBuilder builder, + Action queryAction, + Action mutationAction, + Action subscriptionAction) + { + var queryBuilder = new OperationDelegateBuilder(builder.ApplicationServices); + queryAction(queryBuilder); + OperationDelegate queryDelegate = queryBuilder.Build(); + + var mutationBuilder = new OperationDelegateBuilder(builder.ApplicationServices); + mutationAction(mutationBuilder); + OperationDelegate mutationDelegate = mutationBuilder.Build(); + + var subscriptionBuilder = new OperationDelegateBuilder(builder.ApplicationServices); + subscriptionAction(subscriptionBuilder); + OperationDelegate subscriptionDelegate = subscriptionBuilder.Build(); + + return builder.Use(_ => async context => + { + Task execute = context.OperationDefinition.Operation switch + { + OperationType.Query => queryDelegate(context), + OperationType.Mutation => mutationDelegate(context), + OperationType.Subscription => subscriptionDelegate(context), + _ => throw new InvalidOperationException( + $"Operation type {context.OperationDefinition.Operation} not supported.") + }; + + await execute; + }); + } +} \ No newline at end of file diff --git a/src/GraphQL/RunOperationOperationPipelineBuilderExtensions.cs b/src/GraphQL/Execution/RunOperationOperationPipelineBuilderExtensions.cs similarity index 65% rename from src/GraphQL/RunOperationOperationPipelineBuilderExtensions.cs rename to src/GraphQL/Execution/RunOperationOperationPipelineBuilderExtensions.cs index 60b8b5d09..b2db426be 100644 --- a/src/GraphQL/RunOperationOperationPipelineBuilderExtensions.cs +++ b/src/GraphQL/Execution/RunOperationOperationPipelineBuilderExtensions.cs @@ -1,4 +1,4 @@ -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Execution; public static class RunOperationOperationPipelineBuilderExtensions { diff --git a/src/GraphQL/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs b/src/GraphQL/Execution/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs similarity index 61% rename from src/GraphQL/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs rename to src/GraphQL/Execution/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs index 96622c84b..900b9a656 100644 --- a/src/GraphQL/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs +++ b/src/GraphQL/Execution/UseSelectionSetPipelineOperationPipelineBuilderExtensions.cs @@ -1,6 +1,7 @@ -using Tanka.GraphQL.SelectionSets; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.SelectionSets; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Execution; public static class SelectionSetExecutorOperationDelegateBuilderExtensions { @@ -21,16 +22,4 @@ public static OperationDelegateBuilder AddSelectionSetPipeline( return builder; } - - public static OperationDelegateBuilder AddDefaultSelectionSetExecutorFeature( - this OperationDelegateBuilder builder) - { - var feature = new DefaultSelectionSetExecutorFeature(); - - return builder.Use(next => context => - { - context.Features.Set(feature); - return next(context); - }); - } } \ No newline at end of file diff --git a/src/GraphQL/ExecutionResult.cs b/src/GraphQL/ExecutionResult.cs index 54f63c54f..cb835f1c7 100644 --- a/src/GraphQL/ExecutionResult.cs +++ b/src/GraphQL/ExecutionResult.cs @@ -1,4 +1,5 @@ using System.Text.Json.Serialization; +using Tanka.GraphQL.Json; namespace Tanka.GraphQL; diff --git a/src/GraphQL/Executor.BuildQueryContext.cs b/src/GraphQL/Executor.BuildQueryContext.cs index 84e9b00b8..718817b36 100644 --- a/src/GraphQL/Executor.BuildQueryContext.cs +++ b/src/GraphQL/Executor.BuildQueryContext.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL; +using Tanka.GraphQL.Request; + +namespace Tanka.GraphQL; public partial class Executor { diff --git a/src/GraphQL/Executor.Execute.cs b/src/GraphQL/Executor.Execute.cs index 46c4daf8c..c325225ef 100644 --- a/src/GraphQL/Executor.Execute.cs +++ b/src/GraphQL/Executor.Execute.cs @@ -1,4 +1,5 @@ using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; namespace Tanka.GraphQL; diff --git a/src/GraphQL/Executor.Subscribe.cs b/src/GraphQL/Executor.Subscribe.cs index f6bedcdbb..9365d04bc 100644 --- a/src/GraphQL/Executor.Subscribe.cs +++ b/src/GraphQL/Executor.Subscribe.cs @@ -1,4 +1,5 @@ using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; namespace Tanka.GraphQL; diff --git a/src/GraphQL/Executor.cs b/src/GraphQL/Executor.cs index 1a116cec7..fb7cd1ec2 100644 --- a/src/GraphQL/Executor.cs +++ b/src/GraphQL/Executor.cs @@ -1,8 +1,7 @@ using Microsoft.Extensions.DependencyInjection; +using Tanka.GraphQL.Execution; using Tanka.GraphQL.Extensions.Trace; using Tanka.GraphQL.Features; -using Tanka.GraphQL.SelectionSets; -using Tanka.GraphQL.ValueResolution; namespace Tanka.GraphQL; @@ -12,41 +11,6 @@ public partial class Executor private readonly OperationDelegate _operationDelegate; - /// - /// Create executor with default execution pipeline using - /// the provided features. - /// - /// - /// - /// - /// - /// - public Executor( - ISchema schema, - ISelectionSetExecutorFeature selectionSetExecutor, - IFieldExecutorFeature fieldExecutor, - IValueCompletionFeature valueCompletion) - { - _operationDelegate = new OperationDelegateBuilder(EmptyProvider) - .AddFeature(new SchemaFeature - { - Schema = schema - }) - .AddFeature(selectionSetExecutor) - .AddFeature(fieldExecutor) - .AddFeature(valueCompletion) - .AddDefaultErrorCollectorFeature() - .AddDefaultArgumentBinderFeature() - .UseDefaultValidator() - .UseDefaultOperationResolver() - .UseDefaultVariableCoercer() - .WhenOperationTypeUse( - q => q.RunQueryOrMutation(), - m => m.RunQueryOrMutation(), - s => s.RunSubscription()) - .Build(); - } - /// /// Create executor with defaults and use given . /// @@ -68,12 +32,7 @@ public Executor(ExecutorOptions options) builder.AddFeature(new SchemaFeature { Schema = options.Schema - }) - .AddDefaultSelectionSetExecutorFeature() - .AddDefaultFieldExecutorFeature() - .AddDefaultErrorCollectorFeature() - .AddDefaultArgumentBinderFeature() - .AddDefaultValueCompletionFeature(); + }).AddDefaultFeatures(); if (options.ValidationEnabled) builder @@ -82,7 +41,7 @@ public Executor(ExecutorOptions options) builder .UseDefaultOperationResolver() .UseDefaultVariableCoercer() - .WhenOperationTypeUse( + .WhenOperationTypeIsUse( q => q.RunQueryOrMutation(), m => m.RunQueryOrMutation(), s => s.RunSubscription()) @@ -95,13 +54,4 @@ public Executor(OperationDelegate operationDelegate) { _operationDelegate = operationDelegate; } -} - -public record ExecutorOptions -{ - public required ISchema Schema { get; set; } - - public bool TraceEnabled { get; set; } = false; - - public bool ValidationEnabled { get; set; } = true; } \ No newline at end of file diff --git a/src/GraphQL/ExecutorOptions.cs b/src/GraphQL/ExecutorOptions.cs new file mode 100644 index 000000000..4d5859eed --- /dev/null +++ b/src/GraphQL/ExecutorOptions.cs @@ -0,0 +1,10 @@ +namespace Tanka.GraphQL; + +public record ExecutorOptions +{ + public required ISchema Schema { get; set; } + + public bool TraceEnabled { get; set; } = false; + + public bool ValidationEnabled { get; set; } = true; +} \ No newline at end of file diff --git a/src/GraphQL/Features/IArgumentBinderFeature.cs b/src/GraphQL/Features/IArgumentBinderFeature.cs new file mode 100644 index 000000000..195acb5eb --- /dev/null +++ b/src/GraphQL/Features/IArgumentBinderFeature.cs @@ -0,0 +1,13 @@ +using Tanka.GraphQL.ValueResolution; + +namespace Tanka.GraphQL.Features; + +public interface IArgumentBinderFeature +{ + static IArgumentBinderFeature Default = new ArgumentBinderFeature(); + + T? BindInputObject(ResolverContextBase context, string name) + where T : new(); + + IEnumerable? BindInputObjectList(ResolverContextBase context, string name) where T : new(); +} \ No newline at end of file diff --git a/src/GraphQL/Fields/IFieldExecutorFeature.cs b/src/GraphQL/Features/IFieldExecutorFeature.cs similarity index 90% rename from src/GraphQL/Fields/IFieldExecutorFeature.cs rename to src/GraphQL/Features/IFieldExecutorFeature.cs index 1a0758cd5..7ac53b248 100644 --- a/src/GraphQL/Fields/IFieldExecutorFeature.cs +++ b/src/GraphQL/Features/IFieldExecutorFeature.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; -namespace Tanka.GraphQL.Fields; +namespace Tanka.GraphQL.Features; public interface IFieldExecutorFeature { diff --git a/src/GraphQL/Features/IGraphQLRequestFeature.cs b/src/GraphQL/Features/IGraphQLRequestFeature.cs index 1da063bfe..86333d040 100644 --- a/src/GraphQL/Features/IGraphQLRequestFeature.cs +++ b/src/GraphQL/Features/IGraphQLRequestFeature.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL.Features; +using Tanka.GraphQL.Request; + +namespace Tanka.GraphQL.Features; public interface IGraphQLRequestFeature { diff --git a/src/GraphQL/IResponseStreamFeature.cs b/src/GraphQL/Features/IResponseStreamFeature.cs similarity index 73% rename from src/GraphQL/IResponseStreamFeature.cs rename to src/GraphQL/Features/IResponseStreamFeature.cs index 03b5db567..a84cf3c86 100644 --- a/src/GraphQL/IResponseStreamFeature.cs +++ b/src/GraphQL/Features/IResponseStreamFeature.cs @@ -1,4 +1,4 @@ -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Features; public interface IResponseStreamFeature { diff --git a/src/GraphQL/SelectionSets/ISelectionSetExecutorFeature.cs b/src/GraphQL/Features/ISelectionSetExecutorFeature.cs similarity index 90% rename from src/GraphQL/SelectionSets/ISelectionSetExecutorFeature.cs rename to src/GraphQL/Features/ISelectionSetExecutorFeature.cs index 1c165679a..2a1cba8bc 100644 --- a/src/GraphQL/SelectionSets/ISelectionSetExecutorFeature.cs +++ b/src/GraphQL/Features/ISelectionSetExecutorFeature.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; -namespace Tanka.GraphQL.SelectionSets; +namespace Tanka.GraphQL.Features; public interface ISelectionSetExecutorFeature { diff --git a/src/GraphQL/Validation/IValidatorFeature.cs b/src/GraphQL/Features/IValidatorFeature.cs similarity index 78% rename from src/GraphQL/Validation/IValidatorFeature.cs rename to src/GraphQL/Features/IValidatorFeature.cs index 570523e53..cd108325e 100644 --- a/src/GraphQL/Validation/IValidatorFeature.cs +++ b/src/GraphQL/Features/IValidatorFeature.cs @@ -1,6 +1,7 @@ using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Validation; -namespace Tanka.GraphQL.Validation; +namespace Tanka.GraphQL.Features; public interface IValidatorFeature { diff --git a/src/GraphQL/Features/OperationDelegateBuilderExtensions.cs b/src/GraphQL/Features/OperationDelegateBuilderExtensions.cs new file mode 100644 index 000000000..7e342c8ba --- /dev/null +++ b/src/GraphQL/Features/OperationDelegateBuilderExtensions.cs @@ -0,0 +1,13 @@ +namespace Tanka.GraphQL.Features; + +public static class OperationDelegateBuilderExtensions +{ + public static OperationDelegateBuilder AddFeature(this OperationDelegateBuilder builder, TFeature feature) + { + return builder.Use(next => context => + { + context.Features.Set(feature); + return next(context); + }); + } +} \ No newline at end of file diff --git a/src/GraphQL/Fields/ArgumentBinderFeature.cs b/src/GraphQL/Fields/ArgumentBinderFeature.cs index 4d78e12f8..bfe33ede0 100644 --- a/src/GraphQL/Fields/ArgumentBinderFeature.cs +++ b/src/GraphQL/Fields/ArgumentBinderFeature.cs @@ -1,38 +1,9 @@ -using Tanka.GraphQL.Internal; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Internal; using Tanka.GraphQL.ValueResolution; namespace Tanka.GraphQL.Fields; -public static class ArgumentBinderQueryContextExtensions -{ - public static T? BindInputObject(this QueryContext queryContext, ResolverContextBase context, string name) - where T : new() - { - ArgumentNullException.ThrowIfNull(queryContext.ArgumentBinder); - - return queryContext.ArgumentBinder.BindInputObject(context, name); - } - - public static IEnumerable? BindInputObjectList(this QueryContext queryContext, ResolverContextBase context, - string name) - where T : new() - { - ArgumentNullException.ThrowIfNull(queryContext.ArgumentBinder); - - return queryContext.ArgumentBinder.BindInputObjectList(context, name); - } -} - -public interface IArgumentBinderFeature -{ - static IArgumentBinderFeature Default = new ArgumentBinderFeature(); - - T? BindInputObject(ResolverContextBase context, string name) - where T : new(); - - IEnumerable? BindInputObjectList(ResolverContextBase context, string name) where T : new(); -} - public class ArgumentBinderFeature : IArgumentBinderFeature { public T? BindInputObject(ResolverContextBase context, string name) diff --git a/src/GraphQL/Fields/ArgumentBinderQueryContextExtensions.cs b/src/GraphQL/Fields/ArgumentBinderQueryContextExtensions.cs new file mode 100644 index 000000000..99dfd03ae --- /dev/null +++ b/src/GraphQL/Fields/ArgumentBinderQueryContextExtensions.cs @@ -0,0 +1,23 @@ +using Tanka.GraphQL.ValueResolution; + +namespace Tanka.GraphQL.Fields; + +public static class ArgumentBinderQueryContextExtensions +{ + public static T? BindInputObject(this QueryContext queryContext, ResolverContextBase context, string name) + where T : new() + { + ArgumentNullException.ThrowIfNull(queryContext.ArgumentBinder); + + return queryContext.ArgumentBinder.BindInputObject(context, name); + } + + public static IEnumerable? BindInputObjectList(this QueryContext queryContext, ResolverContextBase context, + string name) + where T : new() + { + ArgumentNullException.ThrowIfNull(queryContext.ArgumentBinder); + + return queryContext.ArgumentBinder.BindInputObjectList(context, name); + } +} \ No newline at end of file diff --git a/src/GraphQL/Fields/FieldExecutorFeature.cs b/src/GraphQL/Fields/FieldExecutorFeature.cs index c80eac647..409ea6c26 100644 --- a/src/GraphQL/Fields/FieldExecutorFeature.cs +++ b/src/GraphQL/Fields/FieldExecutorFeature.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.ValueResolution; diff --git a/src/GraphQL/Fields/FieldPipelineExecutorFeature.cs b/src/GraphQL/Fields/FieldPipelineExecutorFeature.cs index 94d74c763..a2ae0db96 100644 --- a/src/GraphQL/Fields/FieldPipelineExecutorFeature.cs +++ b/src/GraphQL/Fields/FieldPipelineExecutorFeature.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using Tanka.GraphQL.Features; using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.ValueResolution; diff --git a/src/GraphQL/ExecutableDocumentConverter.cs b/src/GraphQL/Json/ExecutableDocumentConverter.cs similarity index 96% rename from src/GraphQL/ExecutableDocumentConverter.cs rename to src/GraphQL/Json/ExecutableDocumentConverter.cs index 41275587d..49c0134f3 100644 --- a/src/GraphQL/ExecutableDocumentConverter.cs +++ b/src/GraphQL/Json/ExecutableDocumentConverter.cs @@ -3,7 +3,7 @@ using Tanka.GraphQL.Language; using Tanka.GraphQL.Language.Nodes; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Json; public class ExecutableDocumentConverter : JsonConverter { diff --git a/src/GraphQL/NestedDictionaryConverter.cs b/src/GraphQL/Json/NestedDictionaryConverter.cs similarity index 97% rename from src/GraphQL/NestedDictionaryConverter.cs rename to src/GraphQL/Json/NestedDictionaryConverter.cs index a73d03a86..a62118907 100644 --- a/src/GraphQL/NestedDictionaryConverter.cs +++ b/src/GraphQL/Json/NestedDictionaryConverter.cs @@ -2,7 +2,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Json; public class NestedDictionaryConverter : JsonConverter> { @@ -13,9 +13,9 @@ public NestedDictionaryConverter(bool useDecimals = false) _useDecimals = useDecimals; } - public NestedDictionaryConverter():this(false) + public NestedDictionaryConverter() : this(false) { - + } @@ -31,7 +31,7 @@ public NestedDictionaryConverter():this(false) break; EnsureToken(reader.TokenType, JsonTokenType.PropertyName); - + var propertyName = reader.GetString(); if (propertyName is null) diff --git a/src/GraphQL/QueryContext.cs b/src/GraphQL/QueryContext.cs index 79c3e4bac..1429bdb66 100644 --- a/src/GraphQL/QueryContext.cs +++ b/src/GraphQL/QueryContext.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Http.Features; +using Tanka.GraphQL.Execution; using Tanka.GraphQL.Features; using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; +using Tanka.GraphQL.Request; +using Tanka.GraphQL.Response; using Tanka.GraphQL.SelectionSets; -using Tanka.GraphQL.Validation; using Tanka.GraphQL.ValueResolution; namespace Tanka.GraphQL; @@ -29,7 +31,7 @@ public QueryContext() : this(new FeatureCollection(12)) private IResponseStreamFeature ResponseFeature => _features.Fetch( ref _features.Cache.Response, - _ => new DefaultResponseStreamFeature())!; + _ => new GraphQLResponseFeature())!; private IGraphQLRequestFeature RequestFeature => _features.Fetch( ref _features.Cache.Request, diff --git a/src/GraphQL/Features/CoercedVariableValuesFeature.cs b/src/GraphQL/Request/CoercedVariableValuesFeature.cs similarity index 84% rename from src/GraphQL/Features/CoercedVariableValuesFeature.cs rename to src/GraphQL/Request/CoercedVariableValuesFeature.cs index aa9921cad..7db1e7cbf 100644 --- a/src/GraphQL/Features/CoercedVariableValuesFeature.cs +++ b/src/GraphQL/Request/CoercedVariableValuesFeature.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL.Features; +using Tanka.GraphQL.Features; + +namespace Tanka.GraphQL.Request; public class CoercedVariableValuesFeature : ICoercedVariableValuesFeature { diff --git a/src/GraphQL/GraphQLRequest.cs b/src/GraphQL/Request/GraphQLRequest.cs similarity index 94% rename from src/GraphQL/GraphQLRequest.cs rename to src/GraphQL/Request/GraphQLRequest.cs index 28d3b61c0..4e3d4cb77 100644 --- a/src/GraphQL/GraphQLRequest.cs +++ b/src/GraphQL/Request/GraphQLRequest.cs @@ -1,8 +1,9 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using Tanka.GraphQL.Json; using Tanka.GraphQL.Language.Nodes; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Request; /// /// Execution options diff --git a/src/GraphQL/Features/GraphQLRequestFeature.cs b/src/GraphQL/Request/GraphQLRequestFeature.cs similarity index 63% rename from src/GraphQL/Features/GraphQLRequestFeature.cs rename to src/GraphQL/Request/GraphQLRequestFeature.cs index e4cc7b5f4..aaeff03f1 100644 --- a/src/GraphQL/Features/GraphQLRequestFeature.cs +++ b/src/GraphQL/Request/GraphQLRequestFeature.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL.Features; +using Tanka.GraphQL.Features; + +namespace Tanka.GraphQL.Request; internal class GraphQLRequestFeature : IGraphQLRequestFeature { diff --git a/src/GraphQL/Variables.cs b/src/GraphQL/Request/Variables.cs similarity index 98% rename from src/GraphQL/Variables.cs rename to src/GraphQL/Request/Variables.cs index 910f59900..550bccf29 100644 --- a/src/GraphQL/Variables.cs +++ b/src/GraphQL/Request/Variables.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.ValueSerialization; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.Request; public static class Variables { diff --git a/src/GraphQL/Response/DefaultResponseStreamFeature.cs b/src/GraphQL/Response/DefaultResponseStreamFeature.cs new file mode 100644 index 000000000..cc2448f17 --- /dev/null +++ b/src/GraphQL/Response/DefaultResponseStreamFeature.cs @@ -0,0 +1,8 @@ +using Tanka.GraphQL.Features; + +namespace Tanka.GraphQL.Response; + +public class GraphQLResponseFeature : IResponseStreamFeature +{ + public IAsyncEnumerable Response { get; set; } = AsyncEnumerable.Empty(); +} \ No newline at end of file diff --git a/src/GraphQL/SelectionSets/SelectionSetExecutorFeature.cs b/src/GraphQL/SelectionSets/SelectionSetExecutorFeature.cs index 59737f1cf..6503b0f63 100644 --- a/src/GraphQL/SelectionSets/SelectionSetExecutorFeature.cs +++ b/src/GraphQL/SelectionSets/SelectionSetExecutorFeature.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; namespace Tanka.GraphQL.SelectionSets; diff --git a/src/GraphQL/SelectionSets/SelectionSetPipelineExecutorFeature.cs b/src/GraphQL/SelectionSets/SelectionSetPipelineExecutorFeature.cs index f0ab74793..7699fca1b 100644 --- a/src/GraphQL/SelectionSets/SelectionSetPipelineExecutorFeature.cs +++ b/src/GraphQL/SelectionSets/SelectionSetPipelineExecutorFeature.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; namespace Tanka.GraphQL.SelectionSets; diff --git a/src/GraphQL/Features/SchemaFeature.cs b/src/GraphQL/TypeSystem/SchemaFeature.cs similarity index 60% rename from src/GraphQL/Features/SchemaFeature.cs rename to src/GraphQL/TypeSystem/SchemaFeature.cs index 849f2a028..759ccf6a9 100644 --- a/src/GraphQL/Features/SchemaFeature.cs +++ b/src/GraphQL/TypeSystem/SchemaFeature.cs @@ -1,4 +1,6 @@ -namespace Tanka.GraphQL.Features; +using Tanka.GraphQL.Features; + +namespace Tanka.GraphQL.TypeSystem; public class SchemaFeature : ISchemaFeature { diff --git a/src/GraphQL/TypeIs.cs b/src/GraphQL/TypeSystem/TypeIs.cs similarity index 97% rename from src/GraphQL/TypeIs.cs rename to src/GraphQL/TypeSystem/TypeIs.cs index 1cde31261..ada973e31 100644 --- a/src/GraphQL/TypeIs.cs +++ b/src/GraphQL/TypeSystem/TypeIs.cs @@ -1,7 +1,7 @@ using Tanka.GraphQL.Language.Nodes; using Tanka.GraphQL.Language.Nodes.TypeSystem; -namespace Tanka.GraphQL; +namespace Tanka.GraphQL.TypeSystem; public static class TypeIs { diff --git a/src/GraphQL/Validation/NoValidationFeature.cs b/src/GraphQL/Validation/NoValidationFeature.cs index cbe1969e5..416014323 100644 --- a/src/GraphQL/Validation/NoValidationFeature.cs +++ b/src/GraphQL/Validation/NoValidationFeature.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; namespace Tanka.GraphQL.Validation; diff --git a/src/GraphQL/Validation/ValidatorFeature.cs b/src/GraphQL/Validation/ValidatorFeature.cs index 2f9163999..3a61e7aa1 100644 --- a/src/GraphQL/Validation/ValidatorFeature.cs +++ b/src/GraphQL/Validation/ValidatorFeature.cs @@ -1,4 +1,5 @@ -using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Features; +using Tanka.GraphQL.Language.Nodes; namespace Tanka.GraphQL.Validation; diff --git a/src/graphql.server/GraphQLHttpRequest.cs b/src/graphql.server/GraphQLHttpRequest.cs index fb1692ef3..355e45411 100644 --- a/src/graphql.server/GraphQLHttpRequest.cs +++ b/src/graphql.server/GraphQLHttpRequest.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text.Json.Serialization; +using Tanka.GraphQL.Json; using Tanka.GraphQL.Language.Nodes; namespace Tanka.GraphQL.Server; diff --git a/src/graphql.server/HttpTransportGraphQLRequestBuilderExtensions.cs b/src/graphql.server/HttpTransportGraphQLRequestBuilderExtensions.cs index 957db5ce9..96e5e60ec 100644 --- a/src/graphql.server/HttpTransportGraphQLRequestBuilderExtensions.cs +++ b/src/graphql.server/HttpTransportGraphQLRequestBuilderExtensions.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Tanka.GraphQL.Request; namespace Tanka.GraphQL.Server; diff --git a/src/graphql.server/LogMessages.cs b/src/graphql.server/LogMessages.cs index 15c4a29e4..dbf3de9bb 100644 --- a/src/graphql.server/LogMessages.cs +++ b/src/graphql.server/LogMessages.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Microsoft.Extensions.Logging; using Tanka.GraphQL.Language; +using Tanka.GraphQL.Request; namespace Tanka.GraphQL.Server; diff --git a/src/graphql.server/SchemaOptions.cs b/src/graphql.server/SchemaOptions.cs index bf8bb08a7..28040fc13 100644 --- a/src/graphql.server/SchemaOptions.cs +++ b/src/graphql.server/SchemaOptions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.TypeSystem; diff --git a/src/graphql.server/SchemaOptionsBuilder.cs b/src/graphql.server/SchemaOptionsBuilder.cs index 2b3d6fd05..f59315fef 100644 --- a/src/graphql.server/SchemaOptionsBuilder.cs +++ b/src/graphql.server/SchemaOptionsBuilder.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes.TypeSystem; namespace Tanka.GraphQL.Server; diff --git a/src/graphql.server/WebSockets/Messages.cs b/src/graphql.server/WebSockets/Messages.cs index c3514a62f..8b50a7d5f 100644 --- a/src/graphql.server/WebSockets/Messages.cs +++ b/src/graphql.server/WebSockets/Messages.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; +using Tanka.GraphQL.Json; namespace Tanka.GraphQL.Server.WebSockets; diff --git a/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationFacts.cs b/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationFacts.cs index a599fbe98..f9080ff66 100644 --- a/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationFacts.cs +++ b/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationFacts.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Tanka.GraphQL.Request; using Tanka.GraphQL.TypeSystem; using Xunit; diff --git a/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationSchemaBuilderFacts.cs b/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationSchemaBuilderFacts.cs index afd98c945..3c6361bd1 100644 --- a/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationSchemaBuilderFacts.cs +++ b/tests/GraphQL.Extensions.ApolloFederation.Tests/FederationSchemaBuilderFacts.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Fields; using Tanka.GraphQL.Language.Nodes.TypeSystem; +using Tanka.GraphQL.Request; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.ValueResolution; using Xunit; diff --git a/tests/GraphQL.Extensions.ApolloFederation.Tests/SchemaFactory.cs b/tests/GraphQL.Extensions.ApolloFederation.Tests/SchemaFactory.cs index 72da9be07..a9727e808 100644 --- a/tests/GraphQL.Extensions.ApolloFederation.Tests/SchemaFactory.cs +++ b/tests/GraphQL.Extensions.ApolloFederation.Tests/SchemaFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes.TypeSystem; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.ValueResolution; diff --git a/tests/GraphQL.Extensions.Tracing.Tests/TraceFacts.cs b/tests/GraphQL.Extensions.Tracing.Tests/TraceFacts.cs index ae3dcc4ce..e1ec39d8b 100644 --- a/tests/GraphQL.Extensions.Tracing.Tests/TraceFacts.cs +++ b/tests/GraphQL.Extensions.Tracing.Tests/TraceFacts.cs @@ -1,5 +1,7 @@ +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Extensions.Trace; using Tanka.GraphQL.Language.Nodes.TypeSystem; +using Tanka.GraphQL.Request; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.ValueResolution; diff --git a/tests/graphql.tests/Executor.MutationFacts.cs b/tests/graphql.tests/Executor.MutationFacts.cs index 9c4c091b4..45734e251 100644 --- a/tests/graphql.tests/Executor.MutationFacts.cs +++ b/tests/graphql.tests/Executor.MutationFacts.cs @@ -1,5 +1,7 @@ using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; using Tanka.GraphQL.ValueResolution; using Xunit; diff --git a/tests/graphql.tests/Executor.QueryFacts.cs b/tests/graphql.tests/Executor.QueryFacts.cs index e8d38bcaa..a6d09a0ea 100644 --- a/tests/graphql.tests/Executor.QueryFacts.cs +++ b/tests/graphql.tests/Executor.QueryFacts.cs @@ -1,5 +1,7 @@ using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; using Tanka.GraphQL.ValueResolution; using Xunit; diff --git a/tests/graphql.tests/Executor.SubscriptionFacts.cs b/tests/graphql.tests/Executor.SubscriptionFacts.cs index 97d8d5897..f2f1b9cef 100644 --- a/tests/graphql.tests/Executor.SubscriptionFacts.cs +++ b/tests/graphql.tests/Executor.SubscriptionFacts.cs @@ -3,7 +3,9 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Tanka.GraphQL.Executable; using Tanka.GraphQL.Language.Nodes; +using Tanka.GraphQL.Request; using Xunit; namespace Tanka.GraphQL.Tests; diff --git a/tests/graphql.tests/ExecutorFacts.cs b/tests/graphql.tests/ExecutorFacts.cs index 51c004c92..1775185cd 100644 --- a/tests/graphql.tests/ExecutorFacts.cs +++ b/tests/graphql.tests/ExecutorFacts.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Tanka.GraphQL.Fields; using Tanka.GraphQL.Language.Nodes.TypeSystem; +using Tanka.GraphQL.Request; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.ValueResolution; using Xunit; diff --git a/tests/graphql.tests/NestedDictionaryConverterFacts.cs b/tests/graphql.tests/NestedDictionaryConverterFacts.cs index 4d6fa332b..235502f7a 100644 --- a/tests/graphql.tests/NestedDictionaryConverterFacts.cs +++ b/tests/graphql.tests/NestedDictionaryConverterFacts.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Tanka.GraphQL.Json; using Xunit; namespace Tanka.GraphQL.Tests; public class NestedDictionaryConverterFacts { - public static readonly JsonSerializerOptions Options = new JsonSerializerOptions(JsonSerializerDefaults.Web) + public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web) { Converters = { @@ -16,42 +16,45 @@ public class NestedDictionaryConverterFacts }; [Fact] - public void Deserialize_simple_string_value() + public void Deserialize_federation_request() { /* Given */ var json = """ { - "key":"string" + "representations":[{"__typename":"Product","upc":"1"},{"__typename":"Product","upc":"2"},{ "__typename":"Product","upc":"3"}] } """; /* When */ - var actual = JsonSerializer.Deserialize>(json, Options); + IReadOnlyDictionary actual = + JsonSerializer.Deserialize?>(json, Options); /* Then */ - Assert.True(actual.ContainsKey("key")); - Assert.Equal("string", actual["key"]); + object actualValue = actual.Select("representations", 1, "__typename"); + Assert.Equal("Product", actualValue); } [Fact] - public void Deserialize_nested_string_value() + public void Deserialize_nested_array_with_object_value_with_string_property() { /* Given */ var json = """ { - "key": { - "nestedKey": "string" - } + "key": [{ + "Product": "test" + }] } """; /* When */ - var actual = JsonSerializer.Deserialize>(json, Options); + IReadOnlyDictionary actual = + JsonSerializer.Deserialize>(json, Options); /* Then */ - Assert.Equal("string", actual.NestedOrNull("key")!["nestedKey"]); + object actualValue = actual.Select("key", 0, "Product"); + Assert.Equal("test", actualValue); } [Fact] @@ -69,51 +72,53 @@ public void Deserialize_nested_object_with_object_with_string_value() """; /* When */ - var actual = JsonSerializer.Deserialize>(json, Options); + IReadOnlyDictionary actual = + JsonSerializer.Deserialize>(json, Options); /* Then */ - var actualValue = actual.Select("key", "nestedObject", "Product"); + object actualValue = actual.Select("key", "nestedObject", "Product"); Assert.Equal("test", actualValue); } [Fact] - public void Deserialize_nested_array_with_object_value_with_string_property() + public void Deserialize_nested_string_value() { /* Given */ var json = """ { - "key": [{ - "Product": "test" - }] + "key": { + "nestedKey": "string" + } } """; /* When */ - var actual = JsonSerializer.Deserialize>(json, Options); + IReadOnlyDictionary actual = + JsonSerializer.Deserialize>(json, Options); /* Then */ - var actualValue = actual.Select("key", 0, "Product"); - Assert.Equal("test", actualValue); + Assert.Equal("string", actual.NestedOrNull("key")!["nestedKey"]); } [Fact] - public void Deserialize_federation_request() + public void Deserialize_simple_string_value() { /* Given */ var json = """ { - "representations":[{"__typename":"Product","upc":"1"},{"__typename":"Product","upc":"2"},{ "__typename":"Product","upc":"3"}] + "key":"string" } """; /* When */ - var actual = JsonSerializer.Deserialize?>(json, Options); + IReadOnlyDictionary actual = + JsonSerializer.Deserialize>(json, Options); /* Then */ - var actualValue = actual.Select( "representations", 1, "__typename"); - Assert.Equal("Product", actualValue); + Assert.True(actual.ContainsKey("key")); + Assert.Equal("string", actual["key"]); } } \ No newline at end of file diff --git a/tests/graphql.tests/SubscriptionsFacts.cs b/tests/graphql.tests/SubscriptionsFacts.cs index 7cbd523d7..ea5608964 100644 --- a/tests/graphql.tests/SubscriptionsFacts.cs +++ b/tests/graphql.tests/SubscriptionsFacts.cs @@ -3,7 +3,6 @@ using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; -using Tanka.GraphQL.Subscriptions; using Tanka.GraphQL.TypeSystem; using Tanka.GraphQL.ValueResolution; using Xunit;