Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] @semanticNonNull support #7681

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/HotChocolate/Core/src/Abstractions/WellKnownDirectives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,14 @@ public static class WellKnownDirectives
/// The name of the @tag argument name.
/// </summary>
public const string Name = "name";

/// <summary>
/// The name of the @semanticNonNull directive.
/// </summary>
public const string SemanticNonNull = "semanticNonNull";

/// <summary>
/// The name of the @semanticNonNull argument levels.
/// </summary>
public const string Levels = "levels";
}
5 changes: 5 additions & 0 deletions src/HotChocolate/Core/src/Abstractions/WellKnownMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,9 @@ public static class WellKnownMiddleware
/// The key identifies the authorization middleware.
/// </summary>
public const string Authorization = "HotChocolate.Authorization";

/// <summary>
/// This key identifies the semantic-non-null middleware.
/// </summary>
public const string SemanticNonNull = "HotChocolate.Types.SemanticNonNull";
}
6 changes: 6 additions & 0 deletions src/HotChocolate/Core/src/Types/IReadOnlySchemaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ public interface IReadOnlySchemaOptions
/// </summary>
bool EnableStream { get; }

/// <summary>
/// Enables the @semanticNonNull directive.
/// This feature is experimental and might be changed or removed in the future.
/// </summary>
bool EnableSemanticNonNull { get; }

/// <summary>
/// Specifies the maximum allowed nodes that can be fetched at once through the nodes field.
/// </summary>
Expand Down
2,405 changes: 712 additions & 1,693 deletions src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/HotChocolate/Core/src/Types/Properties/TypeResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1003,4 +1003,10 @@ Type: `{0}`</value>
<data name="ObjectToDictionaryConverter_CycleInObjectGraph" xml:space="preserve">
<value>Cycle in object graph detected.</value>
</data>
<data name="SemanticNonNullDirectiveType_Description" xml:space="preserve">
<value></value>
</data>
<data name="SemanticNonNullDirectiveType_Levels_Description" xml:space="preserve">
<value></value>
</data>
</root>
3 changes: 2 additions & 1 deletion src/HotChocolate/Core/src/Types/SchemaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public partial class SchemaBuilder : ISchemaBuilder
[
typeof(IntrospectionTypeInterceptor),
typeof(InterfaceCompletionTypeInterceptor),
typeof(MiddlewareValidationTypeInterceptor)
typeof(MiddlewareValidationTypeInterceptor),
typeof(SemanticNonNullTypeInterceptor),
];

private SchemaOptions _options = new();
Expand Down
158 changes: 33 additions & 125 deletions src/HotChocolate/Core/src/Types/SchemaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,58 +15,34 @@ public class SchemaOptions : IReadOnlySchemaOptions
private BindingBehavior _defaultBindingBehavior = BindingBehavior.Implicit;
private FieldBindingFlags _defaultFieldBindingFlags = FieldBindingFlags.Instance;

/// <summary>
/// Gets or sets the name of the query type.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.QueryTypeName"/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that these crefs are needed.

public string? QueryTypeName { get; set; }

/// <summary>
/// Gets or sets the name of the mutation type.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.MutationTypeName"/>
public string? MutationTypeName { get; set; }

/// <summary>
/// Gets or sets the name of the subscription type.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.SubscriptionTypeName"/>
public string? SubscriptionTypeName { get; set; }

/// <summary>
/// Defines if the schema allows the query type to be omitted.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.StrictValidation"/>
public bool StrictValidation { get; set; } = true;

/// <summary>
/// Defines if the CSharp XML documentation shall be integrated.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.UseXmlDocumentation"/>
public bool UseXmlDocumentation { get; set; } = true;

/// <summary>
/// A delegate which defines the name of the XML documentation file to be read.
/// Only used if <seealso cref="UseXmlDocumentation"/> is true.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.ResolveXmlDocumentationFileName"/>
public Func<Assembly, string>? ResolveXmlDocumentationFileName { get; set; }

/// <summary>
/// Defines if fields shall be sorted by name.
/// Default: <c>false</c>
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.SortFieldsByName"/>
public bool SortFieldsByName { get; set; }

/// <summary>
/// Defines if types shall be removed from the schema that are
/// unreachable from the root types.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.RemoveUnreachableTypes"/>
public bool RemoveUnreachableTypes { get; set; }

/// <summary>
/// Defines if unused type system directives shall
/// be removed from the schema.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.RemoveUnusedTypeSystemDirectives"/>
public bool RemoveUnusedTypeSystemDirectives { get; set; } = true;

/// <summary>
/// Defines the default binding behavior.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultBindingBehavior"/>
public BindingBehavior DefaultBindingBehavior
{
get => _defaultBindingBehavior;
Expand All @@ -81,10 +57,7 @@ public BindingBehavior DefaultBindingBehavior
}
}

/// <summary>
/// Defines which members shall be by default inferred as GraphQL fields.
/// This default applies to <see cref="ObjectType"/> and <see cref="ObjectTypeExtension"/>.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultFieldBindingFlags"/>
public FieldBindingFlags DefaultFieldBindingFlags
{
get => _defaultFieldBindingFlags;
Expand All @@ -99,132 +72,66 @@ public FieldBindingFlags DefaultFieldBindingFlags
}
}

/// <summary>
/// Defines on which fields a middleware pipeline can be applied on.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.FieldMiddleware"/>
public FieldMiddlewareApplication FieldMiddleware { get; set; } =
FieldMiddlewareApplication.UserDefinedFields;

/// <summary>
/// Defines if the experimental directive introspection feature shall be enabled.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableDirectiveIntrospection"/>
public bool EnableDirectiveIntrospection { get; set; }

/// <summary>
/// The default directive visibility when directive introspection is enabled.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultDirectiveVisibility"/>
public DirectiveVisibility DefaultDirectiveVisibility { get; set; } =
DirectiveVisibility.Public;

/// <summary>
/// Defines that the default resolver execution strategy.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultResolverStrategy"/>
public ExecutionStrategy DefaultResolverStrategy { get; set; } =
ExecutionStrategy.Parallel;

/// <summary>
/// Defines if the order of important middleware components shall be validated.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.ValidatePipelineOrder"/>
public bool ValidatePipelineOrder { get; set; } = true;

/// <summary>
/// Defines if the runtime types of types shall be validated.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.StrictRuntimeTypeValidation"/>
public bool StrictRuntimeTypeValidation { get; set; }

/// <summary>
/// Defines a delegate that determines if a runtime
/// is an instance of an <see cref="ObjectType{T}"/>.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultIsOfTypeCheck"/>
public IsOfTypeFallback? DefaultIsOfTypeCheck { get; set; }

/// <summary>
/// Defines if the OneOf spec RFC is enabled. This feature is experimental.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableOneOf"/>
public bool EnableOneOf { get; set; } = true;

/// <summary>
/// Defines if the schema building process shall validate that all nodes are resolvable through `node`.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnsureAllNodesCanBeResolved"/>
public bool EnsureAllNodesCanBeResolved { get; set; } = true;

/// <summary>
/// Defines if flag enums should be inferred as object value nodes
/// </summary>
/// <example>
/// Given the following enum
/// <br/>
/// <code>
/// [Flags]
/// public enum Example { First, Second, Third }
///
/// public class Query { public Example Loopback(Example input) => input;
/// </code>
/// <br/>
/// The following schema is produced
/// <br/>
/// <code>
/// type Query {
/// loopback(input: ExampleFlagsInput!): ExampleFlags
/// }
///
/// type ExampleFlags {
/// isFirst: Boolean!
/// isSecond: Boolean!
/// isThird: Boolean!
/// }
///
/// input ExampleFlagsInput {
/// isFirst: Boolean
/// isSecond: Boolean
/// isThird: Boolean
/// }
/// </code>
/// </example>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableFlagEnums"/>
public bool EnableFlagEnums { get; set; }

/// <summary>
/// Enables the @defer directive.
/// Defer and stream both are at the moment preview features.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableDefer"/>
public bool EnableDefer { get; set; }

/// <summary>
/// Enables the @stream directive.
/// Defer and stream both are at the moment preview features.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableStream"/>
public bool EnableStream { get; set; }

/// <summary>
/// Specifies the maximum allowed nodes that can be fetched at once through the nodes field.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableSemanticNonNull"/>
public bool EnableSemanticNonNull { get; set; }

/// <inheritdoc cref="IReadOnlySchemaOptions.MaxAllowedNodeBatchSize"/>
public int MaxAllowedNodeBatchSize { get; set; } = 50;

/// <summary>
/// Specified if the leading I shall be stripped from the interface name.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.StripLeadingIFromInterface"/>
public bool StripLeadingIFromInterface { get; set; }

/// <summary>
/// Specifies that the @tag directive shall be registered with the type system.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.EnableTag"/>
public bool EnableTag { get; set; } = true;

/// <summary>
/// Defines the default dependency injection scope for query fields.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultQueryDependencyInjectionScope"/>
public DependencyInjectionScope DefaultQueryDependencyInjectionScope { get; set; } =
DependencyInjectionScope.Resolver;

/// <summary>
/// Defines the default dependency injection scope for mutation fields.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.DefaultMutationDependencyInjectionScope"/>
public DependencyInjectionScope DefaultMutationDependencyInjectionScope { get; set; } =
DependencyInjectionScope.Request;

/// <summary>
/// Defines if the root field pages shall be published to the promise cache.
/// </summary>
/// <inheritdoc cref="IReadOnlySchemaOptions.PublishRootFieldPagesToPromiseCache"/>
public bool PublishRootFieldPagesToPromiseCache { get; set; } = true;

/// <summary>
Expand Down Expand Up @@ -258,6 +165,7 @@ public static SchemaOptions FromOptions(IReadOnlySchemaOptions options)
EnableFlagEnums = options.EnableFlagEnums,
EnableDefer = options.EnableDefer,
EnableStream = options.EnableStream,
EnableSemanticNonNull = options.EnableSemanticNonNull,
DefaultFieldBindingFlags = options.DefaultFieldBindingFlags,
MaxAllowedNodeBatchSize = options.MaxAllowedNodeBatchSize,
StripLeadingIFromInterface = options.StripLeadingIFromInterface,
Expand Down
Loading
Loading