diff --git a/dictionary.txt b/dictionary.txt index 4a638cbba3c..b3091f4468b 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -18,6 +18,7 @@ BCPROCKS bfnrt blazor blazorwasm +Brontie Browsable BSON buildtransitive @@ -109,7 +110,6 @@ NSwag ntouches nwithin oncall -oneof OpenIddict opensgid OPTOUT diff --git a/src/HotChocolate/Caching/test/Caching.Tests/SchemaTests.cs b/src/HotChocolate/Caching/test/Caching.Tests/SchemaTests.cs index 23c5ef51de3..e681fad3337 100644 --- a/src/HotChocolate/Caching/test/Caching.Tests/SchemaTests.cs +++ b/src/HotChocolate/Caching/test/Caching.Tests/SchemaTests.cs @@ -48,13 +48,7 @@ enum CacheControlScope { "The `@cacheControl` directive may be provided for individual fields or entire object, interface or union types to provide caching hints to the executor." directive @cacheControl("The maximum amount of time this field's cached value is valid, in seconds." maxAge: Int "The maximum amount of time this field's cached value is valid in shared caches like CDNs, in seconds." sharedMaxAge: Int "If `true`, the field inherits the `maxAge` of its parent field." inheritMaxAge: Boolean "If `PRIVATE`, the field's value is specific to a single user. The default value is `PUBLIC`, which means the field's value is not tied to a single user." scope: CacheControlScope "The Vary HTTP response header describes the parts of the request message aside from the method and URL that influenced the content of the response it occurs in. Most often, this is used to create a cache key when content negotiation is in use." vary: [String]) on OBJECT | FIELD_DEFINITION | INTERFACE | UNION - """ - The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. - """ + "The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." directive @oneOf on INPUT_OBJECT """ diff --git a/src/HotChocolate/Core/src/Execution/Properties/Resources.Designer.cs b/src/HotChocolate/Core/src/Execution/Properties/Resources.Designer.cs index 8313f293a96..bf137efe381 100644 --- a/src/HotChocolate/Core/src/Execution/Properties/Resources.Designer.cs +++ b/src/HotChocolate/Core/src/Execution/Properties/Resources.Designer.cs @@ -11,32 +11,46 @@ namespace HotChocolate.Execution.Properties { using System; - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { - private static System.Resources.ResourceManager resourceMan; + private static global::System.Resources.ResourceManager resourceMan; - private static System.Globalization.CultureInfo resourceCulture; + private static global::System.Globalization.CultureInfo resourceCulture; - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Resources.ResourceManager ResourceManager { + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { get { - if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager("HotChocolate.Execution.Properties.Resources", typeof(Resources).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HotChocolate.Execution.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - internal static System.Globalization.CultureInfo Culture { + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -45,375 +59,561 @@ internal static System.Globalization.CultureInfo Culture { } } - internal static string ThrowHelper_FieldDoesNotExistOnType { + /// + /// Looks up a localized string similar to Serial execution tasks cannot be batched.. + /// + internal static string BatchExecutionTask_AddExecutionTask_SerialTasksNotAllowed { get { - return ResourceManager.GetString("ThrowHelper_FieldDoesNotExistOnType", resourceCulture); + return ResourceManager.GetString("BatchExecutionTask_AddExecutionTask_SerialTasksNotAllowed", resourceCulture); } } - internal static string ObjectBuffer_IsEmpty { + /// + /// Looks up a localized string similar to You can only read a response stream once.. + /// + internal static string DeferredResult_ReadResultsAsync_ReadOnlyOnce { get { - return ResourceManager.GetString("ObjectBuffer_IsEmpty", resourceCulture); + return ResourceManager.GetString("DeferredResult_ReadResultsAsync_ReadOnlyOnce", resourceCulture); } } - internal static string ObjectBuffer_IsUsedUp { + /// + /// Looks up a localized string similar to Detected a non-null violation in argument `{0}`.. + /// + internal static string ErrorHelper_ArgumentNonNullError_Message { get { - return ResourceManager.GetString("ObjectBuffer_IsUsedUp", resourceCulture); + return ResourceManager.GetString("ErrorHelper_ArgumentNonNullError_Message", resourceCulture); } } - internal static string PreparedSelection_ReadOnly { + /// + /// Looks up a localized string similar to The type `{0}` is not supported as list value.. + /// + internal static string ErrorHelper_ListValueIsNotSupported_Message { get { - return ResourceManager.GetString("PreparedSelection_ReadOnly", resourceCulture); + return ResourceManager.GetString("ErrorHelper_ListValueIsNotSupported_Message", resourceCulture); } } - internal static string DeferredResult_ReadResultsAsync_ReadOnlyOnce { + /// + /// Looks up a localized string similar to The request exceeded the configured timeout of `{0}`.. + /// + internal static string ErrorHelper_RequestTimeout { get { - return ResourceManager.GetString("DeferredResult_ReadResultsAsync_ReadOnlyOnce", resourceCulture); + return ResourceManager.GetString("ErrorHelper_RequestTimeout", resourceCulture); } } - internal static string ErrorHelper_ArgumentNonNullError_Message { + /// + /// Looks up a localized string similar to The specified root type `{0}` is not supported by this server.. + /// + internal static string ErrorHelper_RootTypeNotFound_Message { get { - return ResourceManager.GetString("ErrorHelper_ArgumentNonNullError_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_RootTypeNotFound_Message", resourceCulture); } } - internal static string ErrorHelper_UnableToResolveTheAbstractType_Message { + /// + /// Looks up a localized string similar to Either no compiled operation was found or the variables have not been coerced.. + /// + internal static string ErrorHelper_StateInvalidForOperationExecution_Message { get { - return ResourceManager.GetString("ErrorHelper_UnableToResolveTheAbstractType_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationExecution_Message", resourceCulture); } } - internal static string ErrorHelper_ListValueIsNotSupported_Message { + /// + /// Looks up a localized string similar to Either no query document exists or the document validation result is invalid.. + /// + internal static string ErrorHelper_StateInvalidForOperationResolver_Message { get { - return ResourceManager.GetString("ErrorHelper_ListValueIsNotSupported_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationResolver_Message", resourceCulture); } } - internal static string ErrorHelper_UnexpectedValueCompletionError_Message { + /// + /// Looks up a localized string similar to There is no operation on the context which can be used to coerce variables.. + /// + internal static string ErrorHelper_StateInvalidForOperationVariableCoercion_Message { get { - return ResourceManager.GetString("ErrorHelper_UnexpectedValueCompletionError_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationVariableCoercion_Message", resourceCulture); } } - internal static string ErrorHelper_RootTypeNotFound_Message { + /// + /// Looks up a localized string similar to Unable to resolve the abstract type `{0}`.. + /// + internal static string ErrorHelper_UnableToResolveTheAbstractType_Message { get { - return ResourceManager.GetString("ErrorHelper_RootTypeNotFound_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_UnableToResolveTheAbstractType_Message", resourceCulture); } } - internal static string ErrorHelper_StateInvalidForOperationResolver_Message { + /// + /// Looks up a localized string similar to Unexpected error during value completion.. + /// + internal static string ErrorHelper_UnexpectedValueCompletionError_Message { get { - return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationResolver_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_UnexpectedValueCompletionError_Message", resourceCulture); } } - internal static string ErrorHelper_StateInvalidForOperationVariableCoercion_Message { + /// + /// Looks up a localized string similar to Could not resolve the actual object type from `{0}` for the abstract type `{1}`.. + /// + internal static string ErrorHelper_ValueCompletion_CouldNotResolveAbstractType_Message { get { - return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationVariableCoercion_Message", resourceCulture); + return ResourceManager.GetString("ErrorHelper_ValueCompletion_CouldNotResolveAbstractType_Message", resourceCulture); } } - internal static string ErrorHelper_StateInvalidForOperationExecution_Message { + /// + /// Looks up a localized string similar to The query cannot be null or empty.. + /// + internal static string ExecutionRequestExecutorExtensions_ExecuteAsync_QueryCannotBeNullOrEmpty { get { - return ResourceManager.GetString("ErrorHelper_StateInvalidForOperationExecution_Message", resourceCulture); + return ResourceManager.GetString("ExecutionRequestExecutorExtensions_ExecuteAsync_QueryCannotBeNullOrEmpty", resourceCulture); } } - internal static string ErrorHelper_ValueCompletion_CouldNotResolveAbstractType_Message { + /// + /// Looks up a localized string similar to Only query results are supported.. + /// + internal static string ExecutionResultExtensions_OnlyQueryResults { get { - return ResourceManager.GetString("ErrorHelper_ValueCompletion_CouldNotResolveAbstractType_Message", resourceCulture); + return ResourceManager.GetString("ExecutionResultExtensions_OnlyQueryResults", resourceCulture); } } - internal static string ThrowHelper_VariableIsNotAnInputType_Message { + /// + /// Looks up a localized string similar to There is no argument with the name `{0}`.. + /// + internal static string MiddlewareContext_ReplaceArgument_InvalidKey { get { - return ResourceManager.GetString("ThrowHelper_VariableIsNotAnInputType_Message", resourceCulture); + return ResourceManager.GetString("MiddlewareContext_ReplaceArgument_InvalidKey", resourceCulture); } } - internal static string ThrowHelper_NonNullVariableIsNull_Message { + /// + /// Looks up a localized string similar to It is not allowed to replace the arguments with null.. + /// + internal static string MiddlewareContext_ReplaceArguments_NullNotAllowed { get { - return ResourceManager.GetString("ThrowHelper_NonNullVariableIsNull_Message", resourceCulture); + return ResourceManager.GetString("MiddlewareContext_ReplaceArguments_NullNotAllowed", resourceCulture); } } - internal static string ThrowHelper_VariableValueInvalidType_Message { + /// + /// Looks up a localized string similar to Buffer is full.. + /// + internal static string ObjectBuffer_IsEmpty { get { - return ResourceManager.GetString("ThrowHelper_VariableValueInvalidType_Message", resourceCulture); + return ResourceManager.GetString("ObjectBuffer_IsEmpty", resourceCulture); } } - internal static string ThrowHelper_VariableNotFound_Message { + /// + /// Looks up a localized string similar to Buffer is used up.. + /// + internal static string ObjectBuffer_IsUsedUp { get { - return ResourceManager.GetString("ThrowHelper_VariableNotFound_Message", resourceCulture); + return ResourceManager.GetString("ObjectBuffer_IsUsedUp", resourceCulture); } } - internal static string ThrowHelper_VariableNotOfType_Message { + /// + /// Looks up a localized string similar to The specified selection does not have a selection set.. + /// + internal static string Operation_GetPossibleTypes_NoSelectionSet { get { - return ResourceManager.GetString("ThrowHelper_VariableNotOfType_Message", resourceCulture); + return ResourceManager.GetString("Operation_GetPossibleTypes_NoSelectionSet", resourceCulture); } } - internal static string ThrowHelper_RootTypeNotSupported_Message { + /// + /// Looks up a localized string similar to The operation selection set is empty.. + /// + internal static string OperationCompiler_Compile_SelectionSetIsEmpty { get { - return ResourceManager.GetString("ThrowHelper_RootTypeNotSupported_Message", resourceCulture); + return ResourceManager.GetString("OperationCompiler_Compile_SelectionSetIsEmpty", resourceCulture); } } - internal static string ThrowHelper_SubscriptionExecutor_ContextInvalidState_Message { + /// + /// Looks up a localized string similar to The document did not contain a fragment definition with the name `{0}`.. + /// + internal static string OperationCompiler_FragmentNotFound { get { - return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_ContextInvalidState_Message", resourceCulture); + return ResourceManager.GetString("OperationCompiler_FragmentNotFound", resourceCulture); } } - internal static string ThrowHelper_SubscriptionExecutor_SubscriptionsMustHaveOneField_Message { + /// + /// Looks up a localized string similar to The operation compiler only allows for 64 unique include conditions.. + /// + internal static string OperationCompiler_ToManyIncludeConditions { get { - return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_SubscriptionsMustHaveOneField_Message", resourceCulture); + return ResourceManager.GetString("OperationCompiler_ToManyIncludeConditions", resourceCulture); } } - internal static string ThrowHelper_SubscriptionExecutor_NoSubscribeResolver_Message { + /// + /// Looks up a localized string similar to The query type could not be casted to {0}.. + /// + internal static string OperationContext_GetQueryRoot_InvalidCast { get { - return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_NoSubscribeResolver_Message", resourceCulture); + return ResourceManager.GetString("OperationContext_GetQueryRoot_InvalidCast", resourceCulture); } } - internal static string ThrowHelper_ResolverContext_LiteralsNotSupported_Message { + /// + /// Looks up a localized string similar to The selection is read-only.. + /// + internal static string PreparedSelection_ReadOnly { get { - return ResourceManager.GetString("ThrowHelper_ResolverContext_LiteralsNotSupported_Message", resourceCulture); + return ResourceManager.GetString("PreparedSelection_ReadOnly", resourceCulture); } } - internal static string ThrowHelper_ResolverContext_CannotConvertArgument_Message { + /// + /// Looks up a localized string similar to Invalid fragment id.. + /// + internal static string QueryPlan_InvalidFragmentId { get { - return ResourceManager.GetString("ThrowHelper_ResolverContext_CannotConvertArgument_Message", resourceCulture); + return ResourceManager.GetString("QueryPlan_InvalidFragmentId", resourceCulture); } } - internal static string ThrowHelper_ResolverContext_LiteralNotCompatible_Message { + /// + /// Looks up a localized string similar to The specified convention type is not supported.. + /// + internal static string RequestExecutorBuilder_Convention_NotSupported { get { - return ResourceManager.GetString("ThrowHelper_ResolverContext_LiteralNotCompatible_Message", resourceCulture); + return ResourceManager.GetString("RequestExecutorBuilder_Convention_NotSupported", resourceCulture); } } - internal static string ThrowHelper_ResolverContext_ArgumentDoesNotExist_Message { + /// + /// Looks up a localized string similar to Its not allowed to set `items` and `data` at the same time.. + /// + internal static string ResultBuilder_DataAndItemsNotAllowed { get { - return ResourceManager.GetString("ThrowHelper_ResolverContext_ArgumentDoesNotExist_Message", resourceCulture); + return ResourceManager.GetString("ResultBuilder_DataAndItemsNotAllowed", resourceCulture); } } - internal static string ThrowHelper_OperationResolverHelper_NoOperationFound_Message { + /// + /// Looks up a localized string similar to A GraphQL result must have data, errors or both.. + /// + internal static string ResultHelper_BuildResult_InvalidResult { get { - return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_NoOperationFound_Message", resourceCulture); + return ResourceManager.GetString("ResultHelper_BuildResult_InvalidResult", resourceCulture); } } - internal static string ThrowHelper_OperationResolverHelper_MultipleOperation_Message { + /// + /// Looks up a localized string similar to Unable to create the operation type `{0}` instance. Try adding the following service: `services.AddScoped<{1}>();`. + /// + internal static string RootValueResolver_Resolve_CannotCreateInstance { get { - return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_MultipleOperation_Message", resourceCulture); + return ResourceManager.GetString("RootValueResolver_Resolve_CannotCreateInstance", resourceCulture); } } - internal static string ThrowHelper_OperationResolverHelper_InvalidOperationName_Message { + /// + /// Looks up a localized string similar to The provided response name must be the same as on the selection.. + /// + internal static string SelectionSetOptimizerContext_AddSelection_ResponseNameNotTheSame { get { - return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_InvalidOperationName_Message", resourceCulture); + return ResourceManager.GetString("SelectionSetOptimizerContext_AddSelection_ResponseNameNotTheSame", resourceCulture); } } - internal static string ThrowHelper_BatchExecutor_CannotSerializeVariable_Message { + /// + /// Looks up a localized string similar to The `{0}` is not a valid GraphQL field name.. + /// + internal static string SelectionSetOptimizerContext_InvalidFieldName { get { - return ResourceManager.GetString("ThrowHelper_BatchExecutor_CannotSerializeVariable_Message", resourceCulture); + return ResourceManager.GetString("SelectionSetOptimizerContext_InvalidFieldName", resourceCulture); } } - internal static string ThrowHelper_CollectVariablesVisitor_NoCompatibleType_Message { + /// + /// Looks up a localized string similar to This SelectionVariants instance is read-only.. + /// + internal static string SelectionVariants_ReadOnly { get { - return ResourceManager.GetString("ThrowHelper_CollectVariablesVisitor_NoCompatibleType_Message", resourceCulture); + return ResourceManager.GetString("SelectionVariants_ReadOnly", resourceCulture); } } - internal static string ThrowHelper_FieldVisibility_ValueNotSupported_Message { + /// + /// Looks up a localized string similar to The specified type `{0}` is not a possible type to this selection set.. + /// + internal static string SelectionVariants_TypeContextInvalid { get { - return ResourceManager.GetString("ThrowHelper_FieldVisibility_ValueNotSupported_Message", resourceCulture); + return ResourceManager.GetString("SelectionVariants_TypeContextInvalid", resourceCulture); } } - internal static string ThrowHelper_QueryCompiler_CompositeTypeSelectionSet_Message { + /// + /// Looks up a localized string similar to Could not serialize the specified variable `{0}`.. + /// + internal static string ThrowHelper_BatchExecutor_CannotSerializeVariable_Message { get { - return ResourceManager.GetString("ThrowHelper_QueryCompiler_CompositeTypeSelectionSet_Message", resourceCulture); + return ResourceManager.GetString("ThrowHelper_BatchExecutor_CannotSerializeVariable_Message", resourceCulture); } } - internal static string ThrowHelper_OperationExecutionMiddleware_NoBatchDispatcher_Message { + /// + /// Looks up a localized string similar to Unable to find a compatible input type for the exported object type.. + /// + internal static string ThrowHelper_CollectVariablesVisitor_NoCompatibleType_Message { get { - return ResourceManager.GetString("ThrowHelper_OperationExecutionMiddleware_NoBatchDispatcher_Message", resourceCulture); + return ResourceManager.GetString("ThrowHelper_CollectVariablesVisitor_NoCompatibleType_Message", resourceCulture); } } - internal static string OperationCompiler_Compile_SelectionSetIsEmpty { + /// + /// Looks up a localized string similar to Field `{0}` does not exist on type `{1}`.. + /// + internal static string ThrowHelper_FieldDoesNotExistOnType { get { - return ResourceManager.GetString("OperationCompiler_Compile_SelectionSetIsEmpty", resourceCulture); + return ResourceManager.GetString("ThrowHelper_FieldDoesNotExistOnType", resourceCulture); } } - internal static string ExecutionRequestExecutorExtensions_ExecuteAsync_QueryCannotBeNullOrEmpty { + /// + /// Looks up a localized string similar to The skip/include if-argument value has to be a 'Boolean'.. + /// + internal static string ThrowHelper_FieldVisibility_ValueNotSupported_Message { get { - return ResourceManager.GetString("ExecutionRequestExecutorExtensions_ExecuteAsync_QueryCannotBeNullOrEmpty", resourceCulture); + return ResourceManager.GetString("ThrowHelper_FieldVisibility_ValueNotSupported_Message", resourceCulture); } } - internal static string RequestExecutorBuilder_Convention_NotSupported { + /// + /// Looks up a localized string similar to The {0} only supports formatting `IQueryResult`.. + /// + internal static string ThrowHelper_JsonFormatter_ResultNotSupported { get { - return ResourceManager.GetString("RequestExecutorBuilder_Convention_NotSupported", resourceCulture); + return ResourceManager.GetString("ThrowHelper_JsonFormatter_ResultNotSupported", resourceCulture); } } - internal static string RootValueResolver_Resolve_CannotCreateInstance { + /// + /// Looks up a localized string similar to Variable `{0}` is required.. + /// + internal static string ThrowHelper_NonNullVariableIsNull_Message { get { - return ResourceManager.GetString("RootValueResolver_Resolve_CannotCreateInstance", resourceCulture); + return ResourceManager.GetString("ThrowHelper_NonNullVariableIsNull_Message", resourceCulture); } } - internal static string OperationContext_GetQueryRoot_InvalidCast { + /// + /// Looks up a localized string similar to Value for OneOf field {0} must be non-null.. + /// + internal static string ThrowHelper_OneOfFieldMustBeNonNull { get { - return ResourceManager.GetString("OperationContext_GetQueryRoot_InvalidCast", resourceCulture); + return ResourceManager.GetString("ThrowHelper_OneOfFieldMustBeNonNull", resourceCulture); } } - internal static string ErrorHelper_RequestTimeout { + /// + /// Looks up a localized string similar to The specified selection does not have a selection set.. + /// + internal static string ThrowHelper_Operation_NoSelectionSet { get { - return ResourceManager.GetString("ErrorHelper_RequestTimeout", resourceCulture); + return ResourceManager.GetString("ThrowHelper_Operation_NoSelectionSet", resourceCulture); } } - internal static string ResultHelper_BuildResult_InvalidResult { + /// + /// Looks up a localized string similar to Make sure that you have registered an IBatchDispatcher with your scoped request services.. + /// + internal static string ThrowHelper_OperationExecutionMiddleware_NoBatchDispatcher_Message { get { - return ResourceManager.GetString("ResultHelper_BuildResult_InvalidResult", resourceCulture); + return ResourceManager.GetString("ThrowHelper_OperationExecutionMiddleware_NoBatchDispatcher_Message", resourceCulture); } } - internal static string BatchExecutionTask_AddExecutionTask_SerialTasksNotAllowed { + /// + /// Looks up a localized string similar to The specified operation `{0}` cannot be found.. + /// + internal static string ThrowHelper_OperationResolverHelper_InvalidOperationName_Message { get { - return ResourceManager.GetString("BatchExecutionTask_AddExecutionTask_SerialTasksNotAllowed", resourceCulture); + return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_InvalidOperationName_Message", resourceCulture); } } - internal static string QueryPlan_InvalidFragmentId { + /// + /// Looks up a localized string similar to The operation name can only be omitted if there is just one operation in a GraphQL document.. + /// + internal static string ThrowHelper_OperationResolverHelper_MultipleOperation_Message { get { - return ResourceManager.GetString("QueryPlan_InvalidFragmentId", resourceCulture); + return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_MultipleOperation_Message", resourceCulture); } } - internal static string WorkBacklog_NotFullyInitialized { + /// + /// Looks up a localized string similar to There are no operations in the GraphQL document.. + /// + internal static string ThrowHelper_OperationResolverHelper_NoOperationFound_Message { get { - return ResourceManager.GetString("WorkBacklog_NotFullyInitialized", resourceCulture); + return ResourceManager.GetString("ThrowHelper_OperationResolverHelper_NoOperationFound_Message", resourceCulture); } } - internal static string ThrowHelper_ResolverContext_CannotCastParent { + /// + /// Looks up a localized string similar to A composite type always needs to specify a selection set.. + /// + internal static string ThrowHelper_QueryCompiler_CompositeTypeSelectionSet_Message { get { - return ResourceManager.GetString("ThrowHelper_ResolverContext_CannotCastParent", resourceCulture); + return ResourceManager.GetString("ThrowHelper_QueryCompiler_CompositeTypeSelectionSet_Message", resourceCulture); } } - internal static string ExecutionResultExtensions_OnlyQueryResults { + /// + /// Looks up a localized string similar to There was no argument with the name `{0}` found on the field `{1}`.. + /// + internal static string ThrowHelper_ResolverContext_ArgumentDoesNotExist_Message { get { - return ResourceManager.GetString("ExecutionResultExtensions_OnlyQueryResults", resourceCulture); + return ResourceManager.GetString("ThrowHelper_ResolverContext_ArgumentDoesNotExist_Message", resourceCulture); } } - internal static string SelectionVariants_ReadOnly { + /// + /// Looks up a localized string similar to The resolver parent type of field `{0}` is `{1}` but the resolver requested the type `{2}`. The resolver was unable to cast the parent type to the requested type.. + /// + internal static string ThrowHelper_ResolverContext_CannotCastParent { get { - return ResourceManager.GetString("SelectionVariants_ReadOnly", resourceCulture); + return ResourceManager.GetString("ThrowHelper_ResolverContext_CannotCastParent", resourceCulture); } } - internal static string OperationCompiler_FragmentNotFound { + /// + /// Looks up a localized string similar to Unable to convert the value of the argument `{0}` to `{1}`. Check if the requested type is correct or register a custom type converter.. + /// + internal static string ThrowHelper_ResolverContext_CannotConvertArgument_Message { get { - return ResourceManager.GetString("OperationCompiler_FragmentNotFound", resourceCulture); + return ResourceManager.GetString("ThrowHelper_ResolverContext_CannotConvertArgument_Message", resourceCulture); } } - internal static string SelectionSetOptimizerContext_InvalidFieldName { + /// + /// Looks up a localized string similar to The argument literal representation is `{0}` which is not compatible with the request literal type `{1}`.. + /// + internal static string ThrowHelper_ResolverContext_LiteralNotCompatible_Message { get { - return ResourceManager.GetString("SelectionSetOptimizerContext_InvalidFieldName", resourceCulture); + return ResourceManager.GetString("ThrowHelper_ResolverContext_LiteralNotCompatible_Message", resourceCulture); } } - internal static string OperationCompiler_ToManyIncludeConditions { + /// + /// Looks up a localized string similar to The ArgumentValue method on the resolver context only allows for runtime values. If you want to retrieve the argument value as GraphQL literal use the ArgumentLiteral method instead.. + /// + internal static string ThrowHelper_ResolverContext_LiteralsNotSupported_Message { get { - return ResourceManager.GetString("OperationCompiler_ToManyIncludeConditions", resourceCulture); + return ResourceManager.GetString("ThrowHelper_ResolverContext_LiteralsNotSupported_Message", resourceCulture); } } - internal static string SelectionVariants_TypeContextInvalid { + /// + /// Looks up a localized string similar to The root type `{0}` is not supported.. + /// + internal static string ThrowHelper_RootTypeNotSupported_Message { get { - return ResourceManager.GetString("SelectionVariants_TypeContextInvalid", resourceCulture); + return ResourceManager.GetString("ThrowHelper_RootTypeNotSupported_Message", resourceCulture); } } + /// + /// Looks up a localized string similar to The type {0} was already added.. + /// internal static string ThrowHelper_SelectionSet_TypeAlreadyAdded { get { return ResourceManager.GetString("ThrowHelper_SelectionSet_TypeAlreadyAdded", resourceCulture); } } - internal static string ThrowHelper_OneOfFieldMustBeNonNull { + /// + /// Looks up a localized string similar to The request context is in an invalid state for subscriptions.. + /// + internal static string ThrowHelper_SubscriptionExecutor_ContextInvalidState_Message { get { - return ResourceManager.GetString("ThrowHelper_OneOfFieldMustBeNonNull", resourceCulture); + return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_ContextInvalidState_Message", resourceCulture); } } - internal static string ThrowHelper_Operation_NoSelectionSet { + /// + /// Looks up a localized string similar to You must declare a subscribe resolver for subscription fields.. + /// + internal static string ThrowHelper_SubscriptionExecutor_NoSubscribeResolver_Message { get { - return ResourceManager.GetString("ThrowHelper_Operation_NoSelectionSet", resourceCulture); + return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_NoSubscribeResolver_Message", resourceCulture); } } - internal static string ThrowHelper_JsonFormatter_ResultNotSupported { + /// + /// Looks up a localized string similar to Subscription queries must have exactly one root field.. + /// + internal static string ThrowHelper_SubscriptionExecutor_SubscriptionsMustHaveOneField_Message { get { - return ResourceManager.GetString("ThrowHelper_JsonFormatter_ResultNotSupported", resourceCulture); + return ResourceManager.GetString("ThrowHelper_SubscriptionExecutor_SubscriptionsMustHaveOneField_Message", resourceCulture); } } - internal static string ResultBuilder_DataAndItemsNotAllowed { + /// + /// Looks up a localized string similar to Variable `{0}` is not an input type.. + /// + internal static string ThrowHelper_VariableIsNotAnInputType_Message { get { - return ResourceManager.GetString("ResultBuilder_DataAndItemsNotAllowed", resourceCulture); + return ResourceManager.GetString("ThrowHelper_VariableIsNotAnInputType_Message", resourceCulture); } } - internal static string MiddlewareContext_ReplaceArgument_InvalidKey { + /// + /// Looks up a localized string similar to The variable with the name `{0}` does not exist.. + /// + internal static string ThrowHelper_VariableNotFound_Message { get { - return ResourceManager.GetString("MiddlewareContext_ReplaceArgument_InvalidKey", resourceCulture); + return ResourceManager.GetString("ThrowHelper_VariableNotFound_Message", resourceCulture); } } - internal static string VariableValueOrLiteral_NullNotAllowed { + /// + /// Looks up a localized string similar to The variable with the name `{0}` is not of the requested type `{1}`.. + /// + internal static string ThrowHelper_VariableNotOfType_Message { get { - return ResourceManager.GetString("VariableValueOrLiteral_NullNotAllowed", resourceCulture); + return ResourceManager.GetString("ThrowHelper_VariableNotOfType_Message", resourceCulture); } } - internal static string Operation_GetPossibleTypes_NoSelectionSet { + /// + /// Looks up a localized string similar to Variable `{0}` got an invalid value.. + /// + internal static string ThrowHelper_VariableValueInvalidType_Message { get { - return ResourceManager.GetString("Operation_GetPossibleTypes_NoSelectionSet", resourceCulture); + return ResourceManager.GetString("ThrowHelper_VariableValueInvalidType_Message", resourceCulture); } } - internal static string MiddlewareContext_ReplaceArguments_NullNotAllowed { + /// + /// Looks up a localized string similar to The runtime value can only be null if the literal is also null.. + /// + internal static string VariableValueOrLiteral_NullNotAllowed { get { - return ResourceManager.GetString("MiddlewareContext_ReplaceArguments_NullNotAllowed", resourceCulture); + return ResourceManager.GetString("VariableValueOrLiteral_NullNotAllowed", resourceCulture); } } - internal static string SelectionSetOptimizerContext_AddSelection_ResponseNameNotTheSame { + /// + /// Looks up a localized string similar to The WorkBacklog is not fully initialized.. + /// + internal static string WorkBacklog_NotFullyInitialized { get { - return ResourceManager.GetString("SelectionSetOptimizerContext_AddSelection_ResponseNameNotTheSame", resourceCulture); + return ResourceManager.GetString("WorkBacklog_NotFullyInitialized", resourceCulture); } } } diff --git a/src/HotChocolate/Core/src/Execution/Properties/Resources.resx b/src/HotChocolate/Core/src/Execution/Properties/Resources.resx index 97cbae00fb1..047fa3518de 100644 --- a/src/HotChocolate/Core/src/Execution/Properties/Resources.resx +++ b/src/HotChocolate/Core/src/Execution/Properties/Resources.resx @@ -277,7 +277,7 @@ The type {0} was already added. - Value for oneof field {0} must be non-null. + Value for OneOf field {0} must be non-null. The specified selection does not have a selection set. diff --git a/src/HotChocolate/Core/src/Types.Shared/BuiltInTypes.cs b/src/HotChocolate/Core/src/Types.Shared/BuiltInTypes.cs index 36280a3c511..ba792c03e00 100644 --- a/src/HotChocolate/Core/src/Types.Shared/BuiltInTypes.cs +++ b/src/HotChocolate/Core/src/Types.Shared/BuiltInTypes.cs @@ -28,7 +28,8 @@ public static class BuiltInTypes WellKnownDirectives.Deprecated, WellKnownDirectives.Defer, WellKnownDirectives.Stream, - WellKnownDirectives.SpecifiedBy + WellKnownDirectives.SpecifiedBy, + WellKnownDirectives.OneOf ]; public static bool IsBuiltInType(string name) diff --git a/src/HotChocolate/Core/src/Types.Shared/WellKnownDirectives.cs b/src/HotChocolate/Core/src/Types.Shared/WellKnownDirectives.cs index 35527212617..62a1fecea18 100644 --- a/src/HotChocolate/Core/src/Types.Shared/WellKnownDirectives.cs +++ b/src/HotChocolate/Core/src/Types.Shared/WellKnownDirectives.cs @@ -9,4 +9,5 @@ internal static class WellKnownDirectives public const string Deprecated = "deprecated"; public const string SpecifiedBy = "specifiedBy"; public const string DeprecationReasonArgument = "reason"; + public const string OneOf = "oneOf"; } diff --git a/src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs b/src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs index 75d5f80b31f..1e7416acecf 100644 --- a/src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs +++ b/src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs @@ -989,11 +989,11 @@ internal static string ErrorHelper_ObjectType_UnableToInferOrResolveType { } /// - /// Looks up a localized string similar to Oneof Input Object `{0}` must only have nullable fields without default values. Edit your type and make the field{1} `{2}` nullable and remove any defaults.. + /// Looks up a localized string similar to OneOf Input Object `{0}` must only have nullable fields without default values. Edit your type and make the field{1} `{2}` nullable and remove any defaults.. /// - internal static string ErrorHelper_OneofInputObjectMustHaveNullableFieldsWithoutDefaults { + internal static string ErrorHelper_OneOfInputObjectMustHaveNullableFieldsWithoutDefaults { get { - return ResourceManager.GetString("ErrorHelper_OneofInputObjectMustHaveNullableFieldsWithoutDefaults", resourceCulture); + return ResourceManager.GetString("ErrorHelper_OneOfInputObjectMustHaveNullableFieldsWithoutDefaults", resourceCulture); } } @@ -1529,11 +1529,7 @@ internal static string ObjectTypeExtension_CannotMerge { } /// - /// Looks up a localized string similar to The `@oneOf` directive is used within the type system definition language - /// to indicate: - /// - /// - an Input Object is a Oneof Input Object, or - /// - an Object Type's Field is a Oneof Field.. + /// Looks up a localized string similar to The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object.. /// internal static string OneOfDirectiveType_Description { get { @@ -2370,7 +2366,7 @@ internal static string ThrowHelper_NonNullInputViolation { } /// - /// Looks up a localized string similar to `null` was set to the field `{0}`of the Oneof Input Object `{1}`. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. + /// Looks up a localized string similar to `null` was set to the field `{0}`of the OneOf Input Object `{1}`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. /// internal static string ThrowHelper_OneOfFieldIsNull { get { @@ -2379,7 +2375,7 @@ internal static string ThrowHelper_OneOfFieldIsNull { } /// - /// Looks up a localized string similar to More than one field of the Oneof Input Object `{0}` is set. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. + /// Looks up a localized string similar to More than one field of the OneOf Input Object `{0}` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. /// internal static string ThrowHelper_OneOfMoreThanOneFieldSet { get { @@ -2388,7 +2384,7 @@ internal static string ThrowHelper_OneOfMoreThanOneFieldSet { } /// - /// Looks up a localized string similar to The Oneof Input Objects `{0}` require that exactly one field must be supplied and that field must not be `null`. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. + /// Looks up a localized string similar to The OneOf Input Objects `{0}` require that exactly one field must be supplied and that field must not be `null`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.. /// internal static string ThrowHelper_OneOfNoFieldSet { get { diff --git a/src/HotChocolate/Core/src/Types/Properties/TypeResources.resx b/src/HotChocolate/Core/src/Types/Properties/TypeResources.resx index a73b5767ccc..6ff7ea8c7e1 100644 --- a/src/HotChocolate/Core/src/Types/Properties/TypeResources.resx +++ b/src/HotChocolate/Core/src/Types/Properties/TypeResources.resx @@ -700,20 +700,16 @@ Type: `{0}` The fieldName cannot be null or empty. - The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. + The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object. - The Oneof Input Objects `{0}` require that exactly one field must be supplied and that field must not be `null`. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. + The OneOf Input Objects `{0}` require that exactly one field must be supplied and that field must not be `null`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. - More than one field of the Oneof Input Object `{0}` is set. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. + More than one field of the OneOf Input Object `{0}` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. - `null` was set to the field `{0}`of the Oneof Input Object `{1}`. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. + `null` was set to the field `{0}`of the OneOf Input Object `{1}`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null. Member is not a method! @@ -880,8 +876,8 @@ Type: `{0}` The argument `{0}` of the implemented field `{1}` must be defined. The field `{2}` must include an argument of the same name for every argument defined on the implemented field of the interface type `{3}`. - - Oneof Input Object `{0}` must only have nullable fields without default values. Edit your type and make the field{1} `{2}` nullable and remove any defaults. + + OneOf Input Object `{0}` must only have nullable fields without default values. Edit your type and make the field{1} `{2}` nullable and remove any defaults. Cannot reference Input Object `{0}` within itself through a series of non-null fields `{1}`. diff --git a/src/HotChocolate/Core/src/Types/Types/Directives/OneOfAttribute.cs b/src/HotChocolate/Core/src/Types/Types/Directives/OneOfAttribute.cs index f7b6d45a1d6..da99af69824 100644 --- a/src/HotChocolate/Core/src/Types/Types/Directives/OneOfAttribute.cs +++ b/src/HotChocolate/Core/src/Types/Types/Directives/OneOfAttribute.cs @@ -4,7 +4,7 @@ namespace HotChocolate.Types; /// /// The `@oneOf` directive is used within the type system definition language -/// to indicate an Input Object is a Oneof Input Object. +/// to indicate an Input Object is a OneOf Input Object. /// /// /// input UserUniqueCondition @oneOf { diff --git a/src/HotChocolate/Core/src/Types/Types/Directives/OneOfDirectiveType.cs b/src/HotChocolate/Core/src/Types/Types/Directives/OneOfDirectiveType.cs index 4915f66df8d..2b074a26775 100644 --- a/src/HotChocolate/Core/src/Types/Types/Directives/OneOfDirectiveType.cs +++ b/src/HotChocolate/Core/src/Types/Types/Directives/OneOfDirectiveType.cs @@ -4,7 +4,7 @@ namespace HotChocolate.Types; /// /// The `@oneOf` directive is used within the type system definition language -/// to indicate an Input Object is a Oneof Input Object. +/// to indicate an Input Object is a OneOf Input Object. /// /// /// input UserUniqueCondition @oneOf { diff --git a/src/HotChocolate/Core/src/Types/Types/Extensions/InputObjectTypeDescriptorExtensions.cs b/src/HotChocolate/Core/src/Types/Types/Extensions/InputObjectTypeDescriptorExtensions.cs index 96b2c12984e..2cc5aa87e55 100644 --- a/src/HotChocolate/Core/src/Types/Types/Extensions/InputObjectTypeDescriptorExtensions.cs +++ b/src/HotChocolate/Core/src/Types/Types/Extensions/InputObjectTypeDescriptorExtensions.cs @@ -40,7 +40,7 @@ public static IInputObjectTypeDescriptor Ignore( } /// - /// Defines an input object type as a oneof input object type + /// Defines an input object type as a OneOf input object type /// where only ever one field can hold a value. /// /// @@ -60,7 +60,7 @@ public static IInputObjectTypeDescriptor OneOf(this IInputObjectTypeDescriptor d } /// - /// Defines an input object type as a oneof input object type + /// Defines an input object type as a OneOf input object type /// where only ever one field can hold a value. /// /// diff --git a/src/HotChocolate/Core/src/Types/Types/Introspection/__Type.cs b/src/HotChocolate/Core/src/Types/Types/Introspection/__Type.cs index 9b7516287b2..f7dcb58cd08 100644 --- a/src/HotChocolate/Core/src/Types/Types/Introspection/__Type.cs +++ b/src/HotChocolate/Core/src/Types/Types/Introspection/__Type.cs @@ -85,9 +85,9 @@ protected override ObjectTypeConfiguration CreateConfiguration(ITypeDiscoveryCon if (context.DescriptorContext.Options.EnableOneOf) { - def.Fields.Add(new(Names.OneOf, + def.Fields.Add(new(Names.IsOneOf, type: booleanType, - pureResolver: Resolvers.OneOf)); + pureResolver: Resolvers.IsOneOf)); } if (context.DescriptorContext.Options.EnableDirectiveIntrospection) @@ -160,7 +160,7 @@ public static object Kind(IResolverContext context) _ => null }; - public static object? OneOf(IResolverContext context) + public static object? IsOneOf(IResolverContext context) => context.Parent() is IInputObjectTypeDefinition iot ? iot.Directives.ContainsName(DirectiveNames.OneOf.Name) : null; @@ -191,7 +191,7 @@ public static class Names public const string EnumValues = "enumValues"; public const string InputFields = "inputFields"; public const string OfType = "ofType"; - public const string OneOf = "oneOf"; + public const string IsOneOf = "isOneOf"; public const string SpecifiedByUrl = "specifiedByURL"; public const string IncludeDeprecated = "includeDeprecated"; public const string AppliedDirectives = "appliedDirectives"; diff --git a/src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs b/src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs index c3c9d3d871c..f545c41db3c 100644 --- a/src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs +++ b/src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs @@ -183,7 +183,7 @@ public static ISchemaError OneOfInputObjectMustHaveNullableFieldsWithoutDefaults string[] fieldNames) => SchemaErrorBuilder.New() .SetMessage( - ErrorHelper_OneofInputObjectMustHaveNullableFieldsWithoutDefaults, + ErrorHelper_OneOfInputObjectMustHaveNullableFieldsWithoutDefaults, type.Name, fieldNames.Length is 1 ? string.Empty : "s", string.Join(", ", fieldNames)) diff --git a/src/HotChocolate/Core/src/Validation/ErrorHelper.cs b/src/HotChocolate/Core/src/Validation/ErrorHelper.cs index 8ce0212a3a7..540d92530e9 100644 --- a/src/HotChocolate/Core/src/Validation/ErrorHelper.cs +++ b/src/HotChocolate/Core/src/Validation/ErrorHelper.cs @@ -36,6 +36,24 @@ public static IError VariableNotDeclared( .Build(); } + public static IError OneOfVariableIsNotCompatible( + this DocumentValidatorContext context, + VariableNode variable, + VariableDefinitionNode variableDefinition) + { + var variableName = variableDefinition.Variable.Name.Value; + + return ErrorBuilder.New() + .SetMessage( + Resources.ErrorHelper_OneOfVariableIsNotCompatible, + variableName) + .AddLocation(variable) + .SetPath(context.CreateErrorPath()) + .SetExtension("variable", variableName) + .SpecifiedBy("sec-All-Variable-Usages-are-Allowed") + .Build(); + } + public static IError VariableIsNotCompatible( this DocumentValidatorContext context, VariableNode variable, @@ -649,7 +667,7 @@ public static IError OneOfMustHaveExactlyOneField( .AddLocation(node) .SetPath(context.CreateErrorPath()) .SetExtension(nameof(type), type.Name) - .SpecifiedBy("sec-OneOf-Input-Objects-Have-Exactly-One-Field", rfc: 825) + .SpecifiedBy("sec-All-Variable-Usages-Are-Allowed", rfc: 825) .Build(); public static IError OneOfVariablesMustBeNonNull( @@ -666,7 +684,7 @@ public static IError OneOfVariablesMustBeNonNull( .AddLocation(node) .SetPath(context.CreateErrorPath()) .SetFieldCoordinate(fieldCoordinate) - .SpecifiedBy("sec-Oneof–Input-Objects-Have-Exactly-One-Field", rfc: 825) + .SpecifiedBy("sec-All-Variable-Usages-Are-Allowed", rfc: 825) .Build(); public static IError SkipAndIncludeNotAllowedOnSubscriptionRootField( diff --git a/src/HotChocolate/Core/src/Validation/Properties/Resources.Designer.cs b/src/HotChocolate/Core/src/Validation/Properties/Resources.Designer.cs index 418b4aaa7b2..2ef57139892 100644 --- a/src/HotChocolate/Core/src/Validation/Properties/Resources.Designer.cs +++ b/src/HotChocolate/Core/src/Validation/Properties/Resources.Designer.cs @@ -339,7 +339,7 @@ internal static string ErrorHelper_NoSelectionOnRootType { } /// - /// Looks up a localized string similar to The Oneof Input Object `{0}` requires that exactly one field must be supplied and that field must not be `null`.. + /// Looks up a localized string similar to The OneOf Input Object `{0}` requires that exactly one field must be supplied and that field must not be `null`.. /// internal static string ErrorHelper_OneOfMustHaveExactlyOneField { get { @@ -348,7 +348,16 @@ internal static string ErrorHelper_OneOfMustHaveExactlyOneField { } /// - /// Looks up a localized string similar to The variable `${0}` assigned to the field `{1}` of the Oneof Input Object `{2}` must be non-null.. + /// Looks up a localized string similar to The variable `{0}` is not compatible with the type of the current one-of location.. + /// + internal static string ErrorHelper_OneOfVariableIsNotCompatible { + get { + return ResourceManager.GetString("ErrorHelper_OneOfVariableIsNotCompatible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variable `${0}` assigned to the field `{1}` of the OneOf Input Object `{2}` must be non-null.. /// internal static string ErrorHelper_OneOfVariablesMustBeNonNull { get { diff --git a/src/HotChocolate/Core/src/Validation/Properties/Resources.resx b/src/HotChocolate/Core/src/Validation/Properties/Resources.resx index 3875de9850a..2d81d79a770 100644 --- a/src/HotChocolate/Core/src/Validation/Properties/Resources.resx +++ b/src/HotChocolate/Core/src/Validation/Properties/Resources.resx @@ -107,6 +107,9 @@ The context has an invalid state and is missing the schema. + + The variable `{0}` is not compatible with the type of the current one-of location. + The variable `{0}` is not compatible with the type of the current location. @@ -216,10 +219,10 @@ Introspection is not allowed for the current request. - The Oneof Input Object `{0}` requires that exactly one field must be supplied and that field must not be `null`. + The OneOf Input Object `{0}` requires that exactly one field must be supplied and that field must not be `null`. - The variable `${0}` assigned to the field `{1}` of the Oneof Input Object `{2}` must be non-null. + The variable `${0}` assigned to the field `{1}` of the OneOf Input Object `{2}` must be non-null. The skip and include directives are not allowed to be used on root fields of the subscription type. diff --git a/src/HotChocolate/Core/src/Validation/Rules/ValueVisitor.cs b/src/HotChocolate/Core/src/Validation/Rules/ValueVisitor.cs index f03e75898f1..c15d2e12b22 100644 --- a/src/HotChocolate/Core/src/Validation/Rules/ValueVisitor.cs +++ b/src/HotChocolate/Core/src/Validation/Rules/ValueVisitor.cs @@ -40,7 +40,7 @@ namespace HotChocolate.Validation.Rules; /// /// AND /// -/// Oneof Input Objects require that exactly one field must be supplied and that +/// OneOf Input Objects require that exactly one field must be supplied and that /// field must not be {null}. /// /// DRAFT: https://github.com/graphql/graphql-spec/pull/825 diff --git a/src/HotChocolate/Core/src/Validation/Rules/VariableVisitor.cs b/src/HotChocolate/Core/src/Validation/Rules/VariableVisitor.cs index ca4084a651e..f41a5c61578 100644 --- a/src/HotChocolate/Core/src/Validation/Rules/VariableVisitor.cs +++ b/src/HotChocolate/Core/src/Validation/Rules/VariableVisitor.cs @@ -247,12 +247,22 @@ protected override ISyntaxVisitorAction Enter( _ => null }; - if (context.Variables.TryGetValue( - node.Name.Value, - out var variableDefinition) - && !IsVariableUsageAllowed(variableDefinition, context.Types.Peek(), defaultValue)) + var isOneOfVariable = + parent is ObjectFieldNode + && context.Types[^2].NullableType() is IInputObjectTypeDefinition inputObjectType + && inputObjectType.Directives.ContainsName(DirectiveNames.OneOf.Name); + + if (context.Variables.TryGetValue(node.Name.Value, out var variableDefinition) + && !IsVariableUsageAllowed( + variableDefinition, + context.Types.Peek(), + isOneOfVariable, + defaultValue)) { - context.ReportError(context.VariableIsNotCompatible(node, variableDefinition)); + context.ReportError( + isOneOfVariable + ? context.OneOfVariableIsNotCompatible(node, variableDefinition) + : context.VariableIsNotCompatible(node, variableDefinition)); } return Skip; @@ -282,9 +292,10 @@ protected override ISyntaxVisitorAction Leave( private bool IsVariableUsageAllowed( VariableDefinitionNode variableDefinition, IType locationType, + bool isOneOfVariable, IValueNode? locationDefault) { - if (locationType.IsNonNullType() + if (IsNonNullPosition(locationType, isOneOfVariable) && !variableDefinition.Type.IsNonNullType()) { if (variableDefinition.DefaultValue.IsNull() @@ -303,6 +314,11 @@ private bool IsVariableUsageAllowed( locationType); } + private static bool IsNonNullPosition(IType locationType, bool isOneOfVariable) + { + return locationType.IsNonNullType() || isOneOfVariable; + } + // http://facebook.github.io/graphql/June2018/#AreTypesCompatible() private bool AreTypesCompatible( ITypeNode variableType, diff --git a/src/HotChocolate/Core/test/Execution.Tests/Integration/StarWarsCodeFirst/__snapshots__/StarWarsCodeFirstTests.Ensure_Benchmark_Query_LargeQuery.snap b/src/HotChocolate/Core/test/Execution.Tests/Integration/StarWarsCodeFirst/__snapshots__/StarWarsCodeFirstTests.Ensure_Benchmark_Query_LargeQuery.snap index 82986a833f4..f610988143f 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/Integration/StarWarsCodeFirst/__snapshots__/StarWarsCodeFirstTests.Ensure_Benchmark_Query_LargeQuery.snap +++ b/src/HotChocolate/Core/test/Execution.Tests/Integration/StarWarsCodeFirst/__snapshots__/StarWarsCodeFirstTests.Ensure_Benchmark_Query_LargeQuery.snap @@ -5818,7 +5818,7 @@ "deprecationReason": null }, { - "name": "oneOf", + "name": "isOneOf", "description": null, "args": [], "type": { diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.DefaultValueIsInputObject.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.DefaultValueIsInputObject.snap index ee1a0f4e01c..bdba7b5558b 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.DefaultValueIsInputObject.snap +++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.DefaultValueIsInputObject.snap @@ -913,7 +913,7 @@ "deprecationReason": null }, { - "name": "oneOf", + "name": "isOneOf", "description": null, "args": [], "type": { diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery.snap index 24cd217c0da..1dbb8f07eb4 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery.snap +++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery.snap @@ -913,7 +913,7 @@ "deprecationReason": null }, { - "name": "oneOf", + "name": "isOneOf", "description": null, "args": [], "type": { diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery_ToJson.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery_ToJson.snap index 24cd217c0da..1dbb8f07eb4 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery_ToJson.snap +++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/IntrospectionTests.ExecuteGraphiQLIntrospectionQuery_ToJson.snap @@ -913,7 +913,7 @@ "deprecationReason": null }, { - "name": "oneOf", + "name": "isOneOf", "description": null, "args": [], "type": { diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/OneOfIntegrationTests.cs b/src/HotChocolate/Core/test/Types.Tests/Types/OneOfIntegrationTests.cs index ec0c665e616..91e764d7ad1 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/OneOfIntegrationTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Types/OneOfIntegrationTests.cs @@ -34,6 +34,30 @@ public async Task A_is_null_and_B_is_set_Error() .MatchSnapshotAsync(); } + [Fact] + public async Task A_is_null_and_B_is_null_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync("{ example(input: { a: null, b: null }) }") + .MatchSnapshotAsync(); + } + + [Fact] + public async Task A_is_null_Error() + { + // Error: Value for member field {a} must be non-null + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync("{ example(input: { a: null }) }") + .MatchSnapshotAsync(); + } + [Fact] public async Task B_is_set_Valid() { @@ -45,6 +69,18 @@ public async Task B_is_set_Valid() .MatchSnapshotAsync(); } + [Fact] + public async Task Input_is_empty_object_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync("{ example(input: { }) }") + .MatchSnapshotAsync(); + } + [Fact] public async Task A_is_variable_and_B_is_set_Error() { @@ -55,8 +91,40 @@ public async Task A_is_variable_and_B_is_set_Error() .ModifyOptions(o => o.EnableOneOf = true) .ExecuteRequestAsync( OperationRequestBuilder.New() - .SetDocument("query($var: String!) { example(input: { a: $var, b: 123 }) }") - .SetVariableValues(new Dictionary { { "var", null } }) + .SetDocument("query($a: String!) { example(input: { a: $a, b: 123 }) }") + .SetVariableValues(new Dictionary { { "a", null } }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task A_is_unset_variable_and_B_is_set_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($a: String!) { example(input: { a: $a, b: 123 }) }") + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task A_is_variable_and_B_is_unset_variable_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument( + "query($a: String!, $b: Int!) { example(input: { a: $a, b: $b }) }") + .SetVariableValues(new Dictionary { { "a", "abc" } }) .Build()) .MatchSnapshotAsync(); } @@ -70,14 +138,14 @@ public async Task B_is_variable_and_var_is_123_Valid() .ModifyOptions(o => o.EnableOneOf = true) .ExecuteRequestAsync( OperationRequestBuilder.New() - .SetDocument("query($var: Int!) { example(input: { b: $var }) }") - .SetVariableValues(new Dictionary { { "var", 123 } }) + .SetDocument("query($b: Int!) { example(input: { b: $b }) }") + .SetVariableValues(new Dictionary { { "b", 123 } }) .Build()) .MatchSnapshotAsync(); } [Fact] - public async Task Var_is_object_with_field_b_set_to_123_Valid() + public async Task Var_is_object_with_field_B_set_to_123_Valid() { await new ServiceCollection() .AddGraphQL() @@ -93,11 +161,100 @@ public async Task Var_is_object_with_field_b_set_to_123_Valid() .MatchSnapshotAsync(); } + [Fact] + public async Task Var_is_object_with_A_set_to_abc_and_B_set_to_123_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary + { + { + "var", + new ObjectValueNode( + new ObjectFieldNode("a", "abc"), + new ObjectFieldNode("b", 123)) + } + }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task Var_is_object_with_A_set_to_abc_and_B_set_to_null_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary + { + { + "var", + new ObjectValueNode( + new ObjectFieldNode("a", "abc"), + new ObjectFieldNode("b", NullValueNode.Default)) + } + }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task Var_is_object_with_A_set_to_null_Error() + { + // Error: Value for member field {a} must be non-null + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary + { + { + "var", + new ObjectValueNode(new ObjectFieldNode("a", NullValueNode.Default)) + } + }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task Var_is_empty_object_Error() + { + // Error: Exactly one key must be specified + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary { { "var", new ObjectValueNode() } }) + .Build()) + .MatchSnapshotAsync(); + } + [Fact] public async Task Input_is_set_to_string_abc123_Error() { // Error: Incorrect value - await new ServiceCollection() .AddGraphQL() .AddQueryType() @@ -113,7 +270,6 @@ public async Task Input_is_set_to_string_abc123_Error() public async Task Var_is_string_abc123_and_passed_to_input_Error() { // Error: Incorrect value - await new ServiceCollection() .AddGraphQL() .AddQueryType() @@ -151,14 +307,36 @@ public async Task B_is_set_to_string_Error() } [Fact] - public async Task A_is_set_to_string_Error() + public async Task Var_is_object_with_B_set_to_abc_Error() { // Error: Incorrect value for member field {b} await new ServiceCollection() .AddGraphQL() .AddQueryType() .ModifyOptions(o => o.EnableOneOf = true) - .ExecuteRequestAsync("{ example(input: { a: \"123\" }) }") + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary + { + { + "var", + new ObjectValueNode(new ObjectFieldNode("b", "abc")) + } + }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public async Task A_is_set_to_string_Valid() + { + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync("{ example(input: { a: \"abc\" }) }") .MatchSnapshotAsync(); } @@ -172,13 +350,13 @@ public async Task B_is_variable_and_var_not_set_Error() .ModifyOptions(o => o.EnableOneOf = true) .ExecuteRequestAsync( OperationRequestBuilder.New() - .SetDocument("query($var: Int!) { example(input: { b: $var }) }") + .SetDocument("query($b: Int!) { example(input: { b: $b }) }") .Build()) .MatchSnapshotAsync(); } [Fact] - public async Task Var_is_object_with_field_a_set_to_abc_Valid() + public async Task Var_is_object_with_field_A_set_to_abc_Valid() { await new ServiceCollection() .AddGraphQL() @@ -207,16 +385,17 @@ public async Task A_is_set_and_B_is_null_Error() } [Fact] - public async Task B_is_variable_and_var_is_null_Valid() + public async Task B_is_variable_and_var_is_null_Error() { + // Error: Value for member field {b} must be non-null await new ServiceCollection() .AddGraphQL() .AddQueryType() .ModifyOptions(o => o.EnableOneOf = true) .ExecuteRequestAsync( OperationRequestBuilder.New() - .SetDocument("query($var: Int) { example(input: { b: $var }) }") - .SetVariableValues(new Dictionary { { "var", null } }) + .SetDocument("query($b: Int) { example(input: { b: $b }) }") + .SetVariableValues(new Dictionary { { "b", null } }) .Build()) .MatchSnapshotAsync(); } @@ -224,7 +403,7 @@ public async Task B_is_variable_and_var_is_null_Valid() [Fact] public async Task B_is_set_and_C_is_invalid_prop_Error() { - // Error: Exactly one key must be specified + // Error: Unexpected field {c} await new ServiceCollection() .AddGraphQL() .AddQueryType() @@ -234,7 +413,32 @@ public async Task B_is_set_and_C_is_invalid_prop_Error() } [Fact] - public void Oneof_Input_Objects_that_is_Valid() + public async Task Var_is_object_with_fields_B_and_C_set_Error() + { + // Error: Unexpected field {c} + await new ServiceCollection() + .AddGraphQL() + .AddQueryType() + .ModifyOptions(o => o.EnableOneOf = true) + .ExecuteRequestAsync( + OperationRequestBuilder.New() + .SetDocument("query($var: ExampleInput!) { example(input: $var) }") + .SetVariableValues( + new Dictionary + { + { + "var", + new ObjectValueNode( + new ObjectFieldNode("b", 123), + new ObjectFieldNode("c", "xyz")) + } + }) + .Build()) + .MatchSnapshotAsync(); + } + + [Fact] + public void OneOf_Input_Objects_that_is_Valid() => ExpectValid( @"type Query { foo(f: FooInput): String @@ -246,7 +450,7 @@ input FooInput @oneOf { }"); [Fact] - public void Oneof_Input_Objects_must_have_nullable_fields() + public void OneOf_Input_Objects_must_have_nullable_fields() => ExpectError( @"type Query { foo(f: FooInput): String @@ -258,7 +462,7 @@ input FooInput @oneOf { }"); [Fact] - public void Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_non_null() + public void OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_non_null() => ExpectError( @"type Query { foo(f: FooInput): String @@ -270,7 +474,7 @@ input FooInput @oneOf { }"); [Fact] - public void Oneof_Input_Objects_must_have_nullable_fields_with_one_field_has_default() + public void OneOf_Input_Objects_must_have_nullable_fields_with_one_field_has_default() => ExpectError( @"type Query { foo(f: FooInput): String @@ -282,7 +486,7 @@ input FooInput @oneOf { }"); [Fact] - public void Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default() + public void OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default() => ExpectError( @"type Query { foo(f: FooInput): String @@ -294,7 +498,7 @@ input FooInput @oneOf { }"); [Fact] - public void Oneof_generic_code_first_schema() + public void OneOf_generic_code_first_schema() => SchemaBuilder.New() .AddQueryType() .ModifyOptions(o => o.EnableOneOf = true) @@ -303,7 +507,7 @@ public void Oneof_generic_code_first_schema() .MatchSnapshot(); [Fact] - public async Task Oneof_introspection() + public async Task OneOf_introspection() { await new ServiceCollection() .AddGraphQL() @@ -316,19 +520,19 @@ public async Task Oneof_introspection() }) .ExecuteRequestAsync( @"{ - oneof_input: __type(name: ""ExampleInput"") { + oneOf_input: __type(name: ""ExampleInput"") { # should be true - oneOf + isOneOf } input: __type(name: ""StandardInput"") { # should be false - oneOf + isOneOf } object: __type(name: ""Query"") { # should be null - oneOf + isOneOf } }") .MatchSnapshotAsync(); diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Validation/__snapshots__/InputObjectTypeValidationRuleTests.RejectOneOfWithNullableFields.snap b/src/HotChocolate/Core/test/Types.Tests/Types/Validation/__snapshots__/InputObjectTypeValidationRuleTests.RejectOneOfWithNullableFields.snap index 265b1b61151..7db07cf5aab 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Validation/__snapshots__/InputObjectTypeValidationRuleTests.RejectOneOfWithNullableFields.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Validation/__snapshots__/InputObjectTypeValidationRuleTests.RejectOneOfWithNullableFields.snap @@ -1,5 +1,5 @@ { - "message": "Oneof Input Object `Foo` must only have nullable fields without default values. Edit your type and make the fields `first, second` nullable and remove any defaults.", + "message": "OneOf Input Object `Foo` must only have nullable fields without default values. Edit your type and make the fields `first, second` nullable and remove any defaults.", "type": "Foo", "extensions": { "rfc": "https://github.com/graphql/graphql-spec/pull/825", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions.graphql b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions.graphql index 95c9db01df5..d47d43b647b 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions.graphql +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions.graphql @@ -113,13 +113,7 @@ enum SomeEnum { VALUE2 } -""" -The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. -""" +"The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." directive @oneOf on INPUT_OBJECT "Single line comment" diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions_No_Indent.graphql b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions_No_Indent.graphql index 704750c33f1..4081251a895 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions_No_Indent.graphql +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/DescriptionTests.Schema_With_All_Possible_Descriptions_No_Indent.graphql @@ -40,13 +40,7 @@ comment """ VALUE2 } "Single line comment" enum SomeEnum { "Single line comment" VALUE1 """ Multi line comment - """ VALUE2 } """ -The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. -""" directive @oneOf on INPUT_OBJECT "Single line comment" directive @other("Single line comment" arg1: String """ + """ VALUE2 } "The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." directive @oneOf on INPUT_OBJECT "Single line comment" directive @other("Single line comment" arg1: String """ Multi line comment """ arg2: String) on FIELD """ diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_and_B_Are_Set.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_and_B_Are_Set.snap index 758f024be17..12aba87d2ff 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_and_B_Are_Set.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_and_B_Are_Set.snap @@ -1,6 +1,6 @@ [ { - "Message": "More than one field of the Oneof Input Object `OneOfInput` is set. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "Message": "More than one field of the OneOf Input Object `OneOfInput` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", "Code": "HC0055", "Path": { "Name": "root", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_is_Null_and_B_has_Value.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_is_Null_and_B_has_Value.snap index 758f024be17..12aba87d2ff 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_is_Null_and_B_has_Value.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/InputParserTests.OneOf_A_is_Null_and_B_has_Value.snap @@ -1,6 +1,6 @@ [ { - "Message": "More than one field of the Oneof Input Object `OneOfInput` is set. Oneof Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "Message": "More than one field of the OneOf Input Object `OneOfInput` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", "Code": "HC0055", "Path": { "Name": "root", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_Error.snap new file mode 100644 index 00000000000..f763315800b --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_Error.snap @@ -0,0 +1,21 @@ +{ + "errors": [ + { + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "locations": [ + { + "line": 1, + "column": 18 + } + ], + "path": [ + "example" + ], + "extensions": { + "type": "ExampleInput", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_null_Error.snap new file mode 100644 index 00000000000..f763315800b --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_null_Error.snap @@ -0,0 +1,21 @@ +{ + "errors": [ + { + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "locations": [ + { + "line": 1, + "column": 18 + } + ], + "path": [ + "example" + ], + "extensions": { + "type": "ExampleInput", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_set_Error.snap index 2e800a47bc7..f763315800b 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_set_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_null_and_B_is_set_Error.snap @@ -1,7 +1,7 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_null_Error.snap index 2e800a47bc7..f763315800b 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_null_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_null_Error.snap @@ -1,7 +1,7 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_Error.snap index 2e800a47bc7..f763315800b 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_Error.snap @@ -1,7 +1,7 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_to_string_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_to_string_Error.snap index 64df1f3a5c7..bbc357ad3bf 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_to_string_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_and_B_is_set_to_string_Error.snap @@ -1,7 +1,7 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } }, diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Error.snap deleted file mode 100644 index 60d55fca999..00000000000 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Error.snap +++ /dev/null @@ -1,5 +0,0 @@ -{ - "data": { - "example": "a: 123" - } -} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Valid.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Valid.snap new file mode 100644 index 00000000000..43f2e3f16aa --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_set_to_string_Valid.snap @@ -0,0 +1,5 @@ +{ + "data": { + "example": "a: abc" + } +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_unset_variable_and_B_is_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_unset_variable_and_B_is_set_Error.snap new file mode 100644 index 00000000000..fa99e3e0703 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_unset_variable_and_B_is_set_Error.snap @@ -0,0 +1,21 @@ +{ + "errors": [ + { + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "locations": [ + { + "line": 1, + "column": 37 + } + ], + "path": [ + "example" + ], + "extensions": { + "type": "ExampleInput", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_set_Error.snap index ede7138e291..fa99e3e0703 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_set_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_set_Error.snap @@ -1,11 +1,11 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, - "column": 39 + "column": 37 } ], "path": [ @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_unset_variable_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_unset_variable_Error.snap new file mode 100644 index 00000000000..1ed474db0b7 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.A_is_variable_and_B_is_unset_variable_Error.snap @@ -0,0 +1,21 @@ +{ + "errors": [ + { + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "locations": [ + { + "line": 1, + "column": 47 + } + ], + "path": [ + "example" + ], + "extensions": { + "type": "ExampleInput", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_set_and_C_is_invalid_prop_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_set_and_C_is_invalid_prop_Error.snap index a5d18ae8741..58cc3202201 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_set_and_C_is_invalid_prop_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_set_and_C_is_invalid_prop_Error.snap @@ -1,7 +1,7 @@ -{ +{ "errors": [ { - "message": "The Oneof Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", "locations": [ { "line": 1, @@ -13,7 +13,7 @@ ], "extensions": { "type": "ExampleInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" } }, diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Error.snap new file mode 100644 index 00000000000..a96a642b55c --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Error.snap @@ -0,0 +1,37 @@ +{ + "errors": [ + { + "message": "The variable `$b` assigned to the field `b` of the OneOf Input Object `ExampleInput` must be non-null.", + "locations": [ + { + "line": 1, + "column": 33 + } + ], + "path": [ + "example" + ], + "extensions": { + "fieldCoordinate": "ExampleInput.b", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + }, + { + "message": "The variable `b` is not compatible with the type of the current one-of location.", + "locations": [ + { + "line": 1, + "column": 38 + } + ], + "path": [ + "example" + ], + "extensions": { + "variable": "b", + "specifiedBy": "https://spec.graphql.org/October2021/#sec-All-Variable-Usages-are-Allowed" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Valid.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Valid.snap deleted file mode 100644 index 7bfb47d47b6..00000000000 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_is_null_Valid.snap +++ /dev/null @@ -1,21 +0,0 @@ -{ - "errors": [ - { - "message": "The variable `$var` assigned to the field `b` of the Oneof Input Object `ExampleInput` must be non-null.", - "locations": [ - { - "line": 1, - "column": 35 - } - ], - "path": [ - "example" - ], - "extensions": { - "fieldCoordinate": "ExampleInput.b", - "specifiedBy": "https://spec.graphql.org/draft/#sec-Oneof–Input-Objects-Have-Exactly-One-Field", - "rfc": "https://github.com/graphql/graphql-spec/pull/825" - } - } - ] -} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_not_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_not_set_Error.snap index bd7ab55d32e..299ef68c7d1 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_not_set_Error.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.B_is_variable_and_var_not_set_Error.snap @@ -1,7 +1,7 @@ { "errors": [ { - "message": "Variable `var` is required.", + "message": "Variable `b` is required.", "locations": [ { "line": 1, @@ -10,7 +10,7 @@ ], "extensions": { "code": "HC0018", - "variable": "var" + "variable": "b" } } ] diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Input_is_empty_object_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Input_is_empty_object_Error.snap new file mode 100644 index 00000000000..f763315800b --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Input_is_empty_object_Error.snap @@ -0,0 +1,21 @@ +{ + "errors": [ + { + "message": "The OneOf Input Object `ExampleInput` requires that exactly one field must be supplied and that field must not be `null`.", + "locations": [ + { + "line": 1, + "column": 18 + } + ], + "path": [ + "example" + ], + "extensions": { + "type": "ExampleInput", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", + "rfc": "https://github.com/graphql/graphql-spec/pull/825" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument.snap index e16a23e924b..112723c858b 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument.snap @@ -13,11 +13,5 @@ input DefaultValueInput @oneOf { directive @defaultValue(value: DefaultValueInput) on FIELD_DEFINITION -""" -The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. -""" +"The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." directive @oneOf on INPUT_OBJECT diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument_Fluent.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument_Fluent.snap index 569ead1ab68..50ff3c018fc 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument_Fluent.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_DefaultValue_On_Directive_Argument_Fluent.snap @@ -13,11 +13,5 @@ input DefaultValue @oneOf { directive @defaultValue(value: DefaultValue) on FIELD_DEFINITION -""" -The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. -""" +"The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." directive @oneOf on INPUT_OBJECT diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields.snap similarity index 83% rename from src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields.snap rename to src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields.snap index 5017a861797..befdf7f59d0 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields.snap @@ -1,5 +1,5 @@ { - "message": "Oneof Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the field `a` nullable and remove any defaults.", + "message": "OneOf Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the field `a` nullable and remove any defaults.", "type": "FooInput", "extensions": { "rfc": "https://github.com/graphql/graphql-spec/pull/825", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap similarity index 83% rename from src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap rename to src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap index 5017a861797..befdf7f59d0 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_one_field_has_default.snap @@ -1,5 +1,5 @@ { - "message": "Oneof Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the field `a` nullable and remove any defaults.", + "message": "OneOf Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the field `a` nullable and remove any defaults.", "type": "FooInput", "extensions": { "rfc": "https://github.com/graphql/graphql-spec/pull/825", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap similarity index 83% rename from src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap rename to src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap index 5352be9077a..f0b2424735f 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_non_null.snap @@ -1,5 +1,5 @@ { - "message": "Oneof Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the fields `a, b` nullable and remove any defaults.", + "message": "OneOf Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the fields `a, b` nullable and remove any defaults.", "type": "FooInput", "extensions": { "rfc": "https://github.com/graphql/graphql-spec/pull/825", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap similarity index 83% rename from src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap rename to src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap index 5352be9077a..f0b2424735f 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_Input_Objects_must_have_nullable_fields_with_two_fields_that_have_default.snap @@ -1,5 +1,5 @@ { - "message": "Oneof Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the fields `a, b` nullable and remove any defaults.", + "message": "OneOf Input Object `FooInput` must only have nullable fields without default values. Edit your type and make the fields `a, b` nullable and remove any defaults.", "type": "FooInput", "extensions": { "rfc": "https://github.com/graphql/graphql-spec/pull/825", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_generic_code_first_schema.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_generic_code_first_schema.snap new file mode 100644 index 00000000000..cc83538a5f5 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_generic_code_first_schema.snap @@ -0,0 +1,15 @@ +schema { + query: Query +} + +type Query { + a(a: Example2Input): String +} + +input Example2Input @oneOf { + a: String + b: Int +} + +"The `@oneOf` directive is used within the type system definition language to indicate an Input Object is a OneOf Input Object." +directive @oneOf on INPUT_OBJECT diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_introspection.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_introspection.snap new file mode 100644 index 00000000000..a2aca088e02 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.OneOf_introspection.snap @@ -0,0 +1,13 @@ +{ + "data": { + "oneOf_input": { + "isOneOf": true + }, + "input": { + "isOneOf": false + }, + "object": { + "isOneOf": null + } + } +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_generic_code_first_schema.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_generic_code_first_schema.snap deleted file mode 100644 index 97232f9bb49..00000000000 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_generic_code_first_schema.snap +++ /dev/null @@ -1,21 +0,0 @@ -schema { - query: Query -} - -type Query { - a(a: Example2Input): String -} - -input Example2Input @oneOf { - a: String - b: Int -} - -""" -The `@oneOf` directive is used within the type system definition language - to indicate: - - - an Input Object is a Oneof Input Object, or - - an Object Type's Field is a Oneof Field. -""" -directive @oneOf on INPUT_OBJECT diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_introspection.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_introspection.snap deleted file mode 100644 index 74be4c0e6f9..00000000000 --- a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Oneof_introspection.snap +++ /dev/null @@ -1,13 +0,0 @@ -{ - "data": { - "oneof_input": { - "oneOf": true - }, - "input": { - "oneOf": false - }, - "object": { - "oneOf": null - } - } -} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_empty_object_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_empty_object_Error.snap new file mode 100644 index 00000000000..98e79e75e6d --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_empty_object_Error.snap @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "message": "The OneOf Input Objects `ExampleInput` require that exactly one field must be supplied and that field must not be `null`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "path": [ + "var" + ], + "extensions": { + "code": "HC0054" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_123_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_123_Error.snap new file mode 100644 index 00000000000..1bc241ec8b4 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_123_Error.snap @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "message": "More than one field of the OneOf Input Object `ExampleInput` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "path": [ + "var" + ], + "extensions": { + "code": "HC0055" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_null_Error.snap new file mode 100644 index 00000000000..1bc241ec8b4 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_abc_and_B_set_to_null_Error.snap @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "message": "More than one field of the OneOf Input Object `ExampleInput` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "path": [ + "var" + ], + "extensions": { + "code": "HC0055" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_null_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_null_Error.snap new file mode 100644 index 00000000000..50856065edf --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_A_set_to_null_Error.snap @@ -0,0 +1,15 @@ +{ + "errors": [ + { + "message": "`null` was set to the field `a`of the OneOf Input Object `ExampleInput`. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "path": [ + "var", + "a" + ], + "extensions": { + "code": "HC0056", + "fieldCoordinate": "ExampleInput.a" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_B_set_to_abc_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_B_set_to_abc_Error.snap new file mode 100644 index 00000000000..019532371a6 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_B_set_to_abc_Error.snap @@ -0,0 +1,15 @@ +{ + "errors": [ + { + "message": "Int cannot parse the given literal of type `StringValueNode`.", + "path": [ + "var", + "b" + ], + "extensions": { + "fieldCoordinate": "ExampleInput.b", + "fieldType": "Int" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_fields_B_and_C_set_Error.snap b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_fields_B_and_C_set_Error.snap new file mode 100644 index 00000000000..1bc241ec8b4 --- /dev/null +++ b/src/HotChocolate/Core/test/Types.Tests/Types/__snapshots__/OneOfIntegrationTests.Var_is_object_with_fields_B_and_C_set_Error.snap @@ -0,0 +1,13 @@ +{ + "errors": [ + { + "message": "More than one field of the OneOf Input Object `ExampleInput` is set. OneOf Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null.", + "path": [ + "var" + ], + "extensions": { + "code": "HC0055" + } + } + ] +} diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.DescriptionsAreCorrectlyRead.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.DescriptionsAreCorrectlyRead.snap index 42fd24f7647..123850094b9 100644 --- a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.DescriptionsAreCorrectlyRead.snap +++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.DescriptionsAreCorrectlyRead.snap @@ -840,6 +840,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "isOneOf", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "kind", "description": null, @@ -880,18 +892,6 @@ "isDeprecated": false, "deprecationReason": null }, - { - "name": "oneOf", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "possibleTypes", "description": null, diff --git a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.Interfaces_Impl_Interfaces_Are_Correctly_Exposed_Through_Introspection.snap b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.Interfaces_Impl_Interfaces_Are_Correctly_Exposed_Through_Introspection.snap index c955585f0c0..befb6f23546 100644 --- a/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.Interfaces_Impl_Interfaces_Are_Correctly_Exposed_Through_Introspection.snap +++ b/src/HotChocolate/Core/test/Types.Tests/__snapshots__/SchemaFirstTests.Interfaces_Impl_Interfaces_Are_Correctly_Exposed_Through_Introspection.snap @@ -913,7 +913,7 @@ "deprecationReason": null }, { - "name": "oneOf", + "name": "isOneOf", "description": null, "args": [], "type": { diff --git a/src/HotChocolate/Core/test/Validation.Tests/AllVariableUsagesAreAllowedRuleTests.cs b/src/HotChocolate/Core/test/Validation.Tests/AllVariableUsagesAreAllowedRuleTests.cs index c34fb928e81..16f2f6719de 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/AllVariableUsagesAreAllowedRuleTests.cs +++ b/src/HotChocolate/Core/test/Validation.Tests/AllVariableUsagesAreAllowedRuleTests.cs @@ -503,4 +503,46 @@ dog @include(if: $boolVar) """ ); } + + [Fact] + public void VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable1_Valid() + { + ExpectValid( + """ + mutation addCat($cat: CatInput!) { + addPet(pet: { cat: $cat }) { + name + } + } + """ + ); + } + + [Fact] + public void VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable2_Valid() + { + ExpectValid( + """ + mutation addCatWithDefault($cat: CatInput! = { name: "Brontie" }) { + addPet(pet: { cat: $cat }) { + name + } + } + """ + ); + } + + [Fact] + public void VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable1_Error() + { + ExpectErrors( + """ + mutation addNullableCat($cat: CatInput) { + addPet(pet: { cat: $cat }) { + name + } + } + """ + ); + } } diff --git a/src/HotChocolate/Core/test/Validation.Tests/OneOfRuleTests.cs b/src/HotChocolate/Core/test/Validation.Tests/OneOfRuleTests.cs deleted file mode 100644 index fac7c2080d5..00000000000 --- a/src/HotChocolate/Core/test/Validation.Tests/OneOfRuleTests.cs +++ /dev/null @@ -1,123 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; - -namespace HotChocolate.Validation; - -public class OneOfRuleTests : DocumentValidatorVisitorTestBase -{ - public OneOfRuleTests() - : base(builder => builder.AddValueRules()) - { - } - - [Fact] - public void EmptyOneOf() - { - ExpectErrors( - """ - mutation addPet { - addPet(pet: { }) { - name - } - } - """ - ); - } - - [Fact] - public void MultipleFieldsAreNotAllowed_1() - { - ExpectErrors( - """ - mutation addPet($cat: CatInput, $dog: DogInput) { - addPet(pet: {cat: $cat, dog: $dog}) { - name - } - } - """ - ); - } - - [Fact] - public void MultipleFieldsAreNotAllowed_2() - { - ExpectErrors( - """ - mutation addPet($dog: DogInput) { - addPet(pet: { cat: { name: "Brontie" }, dog: $dog }) { - name - } - } - """ - ); - } - - [Fact] - public void MultipleFieldsAreNotAllowed_3() - { - ExpectErrors( - """ - mutation addPet($cat: CatInput, $dog: DogInput) { - addPet(pet: {cat: $cat, dog: $dog}) { - name - } - } - """ - ); - } - - [Fact] - public void VariablesUsedForOneofInputObjectFieldsMustBeNonNullable_Valid() - { - ExpectValid( - """ - mutation addPet($cat: CatInput!) { - addPet(pet: { cat: $cat }) { - name - } - } - """ - ); - } - - [Fact] - public void VariablesUsedForOneofInputObjectFieldsMustBeNonNullable_Error() - { - ExpectErrors( - """ - mutation addPet($cat: CatInput) { - addPet(pet: { cat: $cat }) { - name - } - } - """ - ); - } - - [Fact] - public void IfFieldWithLiteralValueIsPresentThenTheValueMustNotBeNull_Valid() - { - ExpectValid( - """ - mutation addPet { - addPet(pet: { cat: { name: "Brontie" } }) { - name - } - } - """ - ); - } - - [Fact] - public void IfFieldWithLiteralValueIsPresentThenTheValueMustNotBeNull_Error() - { - ExpectErrors( - """ - mutation addPet { - addPet(pet: { cat: null }) { - name - } - } - """ - ); - } -} diff --git a/src/HotChocolate/Core/test/Validation.Tests/Types/MutationType.cs b/src/HotChocolate/Core/test/Validation.Tests/Types/MutationType.cs index a1b2af677e4..c3361ab67fc 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/Types/MutationType.cs +++ b/src/HotChocolate/Core/test/Validation.Tests/Types/MutationType.cs @@ -14,8 +14,13 @@ protected override void Configure(IObjectTypeDescriptor descriptor) .Resolve(() => "foo"); descriptor.Field("addPet") - .Argument("pet", a => a.Type()) + .Argument("pet", a => a.Type>()) .Type() .Resolve(() => "foo"); + + descriptor.Field("addPets") + .Argument("pets", a => a.Type>>>()) + .Type>() + .Resolve(() => "foo"); } } diff --git a/src/HotChocolate/Core/test/Validation.Tests/ValuesOfCorrectTypeRuleTests.cs b/src/HotChocolate/Core/test/Validation.Tests/ValuesOfCorrectTypeRuleTests.cs index 53827da55e4..2c45f7a804b 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/ValuesOfCorrectTypeRuleTests.cs +++ b/src/HotChocolate/Core/test/Validation.Tests/ValuesOfCorrectTypeRuleTests.cs @@ -119,6 +119,19 @@ query goodComplexDefaultValue($search: ComplexInput = { name: "Fido" }) { """); } + [Fact] + public void GoodOneOfDefaultValue() + { + ExpectValid( + """ + mutation addPet($pet: PetInput! = { cat: { name: "Brontie" } }) { + addPet(pet: $pet) { + name + } + } + """); + } + [Fact] public void StringIntoInt() { @@ -170,6 +183,57 @@ query goodComplexDefaultValue($search: ComplexInput = { name: 123 }) { t.Message)); } + [Fact] + public void BadOneOfWithNoFields() + { + ExpectErrors( + """ + mutation oneOfWithNoFields { + addPet(pet: {}) { + name + } + } + """, + t => Assert.Equal( + "The OneOf Input Object `PetInput` requires that exactly one field must be " + + "supplied and that field must not be `null`.", + t.Message)); + } + + [Fact] + public void BadOneOfWithTwoFields() + { + ExpectErrors( + """ + mutation oneOfWithTwoFields($dog: DogInput) { + addPet(pet: { cat: { name: "Brontie" }, dog: $dog }) { + name + } + } + """, + t => Assert.Equal( + "The OneOf Input Object `PetInput` requires that exactly one field must be " + + "supplied and that field must not be `null`.", + t.Message)); + } + + [Fact] + public void BadListOfOneOfWithNullableVariable() + { + ExpectErrors( + """ + mutation listOfOneOfWithNullableVariable($dog: DogInput) { + addPets(pets: [{ dog: $dog }]) { + name + } + } + """, + t => Assert.Equal( + "The variable `$dog` assigned to the field `dog` of the OneOf Input Object " + + "`PetInput` must be non-null.", + t.Message)); + } + [Fact] public void BadValueVariable() { diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/AllVariableUsagesAreAllowedRuleTests.VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable1_Error.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/AllVariableUsagesAreAllowedRuleTests.VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable1_Error.snap new file mode 100644 index 00000000000..96cb8dcaf74 --- /dev/null +++ b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/AllVariableUsagesAreAllowedRuleTests.VariablesUsedForOneOfInputObjectFieldsMustBeNonNullable1_Error.snap @@ -0,0 +1,27 @@ +[ + { + "Message": "The variable `cat` is not compatible with the type of the current one-of location.", + "Code": null, + "Path": { + "Name": "addPet", + "Parent": { + "Parent": null, + "Length": 0, + "IsRoot": true + }, + "Length": 1, + "IsRoot": false + }, + "Locations": [ + { + "Line": 2, + "Column": 22 + } + ], + "Extensions": { + "variable": "cat", + "specifiedBy": "https://spec.graphql.org/October2021/#sec-All-Variable-Usages-are-Allowed" + }, + "Exception": null + } +] diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_1.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_1.snap deleted file mode 100644 index 130048e3083..00000000000 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_1.snap +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "Message": "The Oneof Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", - "Code": null, - "Path": { - "Name": "addPet", - "Parent": { - "Parent": null, - "Length": 0, - "IsRoot": true - }, - "Length": 1, - "IsRoot": false - }, - "Locations": [ - { - "Line": 2, - "Column": 15 - } - ], - "Extensions": { - "type": "PetInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", - "rfc": "https://github.com/graphql/graphql-spec/pull/825" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_3.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_3.snap deleted file mode 100644 index 130048e3083..00000000000 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_3.snap +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "Message": "The Oneof Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", - "Code": null, - "Path": { - "Name": "addPet", - "Parent": { - "Parent": null, - "Length": 0, - "IsRoot": true - }, - "Length": 1, - "IsRoot": false - }, - "Locations": [ - { - "Line": 2, - "Column": 15 - } - ], - "Extensions": { - "type": "PetInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", - "rfc": "https://github.com/graphql/graphql-spec/pull/825" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.VariablesUsedForOneofInputObjectFieldsMustBeNonNullable_Error.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.VariablesUsedForOneofInputObjectFieldsMustBeNonNullable_Error.snap deleted file mode 100644 index e9eda9499b6..00000000000 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.VariablesUsedForOneofInputObjectFieldsMustBeNonNullable_Error.snap +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "Message": "The variable `$cat` assigned to the field `cat` of the Oneof Input Object `PetInput` must be non-null.", - "Code": null, - "Path": { - "Name": "addPet", - "Parent": { - "Parent": null, - "Length": 0, - "IsRoot": true - }, - "Length": 1, - "IsRoot": false - }, - "Locations": [ - { - "Line": 2, - "Column": 15 - } - ], - "Extensions": { - "fieldCoordinate": "PetInput.cat", - "specifiedBy": "https://spec.graphql.org/draft/#sec-Oneof–Input-Objects-Have-Exactly-One-Field", - "rfc": "https://github.com/graphql/graphql-spec/pull/825" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.IfFieldWithLiteralValueIsPresentThenTheValueMustNotBeNull_Error.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadListOfOneOfWithNullableVariable.snap similarity index 53% rename from src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.IfFieldWithLiteralValueIsPresentThenTheValueMustNotBeNull_Error.snap rename to src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadListOfOneOfWithNullableVariable.snap index 130048e3083..b19018a8b6c 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.IfFieldWithLiteralValueIsPresentThenTheValueMustNotBeNull_Error.snap +++ b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadListOfOneOfWithNullableVariable.snap @@ -1,9 +1,9 @@ [ { - "Message": "The Oneof Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", + "Message": "The variable `$dog` assigned to the field `dog` of the OneOf Input Object `PetInput` must be non-null.", "Code": null, "Path": { - "Name": "addPet", + "Name": "addPets", "Parent": { "Parent": null, "Length": 0, @@ -15,12 +15,12 @@ "Locations": [ { "Line": 2, - "Column": 15 + "Column": 20 } ], "Extensions": { - "type": "PetInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "fieldCoordinate": "PetInput.dog", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" }, "Exception": null diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.EmptyOneOf.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithNoFields.snap similarity index 71% rename from src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.EmptyOneOf.snap rename to src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithNoFields.snap index 130048e3083..c10d19a778a 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.EmptyOneOf.snap +++ b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithNoFields.snap @@ -1,6 +1,6 @@ [ { - "Message": "The Oneof Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", + "Message": "The OneOf Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", "Code": null, "Path": { "Name": "addPet", @@ -15,12 +15,12 @@ "Locations": [ { "Line": 2, - "Column": 15 + "Column": 17 } ], "Extensions": { "type": "PetInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" }, "Exception": null diff --git a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_2.snap b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithTwoFields.snap similarity index 71% rename from src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_2.snap rename to src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithTwoFields.snap index 130048e3083..c10d19a778a 100644 --- a/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/OneOfRuleTests.MultipleFieldsAreNotAllowed_2.snap +++ b/src/HotChocolate/Core/test/Validation.Tests/__snapshots__/ValuesOfCorrectTypeRuleTests.BadOneOfWithTwoFields.snap @@ -1,6 +1,6 @@ [ { - "Message": "The Oneof Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", + "Message": "The OneOf Input Object `PetInput` requires that exactly one field must be supplied and that field must not be `null`.", "Code": null, "Path": { "Name": "addPet", @@ -15,12 +15,12 @@ "Locations": [ { "Line": 2, - "Column": 15 + "Column": 17 } ], "Extensions": { "type": "PetInput", - "specifiedBy": "https://spec.graphql.org/draft/#sec-OneOf-Input-Objects-Have-Exactly-One-Field", + "specifiedBy": "https://spec.graphql.org/draft/#sec-All-Variable-Usages-Are-Allowed", "rfc": "https://github.com/graphql/graphql-spec/pull/825" }, "Exception": null diff --git a/src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs b/src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs index 089b520795f..db1135dd712 100644 --- a/src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs +++ b/src/HotChocolate/Primitives/src/Primitives/ErrorCodes.cs @@ -75,28 +75,28 @@ public static class Execution public const string CannotCastParent = "HC0053"; /// - /// The Oneof Input Objects `{0}` require that exactly one field must be supplied and that - /// field must not be `null`. Oneof Input Objects are a special variant of Input Objects + /// The OneOf Input Objects `{0}` require that exactly one field must be supplied and that + /// field must not be `null`. OneOf Input Objects are a special variant of Input Objects /// where the type system asserts that exactly one of the fields must be set and non-null. /// public const string OneOfNoFieldSet = "HC0054"; /// - /// More than one field of the Oneof Input Object `{0}` is set. Oneof Input Objects + /// More than one field of the OneOf Input Object `{0}` is set. OneOf Input Objects /// are a special variant of Input Objects where the type system asserts that exactly /// one of the fields must be set and non-null. /// public const string OneOfMoreThanOneFieldSet = "HC0055"; /// - /// `null` was set to the field `{0}`of the Oneof Input Object `{1}`. Oneof Input Objects + /// `null` was set to the field `{0}`of the OneOf Input Object `{1}`. OneOf Input Objects /// are a special variant of Input Objects where the type system asserts that exactly /// one of the fields must be set and non-null. /// public const string OneOfFieldIsNull = "HC0056"; /// - /// Value for oneof field {field.FieldName} must be non-null. + /// Value for OneOf field {field.FieldName} must be non-null. /// public const string OneOfFieldMustBeNonNull = "HC0057"; diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/__snapshots__/StarWarsIntrospectionTest.Execute_StarWarsIntrospection_Test.snap b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/__snapshots__/StarWarsIntrospectionTest.Execute_StarWarsIntrospection_Test.snap index e0432b4565b..2336e90c75b 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/__snapshots__/StarWarsIntrospectionTest.Execute_StarWarsIntrospection_Test.snap +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/__snapshots__/StarWarsIntrospectionTest.Execute_StarWarsIntrospection_Test.snap @@ -907,7 +907,7 @@ "DeprecationReason": null }, { - "Name": "oneOf", + "Name": "isOneOf", "Description": null, "Args": [], "Type": { @@ -4193,7 +4193,7 @@ }, { "__typename": "__Field", - "Name": "oneOf", + "Name": "isOneOf", "Description": null, "Args": [], "Type": { diff --git a/website/src/blog/2022-01-13-hot-chocolate-12-5/2022-01-13-hot-chocolate-12-5.md b/website/src/blog/2022-01-13-hot-chocolate-12-5/2022-01-13-hot-chocolate-12-5.md index da3c8b670a8..220669859ea 100644 --- a/website/src/blog/2022-01-13-hot-chocolate-12-5/2022-01-13-hot-chocolate-12-5.md +++ b/website/src/blog/2022-01-13-hot-chocolate-12-5/2022-01-13-hot-chocolate-12-5.md @@ -231,4 +231,4 @@ The current GraphQL spec RFC can be found [here](https://github.com/graphql/grap # Conclusion -We have implemented a ton of other smaller additions and bug fixes. Hot Chocolate 12.5 pushes further ahead and allows you to opt into the newest GraphQL spec proposals and drafts. At the GraphQL working group, we are currently discussing great new additions to the GraphQL spec like fragment modularity and object identity. Together, stream/defer, `oneof`, fragment modularity, object identity, and client-controlled nullability could make GraphQL so much better and help us solve fundamental problems in interacting with our data graphs. We have invested in these new features early and are iterating on these as the spec text matures. +We have implemented a ton of other smaller additions and bug fixes. Hot Chocolate 12.5 pushes further ahead and allows you to opt into the newest GraphQL spec proposals and drafts. At the GraphQL working group, we are currently discussing great new additions to the GraphQL spec like fragment modularity and object identity. Together, stream/defer, OneOf, fragment modularity, object identity, and client-controlled nullability could make GraphQL so much better and help us solve fundamental problems in interacting with our data graphs. We have invested in these new features early and are iterating on these as the spec text matures. diff --git a/website/src/docs/hotchocolate/v12/defining-a-schema/input-object-types.md b/website/src/docs/hotchocolate/v12/defining-a-schema/input-object-types.md index 8efab687351..d40d09d960b 100644 --- a/website/src/docs/hotchocolate/v12/defining-a-schema/input-object-types.md +++ b/website/src/docs/hotchocolate/v12/defining-a-schema/input-object-types.md @@ -220,11 +220,11 @@ public record BookInput([property:DefaultValue("")]Optional Title, strin ``` -## `Oneof` Input Objects +## `OneOf` Input Objects -`Oneof` Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null, all others being omitted. This is represented in introspection with the \_\_Type.oneField: Boolean field, and in SDL via the @oneOf directive on the input object. +`OneOf` Input Objects are a special variant of Input Objects where the type system asserts that exactly one of the fields must be set and non-null, all others being omitted. This is represented in introspection with the \_\_Type.oneField: Boolean field, and in SDL via the @oneOf directive on the input object. -> Warning: `Oneof` Input Objects is currently a draft feature to the GraphQL spec. +> Warning: `OneOf` Input Objects is currently a draft feature to the GraphQL spec.