From ee42d3737bf094402774c3d293a14a5318563650 Mon Sep 17 00:00:00 2001 From: Glen Date: Wed, 24 Sep 2025 17:02:43 +0200 Subject: [PATCH 1/2] [Fusion] Added pre-merge validation rule "InvalidFieldSharingRule" --- .../Fusion.Composition/Events/GroupEvents.cs | 5 + .../MutableComplexTypeDefinitionExtensions.cs | 5 + .../MutableOutputFieldDefinitionExtensions.cs | 8 + .../OutputFieldDefinitionExtensions.cs | 6 +- .../Extensions/OutputFieldInfoExtensions.cs | 22 --- .../Features/SourceFieldMetadata.cs | 8 + .../Info/ObjectFieldInfo.cs | 8 + .../Logging/LogEntryCodes.cs | 1 + .../Logging/LogEntryHelper.cs | 16 ++ .../Options/SchemaComposerOptions.cs | 2 +- .../SourceSchemaPreprocessorOptions.cs | 6 + .../InvalidFieldSharingRule.cs | 56 +++++++ .../Fusion.Composition/PreMergeValidator.cs | 14 ++ .../CompositionResources.Designer.cs | 11 +- .../Properties/CompositionResources.resx | 5 +- .../src/Fusion.Composition/SchemaComposer.cs | 20 ++- .../SourceSchemaEnricher.cs | 53 ++++++- .../Fusion.Composition/SourceSchemaMerger.cs | 8 +- .../SourceSchemaPreprocessor.cs | 45 +++++- .../InvalidShareableUsageRule.cs | 14 ++ .../AbstractTypeTests.cs | 1 + .../Fusion.AspNetCore.Tests/BookStoreTests.cs | 5 +- .../DiagnisticListenerTests.cs | 5 +- .../FusionTestBase.CreateSourceSchema.cs | 1 + .../GlobalObjectIdentificationTests.cs | 114 +++++++------- .../Fusion.AspNetCore.Tests/InterfaceTests.cs | 12 +- .../IntrospectionTests.cs | 6 +- .../Fusion.AspNetCore.Tests/MutationTests.cs | 1 + .../OperationPlannerInterceptorTests.cs | 5 +- .../Fusion.AspNetCore.Tests/RequireTests.cs | 3 + .../SharedPathTests.cs | 17 ++ .../SubscriptionsOverHttpStoreTests.cs | 1 + .../AbstractTypeTests.Abstract_Type.yaml | 2 +- ...stract_Type_Direct_Source_Schema_Call.yaml | 2 +- ...ts.Abstract_Type_With_Abstract_Lookup.yaml | 2 +- ...ts.Abstract_Type_With_Concrete_Lookup.yaml | 2 +- ...ts.Concrete_Type_With_Abstract_Lookup.yaml | 2 +- ...tractTypeTests.List_Of_Abstract_Types.yaml | 2 +- ...nTests.Concrete_Type_Branch_Requested.yaml | 4 +- ...Type_Branch_Requested_Abstract_Lookup.yaml | 4 +- ...om_Concrete_Type_Selections_Requested.yaml | 4 +- ...ionTests.Id_Of_Unknown_Type_Requested.yaml | 4 +- ...ntificationTests.Invalid_Id_Requested.yaml | 4 +- ...Lookup_On_Best_Matching_Source_Schema.yaml | 4 +- ...eld_Alongside_Regular_Root_Selections.yaml | 2 +- ...de_Field_Concrete_Type_Has_Dependency.yaml | 6 +- ...oncrete_Type_Selection_Has_Dependency.yaml | 8 +- ...ts.Node_Field_Selections_On_Interface.yaml | 4 +- ...ctions_On_Interface_And_Concrete_Type.yaml | 4 +- ...Type_Both_Have_Different_Dependencies.yaml | 12 +- ...On_Interface_Selection_Has_Dependency.yaml | 12 +- ...elections_Have_Different_Dependencies.yaml | 12 +- ...Types_Selections_Have_Same_Dependency.yaml | 12 +- ...onTests.Only_Id_And_Typename_Selected.yaml | 2 +- ...ly_TypeName_Selected_On_Concrete_Type.yaml | 4 +- ...ificationTests.Only_Typename_Selected.yaml | 8 +- ...ationTests.Two_Node_Fields_With_Alias.yaml | 4 +- ...e_Field_Concrete_Type_With_Dependency.yaml | 4 +- ...t_Field_Concrete_Type_With_Dependency.yaml | 4 +- ...roperty_Concrete_Type_With_Dependency.yaml | 4 +- .../MutationTests.Multiple_Mutation.yaml | 2 +- .../MutationTests.Single_Mutation.yaml | 2 +- ...RequireTests.Require_Object_In_A_List.yaml | 6 +- ..._Parent_Fields_Below_Type_With_Lookup.yaml | 32 ++-- ...kup_With_Extra_Fields_On_Shared_Level.yaml | 32 ++-- ...up_With_Extra_Fields_On_Shared_Levels.yaml | 32 ++-- ...Tests.Hierarchy_Of_Shared_Root_Fields.yaml | 32 ++-- ...lds_With_Extra_Fields_On_Shared_Level.yaml | 34 ++-- ...d_Parent_Field_Below_Type_With_Lookup.yaml | 32 ++-- ...kup_With_Extra_Fields_On_Shared_Level.yaml | 32 ++-- ...Type_With_Lookup_With_Type_Refinement.yaml | 32 ++-- ...rface_Root_Field_With_Type_Refinement.yaml | 32 ++-- ...redPathTests.Single_Shared_Root_Field.yaml | 32 ++-- ..._Root_Field_With_Extra_Fields_On_Root.yaml | 32 ++-- ...Union_Root_Field_With_Type_Refinement.yaml | 32 ++-- ...nsOverHttpStoreTests.Subscribe_Simple.yaml | 2 +- .../v15/DemoIntegrationTests.cs | 98 ++++++------ .../v15/SubgraphErrorTests.cs | 12 +- .../v15/TransportErrorTests.cs | 14 +- ...onState_With_Multiple_Variable_Values.yaml | 12 +- ...ariable_Values_And_Forwarded_Variable.yaml | 12 +- ...tiple_Variable_Values_Some_Items_Null.yaml | 12 +- ...ubgraph_Type_Of_Shared_Field_Not_Node.yaml | 12 +- ...graph_Type_Of_Shared_Field_Not_Node_2.yaml | 16 +- ...graph_Type_Of_Shared_Field_Not_Node_3.yaml | 16 +- ...at_Require_Data_From_Another_Subgraph.yaml | 2 +- .../DemoIntegrationTests.Viewer_Bug_1.yaml | 4 +- .../DemoIntegrationTests.Viewer_Bug_2.yaml | 8 +- .../DemoIntegrationTests.Viewer_Bug_3.yaml | 4 +- ...NonNull_One_Service_Errors_EntryField.yaml | 2 +- ...t_NonNull_One_Service_Errors_SubField.yaml | 2 +- ...ullable_One_Service_Errors_EntryField.yaml | 2 +- ..._Nullable_One_Service_Errors_SubField.yaml | 2 +- ...ullable_One_Service_Errors_EntryField.yaml | 2 +- ..._Nullable_One_Service_Errors_SubField.yaml | 2 +- ...ices_Offline_SharedEntryField_NonNull.yaml | 4 +- ...st_Service_Offline_EntryField_NonNull.yaml | 2 +- ...t_Service_Offline_EntryField_Nullable.yaml | 2 +- ...fline_SubField_NonNull_Parent_NonNull.yaml | 2 +- ...line_SubField_NonNull_Parent_Nullable.yaml | 2 +- ...ine_SubField_Nullable_Parent_Nullable.yaml | 2 +- .../CompositionTestHelper.cs | 10 +- .../InvalidFieldSharingRuleTests.cs | 147 ++++++++++++++++++ .../SourceSchemaEnricherTests.cs | 61 ++++---- .../SourceSchemaMergerTests.cs | 57 +++---- .../SourceSchemaPreprocessorTests.cs | 111 +++++++++++++ .../InvalidShareableUsageRuleTests.cs | 31 +++- .../Fusion.Execution.Tests/FusionTestBase.cs | 40 ++--- .../Planning/OperationPlannerTests.cs | 10 +- .../Planning/RequirementTests.cs | 6 +- 110 files changed, 1146 insertions(+), 595 deletions(-) delete mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldInfoExtensions.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Info/ObjectFieldInfo.cs create mode 100644 src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidationRules/InvalidFieldSharingRule.cs create mode 100644 src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidationRules/InvalidFieldSharingRuleTests.cs diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/GroupEvents.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/GroupEvents.cs index f942098e5dc..675ac7b1df6 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/GroupEvents.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Events/GroupEvents.cs @@ -23,6 +23,11 @@ internal record InputTypeGroupEvent( string InputTypeName, ImmutableArray InputTypeGroup) : IEvent; +internal record ObjectFieldGroupEvent( + string FieldName, + ImmutableArray FieldGroup, + string TypeName) : IEvent; + internal record OutputFieldGroupEvent( string FieldName, ImmutableArray FieldGroup, diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableComplexTypeDefinitionExtensions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableComplexTypeDefinitionExtensions.cs index da75c6876eb..9e5e33600f0 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableComplexTypeDefinitionExtensions.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableComplexTypeDefinitionExtensions.cs @@ -24,4 +24,9 @@ public static void ApplyKeyDirective(this MutableComplexTypeDefinition type, str new ArgumentAssignment(ArgumentNames.Fields, keyFields))); } } + + public static IEnumerable GetKeyDirectives(this MutableComplexTypeDefinition type) + { + return type.Directives.AsEnumerable().Where(d => d.Name == DirectiveNames.Key); + } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableOutputFieldDefinitionExtensions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableOutputFieldDefinitionExtensions.cs index 38359ff0401..7118be408a5 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableOutputFieldDefinitionExtensions.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/MutableOutputFieldDefinitionExtensions.cs @@ -106,6 +106,14 @@ public static string GetKeyFields( return mergedSelectionSet.ToString(indented: false).AsSpan()[2..^2].ToString(); } + public static string? GetOverrideFrom(this MutableOutputFieldDefinition field) + { + var overrideDirective = + field.Directives.AsEnumerable().SingleOrDefault(d => d.Name == DirectiveNames.Override); + + return (string?)overrideDirective?.Arguments[ArgumentNames.From].Value; + } + public static bool HasInternalDirective(this MutableOutputFieldDefinition type) { return type.Directives.ContainsName(DirectiveNames.Internal); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldDefinitionExtensions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldDefinitionExtensions.cs index e9502f35b25..efc8ab5c553 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldDefinitionExtensions.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldDefinitionExtensions.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using HotChocolate.Features; using HotChocolate.Fusion.Features; using HotChocolate.Types; using static HotChocolate.Fusion.WellKnownArgumentNames; @@ -26,8 +27,9 @@ public static ImmutableArray GetSchemaNames( return [.. schemaNames]; } - public static SourceFieldMetadata? GetSourceFieldMetadata(this IOutputFieldDefinition field) + public static SourceFieldMetadata GetRequiredSourceFieldMetadata( + this IOutputFieldDefinition field) { - return field.Features.Get(); + return field.Features.GetRequired(); } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldInfoExtensions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldInfoExtensions.cs deleted file mode 100644 index d195fc6b535..00000000000 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Extensions/OutputFieldInfoExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Immutable; -using HotChocolate.Fusion.Info; -using static HotChocolate.Fusion.WellKnownArgumentNames; -using static HotChocolate.Fusion.WellKnownDirectiveNames; - -namespace HotChocolate.Fusion.Extensions; - -internal static class OutputFieldInfoExtensions -{ - public static bool IsOverridden( - this OutputFieldInfo fieldInfo, - ImmutableArray fieldGroup) - { - var overriddenInSchemaNames = - fieldGroup - .Where(i => i.Field.Directives.ContainsName(Override)) - .Select(i => (string)i.Field.Directives[Override].First().Arguments[From].Value!) - .ToImmutableArray(); - - return overriddenInSchemaNames.Contains(fieldInfo.Schema.Name); - } -} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Features/SourceFieldMetadata.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Features/SourceFieldMetadata.cs index b2a337b45d7..8897c5b5294 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Features/SourceFieldMetadata.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Features/SourceFieldMetadata.cs @@ -2,7 +2,15 @@ namespace HotChocolate.Fusion.Features; internal sealed class SourceFieldMetadata { + public bool HasShareableDirective { get; set; } + + public bool IsExternal { get; set; } + + public bool IsInternal { get; set; } + public bool IsKeyField { get; set; } + public bool IsOverridden { get; set; } + public bool IsShareable { get; set; } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Info/ObjectFieldInfo.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Info/ObjectFieldInfo.cs new file mode 100644 index 00000000000..4c675ad3f19 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Info/ObjectFieldInfo.cs @@ -0,0 +1,8 @@ +using HotChocolate.Types.Mutable; + +namespace HotChocolate.Fusion.Info; + +internal record ObjectFieldInfo( + MutableOutputFieldDefinition Field, + MutableObjectTypeDefinition Type, + MutableSchemaDefinition Schema); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs index f40b1d1924f..2cc6dbf436c 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryCodes.cs @@ -21,6 +21,7 @@ public static class LogEntryCodes public const string InputFieldTypesNotMergeable = "INPUT_FIELD_TYPES_NOT_MERGEABLE"; public const string InputWithMissingRequiredFields = "INPUT_WITH_MISSING_REQUIRED_FIELDS"; public const string InterfaceFieldNoImplementation = "INTERFACE_FIELD_NO_IMPLEMENTATION"; + public const string InvalidFieldSharing = "INVALID_FIELD_SHARING"; public const string InvalidGraphQL = "INVALID_GRAPHQL"; public const string InvalidShareableUsage = "INVALID_SHAREABLE_USAGE"; public const string IsInvalidField = "IS_INVALID_FIELD"; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs index eae4e244fc5..f10a9d0c688 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Logging/LogEntryHelper.cs @@ -419,6 +419,22 @@ public static LogEntry InterfaceFieldNoImplementation( schema); } + public static LogEntry InvalidFieldSharing( + MutableOutputFieldDefinition field, + string typeName, + MutableSchemaDefinition schema) + { + var coordinate = new SchemaCoordinate(typeName, field.Name); + + return new LogEntry( + string.Format(LogEntryHelper_InvalidFieldSharing, coordinate, schema.Name), + LogEntryCodes.InvalidFieldSharing, + LogSeverity.Error, + coordinate, + field, + schema); + } + public static LogEntry InvalidGraphQL(string exceptionMessage) { return new LogEntry( diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SchemaComposerOptions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SchemaComposerOptions.cs index efef6d5b1af..7a7b4ae3868 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SchemaComposerOptions.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SchemaComposerOptions.cs @@ -4,5 +4,5 @@ public sealed class SchemaComposerOptions { public required bool EnableGlobalObjectIdentification { get; init; } - public SourceSchemaPreprocessorOptions Preprocessor { get; init; } = new(); + public Dictionary PreprocessorOptions { get; init; } = []; } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SourceSchemaPreprocessorOptions.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SourceSchemaPreprocessorOptions.cs index e4cefd64d3b..5af16615e78 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SourceSchemaPreprocessorOptions.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Options/SourceSchemaPreprocessorOptions.cs @@ -6,4 +6,10 @@ public sealed class SourceSchemaPreprocessorOptions /// Applies inferred key directives to types that are returned by lookup fields. /// public bool ApplyInferredKeyDirectives { get; set; } = true; + + /// + /// Applies key directives to types based on the keys defined on the interfaces that they + /// implement. + /// + public bool InheritInterfaceKeys { get; set; } = true; } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidationRules/InvalidFieldSharingRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidationRules/InvalidFieldSharingRule.cs new file mode 100644 index 00000000000..1fff7c49dee --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidationRules/InvalidFieldSharingRule.cs @@ -0,0 +1,56 @@ +using System.Collections.Immutable; +using HotChocolate.Fusion.Events; +using HotChocolate.Fusion.Events.Contracts; +using HotChocolate.Fusion.Extensions; +using static HotChocolate.Fusion.Logging.LogEntryHelper; + +namespace HotChocolate.Fusion.PreMergeValidationRules; + +/// +/// +/// A field in a federated GraphQL schema may be marked @shareable, indicating that the same +/// field can be resolved by multiple schemas without conflict. When a field is not marked as +/// @shareable (sometimes called “non-shareable”), it cannot be provided by more than one +/// schema. +/// +/// +/// Field definitions marked as @external and overridden fields are excluded when validating +/// whether a field is shareable. These annotations indicate specific cases where field ownership +/// lies with another schema or has been replaced. +/// +/// +/// +/// Specification +/// +internal sealed class InvalidFieldSharingRule : IEventHandler +{ + public void Handle(ObjectFieldGroupEvent @event, CompositionContext context) + { + var fieldGroup = @event.FieldGroup; + + // Exclude external and overridden fields. + var filteredFieldGroup = + fieldGroup + .Where( + i => i.Field.GetRequiredSourceFieldMetadata() is + { + IsExternal: false, + IsOverridden: false + }) + .ToImmutableArray(); + + if (filteredFieldGroup.Length < 2) + { + return; + } + + // Remaining fields must be shareable. + foreach (var (field, type, schema) in filteredFieldGroup) + { + if (!field.GetRequiredSourceFieldMetadata().IsShareable) + { + context.Log.Write(InvalidFieldSharing(field, type.Name, schema)); + } + } + } +} diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidator.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidator.cs index 1eccc7b77cb..dcd88d09a91 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidator.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/PreMergeValidator.cs @@ -50,6 +50,7 @@ private void PublishEvents() MultiValueDictionary inputTypeGroupByName = []; MultiValueDictionary inputFieldGroupByName = []; MultiValueDictionary outputFieldGroupByName = []; + MultiValueDictionary objectFieldGroupByName = []; MultiValueDictionary enumTypeGroupByName = []; foreach (var (type, schema) in typeGroup) @@ -81,6 +82,13 @@ private void PublishEvents() outputFieldGroupByName.Add( field.Name, new OutputFieldInfo(field, complexType, schema)); + + if (complexType is MutableObjectTypeDefinition objectType) + { + objectFieldGroupByName.Add( + field.Name, + new ObjectFieldInfo(field, objectType, schema)); + } } break; @@ -131,6 +139,12 @@ private void PublishEvents() } } + foreach (var (fieldName, fieldGroup) in objectFieldGroupByName) + { + PublishEvent( + new ObjectFieldGroupEvent(fieldName, [.. fieldGroup], typeName), context); + } + foreach (var (enumName, enumGroup) in enumTypeGroupByName) { PublishEvent(new EnumTypeGroupEvent(enumName, [.. enumGroup]), context); diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs index cabe3c4067e..657623f5669 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.Designer.cs @@ -716,6 +716,15 @@ internal static string LogEntryHelper_InterfaceFieldNoImplementation { } } + /// + /// Looks up a localized string similar to The field '{0}' in schema '{1}' must be shareable.. + /// + internal static string LogEntryHelper_InvalidFieldSharing { + get { + return ResourceManager.GetString("LogEntryHelper_InvalidFieldSharing", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid GraphQL in source schema. Exception message: {0}.. /// @@ -726,7 +735,7 @@ internal static string LogEntryHelper_InvalidGraphQL { } /// - /// Looks up a localized string similar to The interface field '{0}' in schema '{1}' must not be marked as shareable.. + /// Looks up a localized string similar to The field '{0}' in schema '{1}' must not be marked as shareable.. /// internal static string LogEntryHelper_InvalidShareableUsage { get { diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx index 2b7375eb718..a65512cece7 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/Properties/CompositionResources.resx @@ -237,11 +237,14 @@ The merged object type '{0}' must implement the field '{1}' on interface '{2}'. + + The field '{0}' in schema '{1}' must be shareable. + Invalid GraphQL in source schema. Exception message: {0}. - The interface field '{0}' in schema '{1}' must not be marked as shareable. + The field '{0}' in schema '{1}' must not be marked as shareable. The @is directive on argument '{0}' in schema '{1}' specifies an invalid field selection against the composed schema. diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs index 94efb65ae40..37eefeaf310 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SchemaComposer.cs @@ -42,9 +42,21 @@ public CompositionResult Compose() } // Preprocess Source Schemas - var preprocessorOptions = _schemaComposerOptions.Preprocessor; var preprocessResult = - schemas.Select(schema => new SourceSchemaPreprocessor(schema, preprocessorOptions).Process()).Combine(); + schemas.Select(schema => + { + var optionsExist = + _schemaComposerOptions.PreprocessorOptions.TryGetValue( + schema.Name, + out var preprocessorOptions); + + if (!optionsExist) + { + preprocessorOptions = new SourceSchemaPreprocessorOptions(); + } + + return new SourceSchemaPreprocessor(schema, preprocessorOptions).Process(); + }).Combine(); if (preprocessResult.IsFailure) { @@ -52,7 +64,8 @@ public CompositionResult Compose() } // Enrich Source Schemas - var enrichmentResult = schemas.Select(schema => new SourceSchemaEnricher(schema).Enrich()).Combine(); + var enrichmentResult = + schemas.Select(schema => new SourceSchemaEnricher(schema, schemas).Enrich()).Combine(); if (enrichmentResult.IsFailure) { @@ -153,6 +166,7 @@ public CompositionResult Compose() new InputFieldDefaultMismatchRule(), new InputFieldTypesMergeableRule(), new InputWithMissingRequiredFieldsRule(), + new InvalidFieldSharingRule(), new OutputFieldTypesMergeableRule(), new TypeKindMismatchRule() ]; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaEnricher.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaEnricher.cs index f83f8fd6a98..fad788c4849 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaEnricher.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaEnricher.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using HotChocolate.Features; using HotChocolate.Fusion.Extensions; using HotChocolate.Fusion.Features; @@ -10,7 +11,9 @@ namespace HotChocolate.Fusion; -internal sealed class SourceSchemaEnricher(MutableSchemaDefinition schema) +internal sealed class SourceSchemaEnricher( + MutableSchemaDefinition schema, + ImmutableSortedSet schemas) { public CompositionResult Enrich() { @@ -35,16 +38,37 @@ public CompositionResult Enrich() return CompositionResult.Success(); } - private static void EnrichField(MutableOutputFieldDefinition field, MutableComplexTypeDefinition complexType) + private void EnrichField( + MutableOutputFieldDefinition field, + MutableComplexTypeDefinition complexType) { var sourceFieldMetadata = field.Features.GetOrSet(); + sourceFieldMetadata.IsExternal = field.HasExternalDirective(); + sourceFieldMetadata.IsInternal = + field.HasInternalDirective() + || (complexType is MutableObjectTypeDefinition objectType && objectType.HasInternalDirective()); + + sourceFieldMetadata.HasShareableDirective = field.HasShareableDirective(); + + // Overridden fields. + foreach (var sourceSchema in schemas.Except([schema])) + { + if (sourceSchema.Types.TryGetType(complexType.Name, out var sourceType) + && sourceType is MutableComplexTypeDefinition sourceComplexType + && sourceComplexType.Fields.TryGetField(field.Name, out var sourceField) + && sourceField.GetOverrideFrom() == schema.Name) + { + sourceFieldMetadata.IsOverridden = true; + } + } + // Shareable fields. if (!field.HasExternalDirective() && ( sourceFieldMetadata.IsKeyField || field.HasShareableDirective() - || (complexType is MutableObjectTypeDefinition objectType && objectType.HasShareableDirective()))) + || (complexType is MutableObjectTypeDefinition o && o.HasShareableDirective()))) { sourceFieldMetadata.IsShareable = true; } @@ -59,11 +83,24 @@ private static List GetKeyFields( foreach (var keyDirective in keyDirectives) { - var fieldsArgument = ((StringValueNode)keyDirective.Arguments[ArgumentNames.Fields]).Value; - var selectionSet = Utf8GraphQLParser.Syntax.ParseSelectionSet($"{{ {fieldsArgument} }}"); - var fieldsExtractor = new SelectionSetFieldsExtractor(schema); - var fieldGroup = fieldsExtractor.ExtractFields(selectionSet, complexType); - keyFields.AddRange(fieldGroup.Select(f => f.Field)); + if (!keyDirective.Arguments.TryGetValue(ArgumentNames.Fields, out var fieldsValueNode) + || fieldsValueNode is not StringValueNode stringValueNode) + { + continue; + } + + try + { + var fieldsArgument = stringValueNode.Value; + var selectionSet = Utf8GraphQLParser.Syntax.ParseSelectionSet($"{{ {fieldsArgument} }}"); + var fieldsExtractor = new SelectionSetFieldsExtractor(schema); + var fieldGroup = fieldsExtractor.ExtractFields(selectionSet, complexType); + keyFields.AddRange(fieldGroup.Select(f => f.Field)); + } + catch (SyntaxException) + { + // Validated later. + } } return keyFields; diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs index ee636d634c8..97749b17610 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs @@ -564,10 +564,14 @@ .. typeGroup.Where( MutableSchemaDefinition mergedSchema) { // Filter out internal or overridden fields. - var group = fieldGroup; fieldGroup = [ - .. fieldGroup.Where(i => !i.Field.HasInternalDirective() && !i.IsOverridden(group)) + .. fieldGroup.Where( + i => i.Field.GetRequiredSourceFieldMetadata() is + { + IsInternal: false, + IsOverridden: false + }) ]; if (fieldGroup.Length == 0) diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaPreprocessor.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaPreprocessor.cs index a1cb791925b..5c9411ab860 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaPreprocessor.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaPreprocessor.cs @@ -1,9 +1,10 @@ -using System.Collections.Immutable; using HotChocolate.Fusion.Extensions; +using HotChocolate.Fusion.Language; using HotChocolate.Fusion.Options; using HotChocolate.Fusion.Results; using HotChocolate.Types; using HotChocolate.Types.Mutable; +using ArgumentNames = HotChocolate.Fusion.WellKnownArgumentNames; namespace HotChocolate.Fusion; @@ -23,6 +24,11 @@ public CompositionResult Process() ApplyInferredKeyDirectives(); } + if (_options.InheritInterfaceKeys) + { + InheritInterfaceKeys(); + } + return CompositionResult.Success(); } @@ -41,16 +47,43 @@ private void ApplyInferredKeyDirectives() var fieldType = lookupFieldDefinition.Type.AsTypeDefinition(); var possibleTypes = schema.GetPossibleTypes(fieldType); var lookupMap = lookupFieldDefinition.GetFusionLookupMap(); - var keyFields = lookupFieldDefinition.GetKeyFields(lookupMap, schema); - foreach (var possibleType in possibleTypes) + try + { + var keyFields = lookupFieldDefinition.GetKeyFields(lookupMap, schema); + + foreach (var possibleType in possibleTypes) + { + possibleType.ApplyKeyDirective(keyFields); + } + + if (fieldType is MutableInterfaceTypeDefinition interfaceType) + { + interfaceType.ApplyKeyDirective(keyFields); + } + } + catch (FieldSelectionMapSyntaxException) { - possibleType.ApplyKeyDirective(keyFields); + // Validated later. } + } + } - if (fieldType is MutableInterfaceTypeDefinition interfaceType) + /// + /// Applies key directives to types based on the keys defined on the interfaces that they + /// implement. + /// + private void InheritInterfaceKeys() + { + foreach (var complexType in schema.Types.OfType()) + { + foreach (var interfaceType in complexType.Implements) { - interfaceType.ApplyKeyDirective(keyFields); + foreach (var keyDirective in interfaceType.GetKeyDirectives()) + { + var fieldsArgument = keyDirective.Arguments[ArgumentNames.Fields].Value!; + complexType.ApplyKeyDirective((string)fieldsArgument); + } } } } diff --git a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaValidationRules/InvalidShareableUsageRule.cs b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaValidationRules/InvalidShareableUsageRule.cs index 0c354f2bf3f..761aa55f28a 100644 --- a/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaValidationRules/InvalidShareableUsageRule.cs +++ b/src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaValidationRules/InvalidShareableUsageRule.cs @@ -18,6 +18,12 @@ namespace HotChocolate.Fusion.SourceSchemaValidationRules; /// @shareable is used only in contexts where shared field resolution is meaningful and /// unambiguous. /// +/// +/// Additionally, subscription root fields cannot be shared (i.e., they are effectively +/// non-shareable), as subscription events from multiple schemas would create conflicts in the +/// composed schema. Attempting to mark a subscription field as shareable or to define it in +/// multiple schemas triggers the same error. +/// /// /// /// Specification @@ -28,9 +34,17 @@ public void Handle(OutputFieldEvent @event, CompositionContext context) { var (field, type, schema) = @event; + // Applying @shareable to interface fields is disallowed. if (type is MutableInterfaceTypeDefinition && field.HasShareableDirective()) { context.Log.Write(InvalidShareableUsage(field, type, schema)); } + + // Subscription root fields cannot be shared. + if (type.Name == WellKnownTypeNames.Subscription + && field.GetRequiredSourceFieldMetadata().HasShareableDirective) + { + context.Log.Write(InvalidShareableUsage(field, type, schema)); + } } } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/AbstractTypeTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/AbstractTypeTests.cs index e52a384fa1e..dbd6e154d97 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/AbstractTypeTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/AbstractTypeTests.cs @@ -297,6 +297,7 @@ public IEnumerable InterfaceConnection() } [InterfaceType] + [EntityKey("id")] public interface SharedType { int Id { get; } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/BookStoreTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/BookStoreTests.cs index 93a59afc28c..0aaa68cc267 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/BookStoreTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/BookStoreTests.cs @@ -612,8 +612,9 @@ public async Task Ensure_String_Variables_Can_Be_Empty() public static class SourceSchema1 { - public record Book(int Id, string Title, Author Author); + public record Book(int Id, string Title, [property: Shareable] Author Author); + [EntityKey("id")] public record Author(int Id); public class Query @@ -696,7 +697,7 @@ public IEnumerable GetAuthors() => _authors.Values; } - public record Book(int Id, Author Author) + public record Book(int Id, [property: Shareable] Author Author) { public string IdAndTitle([Require] string title) => $"{Id} - {title}"; diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/DiagnisticListenerTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/DiagnisticListenerTests.cs index 57ceb8f9a5e..2bbc2c4d210 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/DiagnisticListenerTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/DiagnisticListenerTests.cs @@ -63,8 +63,9 @@ public override IDisposable ExecuteOperation(RequestContext context) public static class SourceSchema1 { - public record Book(int Id, string Title, Author Author); + public record Book(int Id, string Title, [property: Shareable] Author Author); + [EntityKey("id")] public record Author(int Id); public class Query @@ -140,7 +141,7 @@ public IEnumerable GetAuthors() => _authors.Values; } - public record Book(int Id, Author Author) + public record Book(int Id, [property: Shareable] Author Author) { public string IdAndTitle([Require] string title) => $"{Id} - {title}"; diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/FusionTestBase.CreateSourceSchema.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/FusionTestBase.CreateSourceSchema.cs index 5ac31b6c622..93f4ca63755 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/FusionTestBase.CreateSourceSchema.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/FusionTestBase.CreateSourceSchema.cs @@ -93,6 +93,7 @@ public override IEnumerable RegisterMoreTypes( yield return typeInspector.GetTypeRef(typeof(HotChocolate.Types.Composite.EntityKey)); yield return typeInspector.GetTypeRef(typeof(HotChocolate.Types.Composite.Require)); yield return typeInspector.GetTypeRef(typeof(HotChocolate.Types.Composite.Is)); + yield return typeInspector.GetTypeRef(typeof(HotChocolate.Types.Composite.Shareable)); _registeredTypes = true; } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/GlobalObjectIdentificationTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/GlobalObjectIdentificationTests.cs index e8813678382..e6dbe5c2dcc 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/GlobalObjectIdentificationTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/GlobalObjectIdentificationTests.cs @@ -16,7 +16,7 @@ public async Task Concrete_Type_Branch_Requested() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -33,7 +33,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -90,7 +90,7 @@ public async Task Concrete_Type_Branch_Requested_Abstract_Lookup() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -107,7 +107,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -164,7 +164,7 @@ public async Task Invalid_Id_Requested() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -181,7 +181,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -236,7 +236,7 @@ public async Task Id_Of_Unknown_Type_Requested() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -253,7 +253,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -309,7 +309,7 @@ public async Task Id_Of_Type_Different_From_Concrete_Type_Selections_Requested() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -326,7 +326,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -382,14 +382,14 @@ public async Task Only_Typename_Selected() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } @@ -400,14 +400,14 @@ type Discussion implements Node @key(fields: "id") { """ type Query { authorById(id: ID!): Author @lookup - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Author implements Node @key(fields: "id") { + type Author implements Node { id: ID! username: String! } @@ -455,7 +455,7 @@ interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } @@ -496,7 +496,7 @@ public async Task Only_TypeName_Selected_On_Concrete_Type() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -513,7 +513,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } @@ -567,7 +567,7 @@ type Query { discussionByName(title: String! @is(field: "title")): Discussion @lookup } - type Discussion { + type Discussion @key(fields: "id") { id: ID! title: String! commentCount: Int! @@ -585,7 +585,7 @@ interface Node { id: ID! } - type Discussion implements Node { + type Discussion implements Node @key(fields: "title") { id: ID! title: String! } @@ -628,7 +628,7 @@ public async Task Two_Node_Fields_With_Alias() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } @@ -645,7 +645,7 @@ type Discussion implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussion(id: ID!): Discussion @lookup } @@ -715,7 +715,7 @@ interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } @@ -768,7 +768,7 @@ interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! name: String } @@ -781,11 +781,11 @@ type Query { discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } - interface Node { + interface Node @key(fields: "id") { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! commentCount: Int } @@ -829,7 +829,7 @@ public async Task Node_Field_Concrete_Type_Selection_Has_Dependency() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup } @@ -837,7 +837,7 @@ interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! viewerRating: Float! product: Product @@ -852,14 +852,14 @@ type Product @key(fields: "id") { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } @@ -906,14 +906,14 @@ public async Task Node_Field_Two_Concrete_Types_Selections_Have_Same_Dependency( "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! product: Product } @@ -927,14 +927,14 @@ type Product @key(fields: "id") { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Review implements Node @key(fields: "id") { + type Review implements Node { id: ID! product: Product } @@ -948,14 +948,14 @@ type Product @key(fields: "id") { "C", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } @@ -1006,14 +1006,14 @@ public async Task Node_Field_Two_Concrete_Types_Selections_Have_Different_Depend "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! product: Product } @@ -1027,14 +1027,14 @@ type Product @key(fields: "id") { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Review implements Node @key(fields: "id") { + type Review implements Node { id: ID! product: Product } @@ -1048,14 +1048,14 @@ type Product @key(fields: "id") { "C", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } @@ -1118,13 +1118,13 @@ interface Votable { viewerCanVote: Boolean! } - type Discussion implements Node & Votable @key(fields: "id") { + type Discussion implements Node & Votable { id: ID! viewerCanVote: Boolean! viewerRating: Float! } - type Comment implements Node & Votable @key(fields: "id") { + type Comment implements Node & Votable { id: ID! viewerCanVote: Boolean! } @@ -1177,13 +1177,13 @@ interface Votable { viewerCanVote: Boolean! } - type Discussion implements Node & Votable @key(fields: "id") { + type Discussion implements Node & Votable { id: ID! viewerCanVote: Boolean! viewerRating: Float! } - type Comment implements Node & Votable @key(fields: "id") { + type Comment implements Node & Votable { id: ID! viewerCanVote: Boolean! } @@ -1228,7 +1228,7 @@ public async Task Node_Field_Selections_On_Interface_And_Concrete_Type_Both_Have "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { @@ -1239,18 +1239,18 @@ interface ProductList { products: [Product] } - type Item1 implements Node & ProductList @key(fields: "id") { + type Item1 implements Node & ProductList { id: ID! products: [Product] } - type Item2 implements Node & ProductList @key(fields: "id") { + type Item2 implements Node & ProductList { id: ID! products: [Product] singularProduct: Product } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! } """); @@ -1259,14 +1259,14 @@ type Product implements Node @key(fields: "id") { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } @@ -1319,7 +1319,7 @@ public async Task Node_Field_Selections_On_Interface_Selection_Has_Dependency() "A", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { @@ -1330,17 +1330,17 @@ interface ProductList { products: [Product] } - type Item1 implements Node & ProductList @key(fields: "id") { + type Item1 implements Node & ProductList { id: ID! products: [Product] } - type Item2 implements Node & ProductList @key(fields: "id") { + type Item2 implements Node & ProductList { id: ID! products: [Product] } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! } """); @@ -1349,14 +1349,14 @@ type Product implements Node @key(fields: "id") { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interface Node { id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/InterfaceTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/InterfaceTests.cs index b6e0f2d8f72..fcd4dc46a53 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/InterfaceTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/InterfaceTests.cs @@ -344,7 +344,7 @@ public async Task Interface_Field_Concrete_Type_With_Dependency() """ type Query { votable: Votable - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interface Votable { @@ -366,7 +366,7 @@ type Comment implements Votable @key(fields: "id") { "B", """ type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } type Discussion @key(fields: "id") { @@ -821,7 +821,7 @@ public async Task Interface_List_Field_Concrete_Type_With_Dependency() """ type Query { votables: [Votable] - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interface Votable { @@ -843,7 +843,7 @@ type Comment implements Votable @key(fields: "id") { "B", """ type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } type Discussion @key(fields: "id") { @@ -1268,7 +1268,7 @@ public async Task List_Field_Interface_Object_Property_Concrete_Type_With_Depend """ type Query { wrappers: [Wrapper] - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } type Wrapper { @@ -1294,7 +1294,7 @@ type Comment implements Votable @key(fields: "id") { "B", """ type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } type Discussion @key(fields: "id") { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntrospectionTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntrospectionTests.cs index 7c8b4b2a28d..e434b929045 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntrospectionTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/IntrospectionTests.cs @@ -339,8 +339,9 @@ public async Task Download_Schema() public static class SourceSchema1 { - public record Book(int Id, string Title, Author Author); + public record Book(int Id, string Title, [property: Shareable] Author Author); + [EntityKey("id")] public record Author(int Id); public class Query @@ -402,6 +403,7 @@ public IEnumerable GetAuthors() => _authors.Values; } - public record Book(int Id, Author Author); + [EntityKey("id")] + public record Book(int Id, [property: Shareable] Author Author); } } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/MutationTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/MutationTests.cs index fb4516a4df5..0a951d64e09 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/MutationTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/MutationTests.cs @@ -117,6 +117,7 @@ public record CreateBookInput(string Title); public record CreateBookPayload(Book Book); + [EntityKey("id")] public record Book(int Id, string Title); } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/OperationPlannerInterceptorTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/OperationPlannerInterceptorTests.cs index 49a5d4ea9e8..93de7bc293e 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/OperationPlannerInterceptorTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/OperationPlannerInterceptorTests.cs @@ -117,8 +117,9 @@ public void OnAfterPlanCompleted( public static class SourceSchema1 { - public record Book(int Id, string Title, Author Author); + public record Book(int Id, string Title, [property: Shareable] Author Author); + [EntityKey("id")] public record Author(int Id); public class Query @@ -194,7 +195,7 @@ public IEnumerable GetAuthors() => _authors.Values; } - public record Book(int Id, Author Author) + public record Book(int Id, [property: Shareable] Author Author) { public string IdAndTitle([Require] string title) => $"{Id} - {title}"; diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/RequireTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/RequireTests.cs index 1e98e39fe45..bee167894f9 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/RequireTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/RequireTests.cs @@ -144,6 +144,7 @@ public Book[] GetBooks() => s_books.Values.ToArray(); [Lookup] + [Shareable] public Book? GetBook(int id) => s_books.TryGetValue(id, out var book) ? book : null; } @@ -175,6 +176,7 @@ public static class BookInventory public class Query { [Lookup] + [Shareable] public Book? GetBook(int id) => s_books.TryGetValue(id, out var book) ? book : null; } @@ -199,6 +201,7 @@ public static class BookShipping public class Query { [Lookup] + [Shareable] public Book? GetBook(int id) => new() { Id = id }; } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SharedPathTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SharedPathTests.cs index 188e9491587..f4a4d2bfb52 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SharedPathTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SharedPathTests.cs @@ -568,16 +568,20 @@ public static class SourceSchema1 { public class Query { + [Shareable] public Viewer Viewer => new Viewer(); public string Schema1 => "schema1"; + [Shareable] public IInterface Interface => new Review(1); public IInterface UnsharedInterface => new Product(2); + [Shareable] public IUnion Union => new Review(2); + [Shareable] public Review TopReview => new Review(3); [Lookup] @@ -588,6 +592,7 @@ public class Viewer { public string Schema1 => "schema1"; + [Shareable] public ViewerSettings Settings => new ViewerSettings(); } @@ -600,6 +605,7 @@ public record Product(int Id) : IInterface, IUnion { public string Schema1 => "schema1"; + [Shareable] public SharedProduct? Shared => new SharedProduct(); } @@ -612,6 +618,7 @@ public class SharedProduct { public string Schema1 => "schema1"; + [Shareable] public SharedProduct2? Shared2 => new SharedProduct2(); } @@ -620,6 +627,7 @@ public class SharedProduct2 public string Schema1 => "schema1"; } + [EntityKey("id")] public interface IInterface { int Id { get; } @@ -633,14 +641,18 @@ public static class SourceSchema2 { public class Query { + [Shareable] public Viewer Viewer => new Viewer(); public string Schema2 => "schema2"; + [Shareable] public IInterface Interface => new Review(1); + [Shareable] public IUnion Union => new Review(2); + [Shareable] public Review TopReview => new Review(3); [Lookup] @@ -651,6 +663,7 @@ public class Viewer { public string Schema2 => "schema2"; + [Shareable] public ViewerSettings Settings => new ViewerSettings(); } @@ -663,6 +676,7 @@ public record Product(int Id) : IInterface, IUnion { public string Schema2 => "schema2"; + [Shareable] public SharedProduct? Shared => new SharedProduct(); } @@ -675,6 +689,7 @@ public class SharedProduct { public string Schema2 => "schema2"; + [Shareable] public SharedProduct2? Shared2 => new SharedProduct2(); } @@ -683,6 +698,7 @@ public class SharedProduct2 public string Schema2 => "schema2"; } + [EntityKey("id")] public interface IInterface { int Id { get; } @@ -696,6 +712,7 @@ public static class SourceSchema3 { public class Query { + [Shareable] public Viewer Viewer => new Viewer(); } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SubscriptionsOverHttpStoreTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SubscriptionsOverHttpStoreTests.cs index e0245044b8b..994384f20c6 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SubscriptionsOverHttpStoreTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/SubscriptionsOverHttpStoreTests.cs @@ -51,6 +51,7 @@ public async Task Subscribe_Simple() public static class SourceSchema1 { + [EntityKey("id")] public record Book(int Id); public class Query diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type.yaml index 021ab9c4387..b94870915b2 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type.yaml @@ -29,7 +29,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_Direct_Source_Schema_Call.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_Direct_Source_Schema_Call.yaml index db8f0c41697..9df185ba36c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_Direct_Source_Schema_Call.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_Direct_Source_Schema_Call.yaml @@ -38,7 +38,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Abstract_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Abstract_Lookup.yaml index 66a84bb5e4f..b54b263f675 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Abstract_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Abstract_Lookup.yaml @@ -28,7 +28,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Concrete_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Concrete_Lookup.yaml index d347d971306..bf0478e9305 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Concrete_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Abstract_Type_With_Concrete_Lookup.yaml @@ -28,7 +28,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Concrete_Type_With_Abstract_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Concrete_Type_With_Abstract_Lookup.yaml index f5cd0214de8..da2410031c0 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Concrete_Type_With_Abstract_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.Concrete_Type_With_Abstract_Lookup.yaml @@ -24,7 +24,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.List_Of_Abstract_Types.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.List_Of_Abstract_Types.yaml index 8aeedf5e923..75c06783578 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.List_Of_Abstract_Types.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/AbstractTypeTests.List_Of_Abstract_Types.yaml @@ -38,7 +38,7 @@ sourceSchemas: query: Query } - interface SharedType { + interface SharedType @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested.yaml index 0ad1f143bb8..5932523c72e 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested.yaml @@ -36,7 +36,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } interactions: @@ -82,7 +82,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } interactions: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested_Abstract_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested_Abstract_Lookup.yaml index acffbcec5f2..e45430efb87 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested_Abstract_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Concrete_Type_Branch_Requested_Abstract_Lookup.yaml @@ -36,7 +36,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } - name: B @@ -60,7 +60,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } interactions: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Type_Different_From_Concrete_Type_Selections_Requested.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Type_Different_From_Concrete_Type_Selections_Requested.yaml index d6473911939..d683d98860c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Type_Different_From_Concrete_Type_Selections_Requested.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Type_Different_From_Concrete_Type_Selections_Requested.yaml @@ -35,7 +35,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } - name: B @@ -59,7 +59,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } interactions: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Unknown_Type_Requested.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Unknown_Type_Requested.yaml index f2d8982b467..622ffd896f9 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Unknown_Type_Requested.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Id_Of_Unknown_Type_Requested.yaml @@ -43,7 +43,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } - name: B @@ -67,7 +67,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } operationPlan: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Invalid_Id_Requested.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Invalid_Id_Requested.yaml index 2eee67bb77f..fb7dc6b2f73 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Invalid_Id_Requested.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Invalid_Id_Requested.yaml @@ -43,7 +43,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } - name: B @@ -67,7 +67,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } operationPlan: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.No_By_Id_Lookup_On_Best_Matching_Source_Schema.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.No_By_Id_Lookup_On_Best_Matching_Source_Schema.yaml index 0d9a5a84709..d2f95c5b981 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.No_By_Id_Lookup_On_Best_Matching_Source_Schema.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.No_By_Id_Lookup_On_Best_Matching_Source_Schema.yaml @@ -24,7 +24,7 @@ sourceSchemas: query: Query } - type Discussion { + type Discussion @key(fields: "id") { id: ID! title: String! commentCount: Int! @@ -67,7 +67,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node { + type Discussion implements Node @key(fields: "title") { id: ID! title: String! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Alongside_Regular_Root_Selections.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Alongside_Regular_Root_Selections.yaml index c8779c252fc..32056ae8728 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Alongside_Regular_Root_Selections.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Alongside_Regular_Root_Selections.yaml @@ -42,7 +42,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Has_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Has_Dependency.yaml index c9a3c8f83ce..47e1757c4f0 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Has_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Has_Dependency.yaml @@ -36,7 +36,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! name: String } @@ -81,11 +81,11 @@ sourceSchemas: query: Query } - interface Node { + interface Node @key(fields: "id") { id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! commentCount: Int } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Selection_Has_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Selection_Has_Dependency.yaml index 0c6215bb25f..c5abae3f4ec 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Selection_Has_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Concrete_Type_Selection_Has_Dependency.yaml @@ -42,7 +42,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! viewerRating: Float! product: Product @@ -53,7 +53,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup } interactions: @@ -100,13 +100,13 @@ sourceSchemas: id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface.yaml index 0dd1c47a738..05c29a3cc13 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface.yaml @@ -38,12 +38,12 @@ sourceSchemas: viewerCanVote: Boolean! } - type Comment implements Node & Votable @key(fields: "id") { + type Comment implements Node & Votable { id: ID! viewerCanVote: Boolean! } - type Discussion implements Node & Votable @key(fields: "id") { + type Discussion implements Node & Votable { id: ID! viewerCanVote: Boolean! viewerRating: Float! diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type.yaml index ce249608a42..da5ecf14d37 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type.yaml @@ -42,12 +42,12 @@ sourceSchemas: viewerCanVote: Boolean! } - type Comment implements Node & Votable @key(fields: "id") { + type Comment implements Node & Votable { id: ID! viewerCanVote: Boolean! } - type Discussion implements Node & Votable @key(fields: "id") { + type Discussion implements Node & Votable { id: ID! viewerCanVote: Boolean! viewerRating: Float! diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type_Both_Have_Different_Dependencies.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type_Both_Have_Different_Dependencies.yaml index ea2f9c17ff4..e0f75842f86 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type_Both_Have_Different_Dependencies.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_And_Concrete_Type_Both_Have_Different_Dependencies.yaml @@ -63,23 +63,23 @@ sourceSchemas: products: [Product] } - type Item1 implements Node & ProductList @key(fields: "id") { + type Item1 implements Node & ProductList { id: ID! products: [Product] } - type Item2 implements Node & ProductList @key(fields: "id") { + type Item2 implements Node & ProductList { id: ID! products: [Product] singularProduct: Product } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: @@ -134,13 +134,13 @@ sourceSchemas: id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_Selection_Has_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_Selection_Has_Dependency.yaml index 9069a7dd915..95c1948f66b 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_Selection_Has_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Selections_On_Interface_Selection_Has_Dependency.yaml @@ -54,22 +54,22 @@ sourceSchemas: products: [Product] } - type Item1 implements Node & ProductList @key(fields: "id") { + type Item1 implements Node & ProductList { id: ID! products: [Product] } - type Item2 implements Node & ProductList @key(fields: "id") { + type Item2 implements Node & ProductList { id: ID! products: [Product] } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: @@ -124,13 +124,13 @@ sourceSchemas: id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Different_Dependencies.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Different_Dependencies.yaml index be765c37289..6bba470249d 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Different_Dependencies.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Different_Dependencies.yaml @@ -45,7 +45,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! product: Product } @@ -55,7 +55,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: @@ -105,10 +105,10 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } - type Review implements Node @key(fields: "id") { + type Review implements Node { id: ID! product: Product } @@ -122,13 +122,13 @@ sourceSchemas: id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Same_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Same_Dependency.yaml index a61f9e593d5..ed5ae8d5127 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Same_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Node_Field_Two_Concrete_Types_Selections_Have_Same_Dependency.yaml @@ -43,7 +43,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! product: Product } @@ -53,7 +53,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: @@ -103,10 +103,10 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } - type Review implements Node @key(fields: "id") { + type Review implements Node { id: ID! product: Product } @@ -120,13 +120,13 @@ sourceSchemas: id: ID! } - type Product implements Node @key(fields: "id") { + type Product implements Node { id: ID! name: String } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Id_And_Typename_Selected.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Id_And_Typename_Selected.yaml index 1afb0946759..f21d1e866c2 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Id_And_Typename_Selected.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Id_And_Typename_Selected.yaml @@ -28,7 +28,7 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_TypeName_Selected_On_Concrete_Type.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_TypeName_Selected_On_Concrete_Type.yaml index ab372b184d2..0bdc70d2a5b 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_TypeName_Selected_On_Concrete_Type.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_TypeName_Selected_On_Concrete_Type.yaml @@ -34,7 +34,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } interactions: @@ -71,7 +71,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(id: ID!): Discussion @lookup @internal } operationPlan: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Typename_Selected.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Typename_Selected.yaml index 2835d800284..e0998d52899 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Typename_Selected.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Only_Typename_Selected.yaml @@ -32,13 +32,13 @@ sourceSchemas: id: ID! } - type Discussion implements Node @key(fields: "id") { + type Discussion implements Node { id: ID! title: String! } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } interactions: - request: @@ -74,14 +74,14 @@ sourceSchemas: id: ID! } - type Author implements Node @key(fields: "id") { + type Author implements Node { id: ID! username: String! } type Query { authorById(id: ID!): Author @lookup - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable } operationPlan: operation: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Two_Node_Fields_With_Alias.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Two_Node_Fields_With_Alias.yaml index add37c1658f..3b201495546 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Two_Node_Fields_With_Alias.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/GlobalObjectIdentificationTests.Two_Node_Fields_With_Alias.yaml @@ -44,7 +44,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussionById(discussionId: ID! @is(field: "id")): Discussion @lookup } interactions: @@ -104,7 +104,7 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable discussion(id: ID!): Discussion @lookup } interactions: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_Field_Concrete_Type_With_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_Field_Concrete_Type_With_Dependency.yaml index 52131d07cf9..e5bdb32b950 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_Field_Concrete_Type_With_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_Field_Concrete_Type_With_Dependency.yaml @@ -42,7 +42,7 @@ sourceSchemas: type Query { votable: Votable - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interactions: - request: @@ -80,7 +80,7 @@ sourceSchemas: } type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_List_Field_Concrete_Type_With_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_List_Field_Concrete_Type_With_Dependency.yaml index c1d74f44c96..d933ab9c1eb 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_List_Field_Concrete_Type_With_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.Interface_List_Field_Concrete_Type_With_Dependency.yaml @@ -51,7 +51,7 @@ sourceSchemas: type Query { votables: [Votable] - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interactions: - request: @@ -100,7 +100,7 @@ sourceSchemas: } type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.List_Field_Interface_Object_Property_Concrete_Type_With_Dependency.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.List_Field_Interface_Object_Property_Concrete_Type_With_Dependency.yaml index e5afbee1c56..5febf0b53d1 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.List_Field_Interface_Object_Property_Concrete_Type_With_Dependency.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/InterfaceTests.List_Field_Interface_Object_Property_Concrete_Type_With_Dependency.yaml @@ -60,7 +60,7 @@ sourceSchemas: type Query { wrappers: [Wrapper] - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } type Wrapper { @@ -122,7 +122,7 @@ sourceSchemas: } type Query { - discussionById(id: ID!): Discussion @lookup + discussionById(id: ID!): Discussion @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Multiple_Mutation.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Multiple_Mutation.yaml index b4770c05ef5..69d12a08ebd 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Multiple_Mutation.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Multiple_Mutation.yaml @@ -43,7 +43,7 @@ sourceSchemas: mutation: Mutation } - type Book { + type Book @key(fields: "id") { id: Int! title: String! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Single_Mutation.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Single_Mutation.yaml index a442c5a3f26..7ac784650ab 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Single_Mutation.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/MutationTests.Single_Mutation.yaml @@ -29,7 +29,7 @@ sourceSchemas: mutation: Mutation } - type Book { + type Book @key(fields: "id") { id: Int! title: String! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/RequireTests.Require_Object_In_A_List.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/RequireTests.Require_Object_In_A_List.yaml index ac2b9af6c2a..55ea39cf70b 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/RequireTests.Require_Object_In_A_List.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/RequireTests.Require_Object_In_A_List.yaml @@ -80,7 +80,7 @@ sourceSchemas: type Query { books("Returns the first _n_ elements from the list." first: Int "Returns the elements in the list that come after the specified cursor." after: String "Returns the last _n_ elements from the list." last: Int "Returns the elements in the list that come before the specified cursor." before: String): BooksConnection - book(id: Int!): Book @lookup + book(id: Int!): Book @lookup @shareable } interactions: - request: @@ -133,7 +133,7 @@ sourceSchemas: } type Query { - book(id: Int!): Book @lookup + book(id: Int!): Book @lookup @shareable } interactions: - request: @@ -207,7 +207,7 @@ sourceSchemas: } type Query { - book(id: Int!): Book @lookup + book(id: Int!): Book @lookup @shareable } input BookDimensionInput { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup.yaml index c830572a777..b95ed80e00f 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup.yaml @@ -32,24 +32,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -59,7 +59,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -68,7 +68,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -110,23 +110,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -136,7 +136,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -145,7 +145,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml index 44aea9141f4..96f7c4e394b 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml @@ -36,24 +36,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -63,7 +63,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -72,7 +72,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -116,23 +116,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -142,7 +142,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -151,7 +151,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Levels.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Levels.yaml index 02e9ee8b959..6e1c4347ca1 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Levels.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Parent_Fields_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Levels.yaml @@ -40,24 +40,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -67,7 +67,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -76,7 +76,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -122,23 +122,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -148,7 +148,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -157,7 +157,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields.yaml index 9ba2d09caa7..0bd2b6c243a 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields.yaml @@ -28,24 +28,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -55,7 +55,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -64,7 +64,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -100,23 +100,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -126,7 +126,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -135,7 +135,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields_With_Extra_Fields_On_Shared_Level.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields_With_Extra_Fields_On_Shared_Level.yaml index b2935c9d6ed..b1b9623b1bf 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields_With_Extra_Fields_On_Shared_Level.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Hierarchy_Of_Shared_Root_Fields_With_Extra_Fields_On_Shared_Level.yaml @@ -34,24 +34,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -61,7 +61,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -70,7 +70,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -123,23 +123,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -149,7 +149,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -158,7 +158,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -197,7 +197,7 @@ sourceSchemas: } type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup.yaml index 307e9ddc271..839ebeb3904 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup.yaml @@ -28,24 +28,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -55,7 +55,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -64,7 +64,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -102,23 +102,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -128,7 +128,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -137,7 +137,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml index 0ab486c3f40..2beaf08a5f3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Extra_Fields_On_Shared_Level.yaml @@ -32,24 +32,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -59,7 +59,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -68,7 +68,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -108,23 +108,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -134,7 +134,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -143,7 +143,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Type_Refinement.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Type_Refinement.yaml index 0c59d39441c..6d92622da7a 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Type_Refinement.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Shared_Parent_Field_Below_Type_With_Lookup_With_Type_Refinement.yaml @@ -30,24 +30,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -57,7 +57,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -66,7 +66,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -108,23 +108,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -134,7 +134,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -143,7 +143,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Interface_Root_Field_With_Type_Refinement.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Interface_Root_Field_With_Type_Refinement.yaml index 5198b98ee21..43dba964bb7 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Interface_Root_Field_With_Type_Refinement.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Interface_Root_Field_With_Type_Refinement.yaml @@ -26,24 +26,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -53,7 +53,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -62,7 +62,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -98,23 +98,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -124,7 +124,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -133,7 +133,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field.yaml index 53d62863313..3047bd714e2 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field.yaml @@ -24,24 +24,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -51,7 +51,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -60,7 +60,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -92,23 +92,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -118,7 +118,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -127,7 +127,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field_With_Extra_Fields_On_Root.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field_With_Extra_Fields_On_Root.yaml index 44f36d2443b..f3cd505815e 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field_With_Extra_Fields_On_Root.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Root_Field_With_Extra_Fields_On_Root.yaml @@ -28,24 +28,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -55,7 +55,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -64,7 +64,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -98,23 +98,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -124,7 +124,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -133,7 +133,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Union_Root_Field_With_Type_Refinement.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Union_Root_Field_With_Type_Refinement.yaml index c1263fd35ca..f1e0fcce0c8 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Union_Root_Field_With_Type_Refinement.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SharedPathTests.Single_Shared_Union_Root_Field_With_Type_Refinement.yaml @@ -26,24 +26,24 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema1: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { productById(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema1: String! - interface: IInterface! + interface: IInterface! @shareable unsharedInterface: IInterface! - union: IUnion! - topReview: Review! + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -53,7 +53,7 @@ sourceSchemas: type SharedProduct { schema1: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -62,7 +62,7 @@ sourceSchemas: type Viewer { schema1: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { @@ -98,23 +98,23 @@ sourceSchemas: query: Query } - interface IInterface { + interface IInterface @key(fields: "id") { id: Int! } type Product implements IInterface { id: Int! schema2: String! - shared: SharedProduct + shared: SharedProduct @shareable } type Query { product(id: Int!): Product @lookup - viewer: Viewer! + viewer: Viewer! @shareable schema2: String! - interface: IInterface! - union: IUnion! - topReview: Review! + interface: IInterface! @shareable + union: IUnion! @shareable + topReview: Review! @shareable } type Review implements IInterface { @@ -124,7 +124,7 @@ sourceSchemas: type SharedProduct { schema2: String! - shared2: SharedProduct2 + shared2: SharedProduct2 @shareable } type SharedProduct2 { @@ -133,7 +133,7 @@ sourceSchemas: type Viewer { schema2: String! - settings: ViewerSettings! + settings: ViewerSettings! @shareable } type ViewerSettings { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SubscriptionsOverHttpStoreTests.Subscribe_Simple.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SubscriptionsOverHttpStoreTests.Subscribe_Simple.yaml index 132c633e296..6249c289b6d 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SubscriptionsOverHttpStoreTests.Subscribe_Simple.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/__snapshots__/SubscriptionsOverHttpStoreTests.Subscribe_Simple.yaml @@ -43,7 +43,7 @@ sourceSchemas: subscription: Subscription } - type Book { + type Book @key(fields: "id") { id: Int! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/DemoIntegrationTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/DemoIntegrationTests.cs index 8a8dc0bd31f..2849f8fcfef 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/DemoIntegrationTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/DemoIntegrationTests.cs @@ -30,7 +30,7 @@ type Product implements Node { id: ID! } - interface Node { + interface Node @key(fields: "id") { id: ID! } """); @@ -2127,8 +2127,8 @@ public async Task BatchExecutionState_With_Multiple_Variable_Values() "A", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2144,8 +2144,8 @@ type User implements Node { "B", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable userBySlug(slug: String!): User } @@ -2162,8 +2162,8 @@ type User implements Node { "C", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2239,8 +2239,8 @@ public async Task BatchExecutionState_With_Multiple_Variable_Values_Some_Items_N "A", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2256,9 +2256,9 @@ type User implements Node { "B", """ type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable # TODO: This will not work like this - nodes(ids: [ID!]!): [Node]! @null(atIndex: 1) + nodes(ids: [ID!]!): [Node]! @null(atIndex: 1) @shareable userBySlug(slug: String!): User } @@ -2275,8 +2275,8 @@ type User implements Node { "C", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2352,8 +2352,8 @@ public async Task BatchExecutionState_With_Multiple_Variable_Values_And_Forwarde "A", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2369,8 +2369,8 @@ type User implements Node { "B", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable userBySlug(slug: String!): User } @@ -2387,8 +2387,8 @@ type User implements Node { "C", """ type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } interface Node { @@ -2475,7 +2475,7 @@ type Product implements Node { type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { @@ -2483,9 +2483,9 @@ type ProductAvailabilityMail { } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2498,7 +2498,7 @@ interface Node { type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { @@ -2506,8 +2506,8 @@ type ProductAvailabilityMail { } type Query { - node("ID of the object." id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node("ID of the object." id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2560,17 +2560,17 @@ type Product implements Node { type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2582,19 +2582,19 @@ interface Node { } type ProductAvailability implements Node { - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph2Only: Boolean! id: ID! } type ProductAvailabilityMail { subgraph2Only: Boolean! - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node(id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2649,19 +2649,19 @@ type Product implements Node { type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph1Only: Boolean! } type ProductAvailabilityMail { - sharedScalar: String! + sharedScalar: String! @shareable subgraph1Only: String! } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2673,19 +2673,19 @@ interface Node { } type ProductAvailability implements Node { - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph2Only: Boolean! id: ID! } type ProductAvailabilityMail { subgraph2Only: Boolean! - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node(id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } """); @@ -2733,7 +2733,7 @@ public async Task Viewer_Bug_1() """ type Query { exclusiveSubgraphA: ExclusiveSubgraphA - viewer: Viewer + viewer: Viewer @shareable } type ExclusiveSubgraphA { @@ -2749,7 +2749,7 @@ type Viewer { "B", """ type Query { - viewer: Viewer + viewer: Viewer @shareable } type Viewer { @@ -2795,7 +2795,7 @@ public async Task Viewer_Bug_2() """ type Query { exclusiveSubgraphA: ExclusiveSubgraphA - viewer: Viewer + viewer: Viewer @shareable } type ExclusiveSubgraphA { @@ -2803,7 +2803,7 @@ type ExclusiveSubgraphA { } type Viewer { - subType: SubType + subType: SubType @shareable } type SubType { @@ -2815,11 +2815,11 @@ type SubType { "B", """ type Query { - viewer: Viewer + viewer: Viewer @shareable } type Viewer { - subType: SubType + subType: SubType @shareable } type SubType { @@ -2866,7 +2866,7 @@ public async Task Viewer_Bug_3() "A", """ type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { @@ -2878,7 +2878,7 @@ type Viewer { "B", """ type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/SubgraphErrorTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/SubgraphErrorTests.cs index 138e1297a5d..832d039d31b 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/SubgraphErrorTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/SubgraphErrorTests.cs @@ -2352,7 +2352,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -2416,7 +2416,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -2480,7 +2480,7 @@ type Product { brand: Brand! } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -2544,7 +2544,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -2608,7 +2608,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -2672,7 +2672,7 @@ type Product { brand: Brand! } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/TransportErrorTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/TransportErrorTests.cs index 714390e823c..5f19f60da4c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/TransportErrorTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/TransportErrorTests.cs @@ -295,7 +295,7 @@ public async Task Resolve_Parallel_Both_Services_Offline_SharedEntryField_NonNul "A", """ type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { @@ -308,7 +308,7 @@ type Viewer { "B", """ type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { @@ -1154,7 +1154,7 @@ type Product { brand: Brand! } - type Brand { + type Brand @key(fields: "id") { id: ID! } """, @@ -1219,7 +1219,7 @@ type Product { brand: Brand! } - type Brand { + type Brand @key(fields: "id") { id: ID! } """, @@ -1284,7 +1284,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -1349,7 +1349,7 @@ type Product { brand: Brand } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); @@ -1414,7 +1414,7 @@ type Product { brand: Brand! } - type Brand { + type Brand @key(fields: "id") { id: ID! } """); diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values.yaml index ee1bc2dcd1e..c47746ddca8 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values.yaml @@ -71,8 +71,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type User implements Node { @@ -144,8 +144,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable userBySlug(slug: String!): User } @@ -243,8 +243,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type ResaleFeedback implements Node { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_And_Forwarded_Variable.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_And_Forwarded_Variable.yaml index 4a5d97fb127..b1bc93a88fe 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_And_Forwarded_Variable.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_And_Forwarded_Variable.yaml @@ -79,8 +79,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type User implements Node { @@ -156,8 +156,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable userBySlug(slug: String!): User } @@ -259,8 +259,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type ResaleFeedback implements Node { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_Some_Items_Null.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_Some_Items_Null.yaml index 09b25428af6..dc56e2bc788 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_Some_Items_Null.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.BatchExecutionState_With_Multiple_Variable_Values_Some_Items_Null.yaml @@ -71,8 +71,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type User implements Node { @@ -144,8 +144,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! @null(atIndex: 1) + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @null(atIndex: 1) @shareable userBySlug(slug: String!): User } @@ -243,8 +243,8 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable } type ResaleFeedback implements Node { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node.yaml index 5d9aa3b9258..6d64d050cb3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node.yaml @@ -47,7 +47,7 @@ sourceSchemas: type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { @@ -55,9 +55,9 @@ sourceSchemas: } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: @@ -105,7 +105,7 @@ sourceSchemas: type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { @@ -113,8 +113,8 @@ sourceSchemas: } type Query { - node("ID of the object." id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node("ID of the object." id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_2.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_2.yaml index 88841e1953f..1488dc59de7 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_2.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_2.yaml @@ -51,17 +51,17 @@ sourceSchemas: type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable } type ProductAvailabilityMail { - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: @@ -108,19 +108,19 @@ sourceSchemas: } type ProductAvailability implements Node { - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph2Only: Boolean! id: ID! } type ProductAvailabilityMail { subgraph2Only: Boolean! - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node(id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_3.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_3.yaml index 5a83cb7d133..ca5ebaf45da 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_3.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Field_Below_Shared_Field_Only_Available_On_One_Subgraph_Type_Of_Shared_Field_Not_Node_3.yaml @@ -55,19 +55,19 @@ sourceSchemas: type ProductAvailability implements Node { id: ID! - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph1Only: Boolean! } type ProductAvailabilityMail { - sharedScalar: String! + sharedScalar: String! @shareable subgraph1Only: String! } type Query { - node(id: ID!): Node @lookup + node(id: ID!): Node @lookup @shareable productById(id: ID!): Product @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: @@ -118,19 +118,19 @@ sourceSchemas: } type ProductAvailability implements Node { - sharedLinked: ProductAvailabilityMail! + sharedLinked: ProductAvailabilityMail! @shareable subgraph2Only: Boolean! id: ID! } type ProductAvailabilityMail { subgraph2Only: Boolean! - sharedScalar: String! + sharedScalar: String! @shareable } type Query { - node(id: ID!): Node @lookup - productAvailabilityById(id: ID!): ProductAvailability @lookup + node(id: ID!): Node @lookup @shareable + productAvailabilityById(id: ID!): ProductAvailability @lookup @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Same_Selection_On_Two_Object_Types_That_Require_Data_From_Another_Subgraph.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Same_Selection_On_Two_Object_Types_That_Require_Data_From_Another_Subgraph.yaml index 4cd77ac42cf..c748f4bb236 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Same_Selection_On_Two_Object_Types_That_Require_Data_From_Another_Subgraph.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Same_Selection_On_Two_Object_Types_That_Require_Data_From_Another_Subgraph.yaml @@ -40,7 +40,7 @@ sourceSchemas: query: Query } - interface Node { + interface Node @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_1.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_1.yaml index 69fc0634797..ff4b0011718 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_1.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_1.yaml @@ -34,7 +34,7 @@ sourceSchemas: type Query { exclusiveSubgraphA: ExclusiveSubgraphA - viewer: Viewer + viewer: Viewer @shareable } type Viewer { @@ -65,7 +65,7 @@ sourceSchemas: } type Query { - viewer: Viewer + viewer: Viewer @shareable } type Viewer { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_2.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_2.yaml index ecac5b94474..e76977dd574 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_2.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_2.yaml @@ -38,7 +38,7 @@ sourceSchemas: type Query { exclusiveSubgraphA: ExclusiveSubgraphA - viewer: Viewer + viewer: Viewer @shareable } type SubType { @@ -46,7 +46,7 @@ sourceSchemas: } type Viewer { - subType: SubType + subType: SubType @shareable } interactions: - request: @@ -73,7 +73,7 @@ sourceSchemas: } type Query { - viewer: Viewer + viewer: Viewer @shareable } type SubType { @@ -81,7 +81,7 @@ sourceSchemas: } type Viewer { - subType: SubType + subType: SubType @shareable } interactions: - request: diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_3.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_3.yaml index 46b5026ed2f..94ca63646db 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_3.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/DemoIntegrationTests.Viewer_Bug_3.yaml @@ -33,7 +33,7 @@ sourceSchemas: } type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { @@ -64,7 +64,7 @@ sourceSchemas: } type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_EntryField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_EntryField.yaml index b03ee491f03..c1a3864962a 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_EntryField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_EntryField.yaml @@ -34,7 +34,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_SubField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_SubField.yaml index c88d6c2a61c..9d78dd81f7c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_SubField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_NonNull_One_Service_Errors_SubField.yaml @@ -34,7 +34,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_EntryField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_EntryField.yaml index 8bb16e2ebe5..8dab53c69bf 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_EntryField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_EntryField.yaml @@ -37,7 +37,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_SubField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_SubField.yaml index df763f8f09e..9c0730010f3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_SubField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_NonNull_Parent_Nullable_One_Service_Errors_SubField.yaml @@ -37,7 +37,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_EntryField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_EntryField.yaml index de2fbde6698..89d489396f2 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_EntryField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_EntryField.yaml @@ -40,7 +40,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_SubField.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_SubField.yaml index 3b8423c049c..51b4b655372 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_SubField.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/SubgraphErrorTests.Resolve_Sequence_SubField_Nullable_Parent_Nullable_One_Service_Errors_SubField.yaml @@ -40,7 +40,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Parallel_Both_Services_Offline_SharedEntryField_NonNull.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Parallel_Both_Services_Offline_SharedEntryField_NonNull.yaml index 2a10dd0a491..12014a0ab9c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Parallel_Both_Services_Offline_SharedEntryField_NonNull.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Parallel_Both_Services_Offline_SharedEntryField_NonNull.yaml @@ -27,7 +27,7 @@ sourceSchemas: } type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { @@ -50,7 +50,7 @@ sourceSchemas: } type Query { - viewer: Viewer! + viewer: Viewer! @shareable } type Viewer { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_NonNull.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_NonNull.yaml index 91b75079b74..e54ea35b76e 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_NonNull.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_NonNull.yaml @@ -29,7 +29,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_Nullable.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_Nullable.yaml index 564995794cb..27324b21ab9 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_Nullable.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_First_Service_Offline_EntryField_Nullable.yaml @@ -32,7 +32,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_NonNull.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_NonNull.yaml index c80f094e6db..1c293c423ea 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_NonNull.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_NonNull.yaml @@ -34,7 +34,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_Nullable.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_Nullable.yaml index b7d38cc0d63..cc72888ab49 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_Nullable.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_NonNull_Parent_Nullable.yaml @@ -37,7 +37,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_Nullable_Parent_Nullable.yaml b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_Nullable_Parent_Nullable.yaml index a059333ff57..0fc089f1e3c 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_Nullable_Parent_Nullable.yaml +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/v15/__snapshots__/TransportErrorTests.Resolve_Sequence_Second_Service_Offline_SubField_Nullable_Parent_Nullable.yaml @@ -40,7 +40,7 @@ sourceSchemas: query: Query } - type Brand { + type Brand @key(fields: "id") { id: ID! } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/CompositionTestHelper.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/CompositionTestHelper.cs index 65a0054ba7b..31681e82ee5 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/CompositionTestHelper.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/CompositionTestHelper.cs @@ -14,6 +14,14 @@ internal static ImmutableSortedSet CreateSchemaDefiniti sdl.Select((s, i) => new SourceSchemaText(((char)('A' + i)).ToString(), s)), new CompositionLog()); - return sourceSchemaParser.Parse().Value; + var schemas = sourceSchemaParser.Parse().Value; + + foreach (var schema in schemas) + { + new SourceSchemaPreprocessor(schema).Process(); + new SourceSchemaEnricher(schema, schemas).Enrich(); + } + + return schemas; } } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidationRules/InvalidFieldSharingRuleTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidationRules/InvalidFieldSharingRuleTests.cs new file mode 100644 index 00000000000..5dd4719d5f8 --- /dev/null +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PreMergeValidationRules/InvalidFieldSharingRuleTests.cs @@ -0,0 +1,147 @@ +using System.Collections.Immutable; +using HotChocolate.Fusion.Logging; +using static HotChocolate.Fusion.CompositionTestHelper; + +namespace HotChocolate.Fusion.PreMergeValidationRules; + +public sealed class InvalidFieldSharingRuleTests +{ + private static readonly object s_rule = new InvalidFieldSharingRule(); + private static readonly ImmutableArray s_rules = [s_rule]; + private readonly CompositionLog _log = new(); + + [Theory] + [MemberData(nameof(ValidExamplesData))] + public void Examples_Valid(string[] sdl) + { + // arrange + var schemas = CreateSchemaDefinitions(sdl); + var validator = new PreMergeValidator(schemas, s_rules, _log); + + // act + var result = validator.Validate(); + + // assert + Assert.True(result.IsSuccess); + Assert.True(_log.IsEmpty); + } + + [Theory] + [MemberData(nameof(InvalidExamplesData))] + public void Examples_Invalid(string[] sdl, string[] errorMessages) + { + // arrange + var schemas = CreateSchemaDefinitions(sdl); + var validator = new PreMergeValidator(schemas, s_rules, _log); + + // act + var result = validator.Validate(); + + // assert + Assert.True(result.IsFailure); + Assert.Equal(errorMessages, _log.Select(e => e.Message).ToArray()); + Assert.True(_log.All(e => e.Code == "INVALID_FIELD_SHARING")); + Assert.True(_log.All(e => e.Severity == LogSeverity.Error)); + } + + public static TheoryData ValidExamplesData() + { + return new TheoryData + { + // In this example, the "User" type field "fullName" is marked as shareable in both + // schemas, allowing them to serve consistent data for that field without conflict. + { + [ + """ + # Schema A + type User @key(fields: "id") { + id: ID! + username: String + fullName: String @shareable + } + """, + """ + # Schema B + type User @key(fields: "id") { + id: ID! + fullName: String @shareable + email: String + } + """ + ] + }, + // In the following example, "User.fullName" is overridden in one schema and therefore + // the field can be defined in the other schema without being marked as @shareable. + { + [ + """ + # Schema A + type User @key(fields: "id") { + id: ID! + fullName: String @override(from: "B") + } + """, + """ + # Schema B + type User @key(fields: "id") { + id: ID! + fullName: String + } + """ + ] + }, + // In the following example, "User.fullName" is marked as @external in one schema and + // therefore the field can be defined in the other schema without being marked as + // @shareable. + { + [ + """ + # Schema A + type User @key(fields: "id") { + id: ID! + fullName: String @external + } + """, + """ + # Schema B + type User @key(fields: "id") { + id: ID! + fullName: String + } + """ + ] + } + }; + } + + public static TheoryData InvalidExamplesData() + { + return new TheoryData + { + // In the following example, "User.fullName" is non-shareable but is defined and + // resolved by two different schemas, resulting in an INVALID_FIELD_SHARING error. + { + [ + """ + # Schema A + type User @key(fields: "id") { + id: ID! + fullName: String + } + """, + """ + # Schema B + type User @key(fields: "id") { + id: ID! + fullName: String + } + """ + ], + [ + "The field 'User.fullName' in schema 'A' must be shareable.", + "The field 'User.fullName' in schema 'B' must be shareable." + ] + } + }; + } +} diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaEnricherTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaEnricherTests.cs index a13fa5ac0a2..bc9b667c655 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaEnricherTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaEnricherTests.cs @@ -1,5 +1,7 @@ using HotChocolate.Fusion.Extensions; +using HotChocolate.Fusion.Features; using HotChocolate.Fusion.Logging; +using HotChocolate.Types; using HotChocolate.Types.Mutable; namespace HotChocolate.Fusion; @@ -38,42 +40,45 @@ type BookCategory implements Category @shareable { """); var sourceSchemaParser = new SourceSchemaParser([sourceSchemaText], new CompositionLog()); var schema = sourceSchemaParser.Parse().Value.Single(); - var enricher = new SourceSchemaEnricher(schema); + var enricher = new SourceSchemaEnricher(schema, [schema]); // act enricher.Enrich(); + static SourceFieldMetadata GetMetadata(IOutputFieldDefinition field) => + field.GetRequiredSourceFieldMetadata(); + var productType = (MutableObjectTypeDefinition)schema.Types["Product"]; - var productIdFieldMetadata = productType.Fields["id"].GetSourceFieldMetadata(); - var productCategoryFieldMetadata = productType.Fields["category"].GetSourceFieldMetadata(); - var productSkuFieldMetadata = productType.Fields["sku"].GetSourceFieldMetadata(); - var productAlreadyShareableFieldMetadata = productType.Fields["alreadyShareable"].GetSourceFieldMetadata(); - var productExternalFieldMetadata = productType.Fields["externalField"].GetSourceFieldMetadata(); - var productNonKeyFieldMetadata = productType.Fields["nonKeyField"].GetSourceFieldMetadata(); + var productIdFieldMetadata = GetMetadata(productType.Fields["id"]); + var productCategoryFieldMetadata = GetMetadata(productType.Fields["category"]); + var productSkuFieldMetadata = GetMetadata(productType.Fields["sku"]); + var productAlreadyShareableFieldMetadata = GetMetadata(productType.Fields["alreadyShareable"]); + var productExternalFieldMetadata = GetMetadata(productType.Fields["externalField"]); + var productNonKeyFieldMetadata = GetMetadata(productType.Fields["nonKeyField"]); var categoryType = (MutableInterfaceTypeDefinition)schema.Types["Category"]; - var categoryIdFieldMetadata = categoryType.Fields["id"].GetSourceFieldMetadata(); + var categoryIdFieldMetadata = GetMetadata(categoryType.Fields["id"]); var bookCategoryType = (MutableObjectTypeDefinition)schema.Types["BookCategory"]; - var bookCategoryIdFieldMetadata = bookCategoryType.Fields["id"].GetSourceFieldMetadata(); - var bookCategoryCountFieldMetadata = bookCategoryType.Fields["count"].GetSourceFieldMetadata(); + var bookCategoryIdFieldMetadata = GetMetadata(bookCategoryType.Fields["id"]); + var bookCategoryCountFieldMetadata = GetMetadata(bookCategoryType.Fields["count"]); // assert - Assert.True(productIdFieldMetadata?.IsKeyField); - Assert.True(productIdFieldMetadata?.IsShareable); - Assert.True(productCategoryFieldMetadata?.IsKeyField); - Assert.True(productCategoryFieldMetadata?.IsShareable); - Assert.True(productSkuFieldMetadata?.IsKeyField); - Assert.True(productSkuFieldMetadata?.IsShareable); - Assert.True(productAlreadyShareableFieldMetadata?.IsKeyField); - Assert.True(productAlreadyShareableFieldMetadata?.IsShareable); - Assert.True(productExternalFieldMetadata?.IsKeyField); - Assert.False(productExternalFieldMetadata?.IsShareable); - Assert.False(productNonKeyFieldMetadata?.IsKeyField); - Assert.False(productNonKeyFieldMetadata?.IsShareable); - Assert.True(categoryIdFieldMetadata?.IsKeyField); - Assert.True(categoryIdFieldMetadata?.IsShareable); - Assert.False(bookCategoryIdFieldMetadata?.IsKeyField); - Assert.True(bookCategoryIdFieldMetadata?.IsShareable); - Assert.False(bookCategoryCountFieldMetadata?.IsKeyField); - Assert.True(bookCategoryCountFieldMetadata?.IsShareable); + Assert.True(productIdFieldMetadata.IsKeyField); + Assert.True(productIdFieldMetadata.IsShareable); + Assert.True(productCategoryFieldMetadata.IsKeyField); + Assert.True(productCategoryFieldMetadata.IsShareable); + Assert.True(productSkuFieldMetadata.IsKeyField); + Assert.True(productSkuFieldMetadata.IsShareable); + Assert.True(productAlreadyShareableFieldMetadata.IsKeyField); + Assert.True(productAlreadyShareableFieldMetadata.IsShareable); + Assert.True(productExternalFieldMetadata.IsKeyField); + Assert.False(productExternalFieldMetadata.IsShareable); + Assert.False(productNonKeyFieldMetadata.IsKeyField); + Assert.False(productNonKeyFieldMetadata.IsShareable); + Assert.True(categoryIdFieldMetadata.IsKeyField); + Assert.True(categoryIdFieldMetadata.IsShareable); + Assert.False(bookCategoryIdFieldMetadata.IsKeyField); + Assert.True(bookCategoryIdFieldMetadata.IsShareable); + Assert.False(bookCategoryCountFieldMetadata.IsKeyField); + Assert.True(bookCategoryCountFieldMetadata.IsShareable); } } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaMergerTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaMergerTests.cs index 0a85e1bc21f..c2f3fd9d06f 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaMergerTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaMergerTests.cs @@ -14,21 +14,20 @@ public void Merge_WithOperationTypes_SetsOperationTypes() { // arrange var intType = BuiltIns.Int.Create(); - var merger = new SourceSchemaMerger( - [ - new MutableSchemaDefinition + var schema = new MutableSchemaDefinition + { + Types = { - Types = - { - new MutableObjectTypeDefinition(Query) - { Fields = { new MutableOutputFieldDefinition("field", intType) } }, - new MutableObjectTypeDefinition(Mutation) - { Fields = { new MutableOutputFieldDefinition("field", intType) } }, - new MutableObjectTypeDefinition(Subscription) - { Fields = { new MutableOutputFieldDefinition("field", intType) } } - } + new MutableObjectTypeDefinition(Query) + { Fields = { new MutableOutputFieldDefinition("field", intType) } }, + new MutableObjectTypeDefinition(Mutation) + { Fields = { new MutableOutputFieldDefinition("field", intType) } }, + new MutableObjectTypeDefinition(Subscription) + { Fields = { new MutableOutputFieldDefinition("field", intType) } } } - ]); + }; + new SourceSchemaEnricher(schema, [schema]).Enrich(); + var merger = new SourceSchemaMerger([schema]); // act var (isSuccess, _, mergedSchema, _) = merger.Merge(); @@ -44,24 +43,23 @@ public void Merge_WithOperationTypes_SetsOperationTypes() public void Merge_WithEmptyMutationAndSubscriptionType_RemovesEmptyOperationTypes() { // arrange - var merger = new SourceSchemaMerger( - [ - new MutableSchemaDefinition + var schema = new MutableSchemaDefinition + { + Types = { - Types = + new MutableObjectTypeDefinition(Query) { - new MutableObjectTypeDefinition(Query) + Fields = { - Fields = - { - new MutableOutputFieldDefinition("field", BuiltIns.Int.Create()) - } - }, - new MutableObjectTypeDefinition(Mutation), - new MutableObjectTypeDefinition(Subscription) - } + new MutableOutputFieldDefinition("field", BuiltIns.Int.Create()) + } + }, + new MutableObjectTypeDefinition(Mutation), + new MutableObjectTypeDefinition(Subscription) } - ]); + }; + new SourceSchemaEnricher(schema, [schema]).Enrich(); + var merger = new SourceSchemaMerger([schema]); // act var (isSuccess, _, mergedSchema, _) = merger.Merge(); @@ -131,7 +129,10 @@ input ProductDimensionInput @inaccessible { } """); var sourceSchemaParser = new SourceSchemaParser([sourceSchemaTextA, sourceSchemaTextB], new CompositionLog()); - var merger = new SourceSchemaMerger(sourceSchemaParser.Parse().Value); + var schemas = sourceSchemaParser.Parse().Value; + new SourceSchemaEnricher(schemas[0], schemas).Enrich(); + new SourceSchemaEnricher(schemas[1], schemas).Enrich(); + var merger = new SourceSchemaMerger(schemas); // act var result = merger.Merge(); diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaPreprocessorTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaPreprocessorTests.cs index 6cc95757388..bfe28ec08c3 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaPreprocessorTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaPreprocessorTests.cs @@ -102,4 +102,115 @@ type Person { // assert Assert.False(schema.Types["Person"].Directives.ContainsName(WellKnownDirectiveNames.Key)); } + + [Fact] + public void Preprocess_InheritInterfaceKeysEnabled_InheritsInterfaceKeys() + { + // arrange + var sourceSchemaText = + new SourceSchemaText( + "A", + """ + interface Animal @key(fields: "id") @key(fields: "age") { + id: ID! + age: Int + } + + interface Pet implements Animal @key(fields: "name") { + id: ID! + age: Int + name: String + } + + type Dog implements Pet { + id: ID! + age: Int + name: String + } + + type Cat implements Pet { + id: ID! + age: Int + name: String + } + """); + var sourceSchemaParser = new SourceSchemaParser([sourceSchemaText], new CompositionLog()); + var schema = sourceSchemaParser.Parse().Value.Single(); + var preprocessor = new SourceSchemaPreprocessor(schema); + + // act + preprocessor.Process(); + schema.Types.Remove("FieldSelectionMap"); + schema.Types.Remove("FieldSelectionSet"); + schema.DirectiveDefinitions.Clear(); + + // assert + schema.ToString().MatchInlineSnapshot( + // lang=graphql + """ + type Cat implements Pet + @key(fields: "name") + @key(fields: "id") + @key(fields: "age") { + age: Int + id: ID! + name: String + } + + type Dog implements Pet + @key(fields: "name") + @key(fields: "id") + @key(fields: "age") { + age: Int + id: ID! + name: String + } + + interface Animal + @key(fields: "id") + @key(fields: "age") { + age: Int + id: ID! + } + + interface Pet implements Animal + @key(fields: "name") + @key(fields: "id") + @key(fields: "age") { + age: Int + id: ID! + name: String + } + """); + } + + [Fact] + public void Preprocess_InheritInterfaceKeysDisabled_DoesNotInheritInterfaceKeys() + { + // arrange + var sourceSchemaText = + new SourceSchemaText( + "A", + """ + interface Pet @key(fields: "id") { + id: ID! + } + + type Cat implements Pet { + id: ID! + } + """); + var sourceSchemaParser = new SourceSchemaParser([sourceSchemaText], new CompositionLog()); + var schema = sourceSchemaParser.Parse().Value.Single(); + var preprocessor = + new SourceSchemaPreprocessor( + schema, + new SourceSchemaPreprocessorOptions { InheritInterfaceKeys = false }); + + // act + preprocessor.Process(); + + // assert + Assert.False(schema.Types["Cat"].Directives.ContainsName(WellKnownDirectiveNames.Key)); + } } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaValidationRules/InvalidShareableUsageRuleTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaValidationRules/InvalidShareableUsageRuleTests.cs index f4dd356d19f..f62ed917411 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaValidationRules/InvalidShareableUsageRuleTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaValidationRules/InvalidShareableUsageRuleTests.cs @@ -82,7 +82,36 @@ interface InventoryItem { """ ], [ - "The interface field 'InventoryItem.sku' in schema 'A' must not be marked as " + "The field 'InventoryItem.sku' in schema 'A' must not be marked as shareable." + ] + }, + // By definition, root subscription fields cannot be shared across multiple schemas. In + // this example, both schemas define a subscription field "newOrderPlaced". + { + [ + """ + # Schema A + type Subscription { + newOrderPlaced: Order @shareable + } + + type Order { + id: ID! + items: [String] + } + """, + """ + # Schema B + type Subscription { + newOrderPlaced: Order @shareable + } + """ + ], + [ + "The field 'Subscription.newOrderPlaced' in schema 'A' must not be marked as " + + "shareable.", + + "The field 'Subscription.newOrderPlaced' in schema 'B' must not be marked as " + "shareable." ] } diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/FusionTestBase.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/FusionTestBase.cs index 2592066227b..b4fbdf3f3ce 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/FusionTestBase.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/FusionTestBase.cs @@ -41,7 +41,7 @@ interface Node { id: ID! } - type PageInfo { + type PageInfo @shareable { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String @@ -49,8 +49,8 @@ type PageInfo { } type Query { - node("ID of the object." id: ID!): Node @lookup - nodes("The list of node IDs." ids: [ID!]!): [Node]! + node("ID of the object." id: ID!): Node @lookup @shareable + nodes("The list of node IDs." ids: [ID!]!): [Node]! @shareable userById(id: ID!): User @lookup userByUsername(username: String!): User @lookup users(first: Int after: String last: Int before: String): UsersConnection @@ -58,7 +58,7 @@ type Query { type User implements Node { id: ID! - name: String! + name: String! @shareable birthdate: String! username: String! } @@ -96,8 +96,8 @@ type Product { } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable inventoryItemById(id: ID!): InventoryItem @lookup productByIdAsync(id: ID!): Product @lookup @internal } @@ -140,14 +140,14 @@ type OrderItem { order: Order } - type Product { + type Product @key(fields: "id") { id: ID! } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! - orderById(id: ID!): Order @lookup + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable + orderById(id: ID!): Order @lookup @shareable userById(id: ID!): User! @lookup @internal } @@ -195,10 +195,10 @@ type Payment implements Node { } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable paymentById(id: ID!): Payment @lookup - orderById(id: ID!): Order! @lookup + orderById(id: ID!): Order! @lookup @shareable } input CreatePaymentInput { @@ -225,7 +225,7 @@ type Mutation { uploadProductPicture(input: UploadProductPictureInput!): UploadProductPicturePayload! } - type PageInfo { + type PageInfo @shareable { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String @@ -260,8 +260,8 @@ type ProductsEdge { } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable productById(id: ID!): Product @lookup products(first: Int after: String last: Int before: String): ProductsConnection } @@ -296,7 +296,7 @@ type Mutation { createReview(input: CreateReviewInput!): CreateReviewPayload! } - type PageInfo { + type PageInfo @shareable { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String @@ -320,8 +320,8 @@ type ProductReviewsEdge { } type Query { - node(id: ID!): Node @lookup - nodes(ids: [ID!]!): [Node]! + node(id: ID!): Node @lookup @shareable + nodes(ids: [ID!]!): [Node]! @shareable productById(id: ID!): Product! @lookup @internal reviewById(id: ID!): Review @lookup userById(id: ID!): User @lookup @internal @@ -343,7 +343,7 @@ type Subscription { type User { reviews(first: Int after: String last: Int before: String): UserReviewsConnection id: ID! - name: String! + name: String! @shareable } type UserReviewsConnection { diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/OperationPlannerTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/OperationPlannerTests.cs index d52da6b6069..e430a0587ff 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/OperationPlannerTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/OperationPlannerTests.cs @@ -111,7 +111,7 @@ type Query { topProducts: [Product!] } - type Product { + type Product @key(fields: "id") { id: ID! name: String! } @@ -273,7 +273,7 @@ type Query { topProducts: [Product!] } - type Product { + type Product @key(fields: "id") { id: ID! name: String! region: String! @@ -325,7 +325,7 @@ type Query { topProducts: [Product!] } - type Product { + type Product @key(fields: "id") { id: ID! name: String! region: String! @@ -377,7 +377,7 @@ type Query { topProducts: [Product!] } - type Product { + type Product @key(fields: "id") { id: ID! region: String! } @@ -393,7 +393,7 @@ type Query { type Product { id: ID! - sku(region: String! @require(field: "region")): String! + sku(region: String! @require(field: "region")): String! @shareable } """, """ diff --git a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/RequirementTests.cs b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/RequirementTests.cs index 9efcbf6f267..79e5eb5a8e0 100644 --- a/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/RequirementTests.cs +++ b/src/HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/Planning/RequirementTests.cs @@ -16,7 +16,7 @@ type Query { books: [Book] } - type Book { + type Book @key(fields: "id") { id: String! title: String! } @@ -66,7 +66,7 @@ type Brand { name: String! } - type Product { + type Product @key(fields: "id") { id: Int! name: String! brand: Brand @@ -122,7 +122,7 @@ type Brand { name: String! } - type Product { + type Product @key(fields: "id") { id: Int! name: String! brand: Brand From a588e0d2fde8f7d1f4e0ec982360889f1ed445ca Mon Sep 17 00:00:00 2001 From: Glen Date: Wed, 24 Sep 2025 17:21:22 +0200 Subject: [PATCH 2/2] Fixed Nitro test --- .../__resources__/invalid-example-1/source-schema-1.graphqls | 2 +- .../__resources__/invalid-example-1/source-schema-2.graphqls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-1.graphqls b/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-1.graphqls index 74a96d2f46d..de50d8e9b68 100644 --- a/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-1.graphqls +++ b/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-1.graphqls @@ -3,7 +3,7 @@ schema { } type Query { - userById(id: ID!): User! @lookup # Warning: LOOKUP_RETURNS_NON_NULLABLE_TYPE + userById(id: ID!): User! @lookup @shareable # Warning: LOOKUP_RETURNS_NON_NULLABLE_TYPE } type User { diff --git a/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-2.graphqls b/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-2.graphqls index 967e906ad5b..9e54af98c0a 100644 --- a/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-2.graphqls +++ b/src/Nitro/CommandLine/test/CommandLine.Fusion.Tests/__resources__/invalid-example-1/source-schema-2.graphqls @@ -3,7 +3,7 @@ schema { } type Query { - userById(id: ID!): User! @lookup # Warning: LOOKUP_RETURNS_NON_NULLABLE_TYPE + userById(id: ID!): User! @lookup @shareable # Warning: LOOKUP_RETURNS_NON_NULLABLE_TYPE } type User {