diff --git a/src/HotChocolate/Core/src/Types/Types/Relay/Extensions/RelayIdFieldHelpers.cs b/src/HotChocolate/Core/src/Types/Types/Relay/Extensions/RelayIdFieldHelpers.cs index 9e96a048ebd..e6b738207b5 100644 --- a/src/HotChocolate/Core/src/Types/Types/Relay/Extensions/RelayIdFieldHelpers.cs +++ b/src/HotChocolate/Core/src/Types/Types/Relay/Extensions/RelayIdFieldHelpers.cs @@ -261,7 +261,7 @@ private static IInputValueFormatter CreateSerializer( return new GlobalIdInputValueFormatter( completionContext.DescriptorContext.NodeIdSerializerAccessor, resultTypeInfo.NamedType, - resultType.ElementType?.Type ?? resultTypeInfo.NamedType, + resultType.ElementType?.Source ?? resultTypeInfo.NamedType, typeName ?? completionContext.Type.Name, validateType); } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/IdAttributeTests.cs b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/IdAttributeTests.cs index 3fff655033b..b8a9eb7e354 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/IdAttributeTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/IdAttributeTests.cs @@ -51,25 +51,25 @@ query foo( nullableIntIdGivenNull: nullableIntId(id: $nullIntId) optionalIntId(id: $intId) optionalIntIdGivenNothing: optionalIntId - intIdList(id: [$intId]) - nullableIntIdList(id: [$intId, $nullIntId]) - optionalIntIdList(id: [$intId]) + intIdList(ids: [$intId]) + nullableIntIdList(ids: [$intId, $nullIntId]) + optionalIntIdList(ids: [$intId]) stringId(id: $stringId) nullableStringId(id: $stringId) nullableStringIdGivenNull: nullableStringId(id: $nullStringId) optionalStringId(id: $stringId) optionalStringIdGivenNothing: optionalStringId - stringIdList(id: [$stringId]) - nullableStringIdList(id: [$stringId, $nullStringId]) - optionalStringIdList(id: [$stringId]) + stringIdList(ids: [$stringId]) + nullableStringIdList(ids: [$stringId, $nullStringId]) + optionalStringIdList(ids: [$stringId]) guidId(id: $guidId) nullableGuidId(id: $guidId) nullableGuidIdGivenNull: nullableGuidId(id: $nullGuidId) optionalGuidId(id: $guidId) optionalGuidIdGivenNothing: optionalGuidId - guidIdList(id: [$guidId $guidId]) - nullableGuidIdList(id: [$guidId $nullGuidId $guidId]) - optionalGuidIdList(id: [$guidId $guidId]) + guidIdList(ids: [$guidId $guidId]) + nullableGuidIdList(ids: [$guidId $nullGuidId $guidId]) + optionalGuidIdList(ids: [$guidId $guidId]) customId(id: $customId) nullableCustomId(id: $customId) nullableCustomIdGivenNull: nullableCustomId(id: $nullCustomId) @@ -106,7 +106,7 @@ public async Task InterceptedId_On_Arguments() OperationRequestBuilder.New() .SetDocument(@"query foo { interceptedId(id: 1) - interceptedIds(id: [1, 2]) + interceptedIds(ids: [1, 2]) }") .Build()); @@ -464,56 +464,53 @@ public async Task EnsureIdIsOnlyAppliedOnce() [SuppressMessage("Performance", "CA1822:Mark members as static")] public class Query { - public string IntId([ID] int id) => id.ToString(); - public string IntIdList([ID] int[] id) => - string.Join(", ", id.Select(t => t.ToString())); + public int IntId([ID] int id) => id; - public string NullableIntId([ID] int? id) => id?.ToString() ?? "null"; - public string NullableIntIdList([ID] int?[] id) => - string.Join(", ", id.Select(t => t?.ToString() ?? "null")); + public int[] IntIdList([ID] int[] ids) => ids; - public string OptionalIntId([DefaultValue("UXVlcnk6MA==")][ID] Optional id) => - id.HasValue ? id.Value.ToString() : "NO VALUE"; - public string OptionalIntIdList([DefaultValue(new int[] {})][ID] Optional id) => - id.HasValue ? string.Join(", ", id.Value.Select(t => t.ToString())) : "NO VALUE"; + public int? NullableIntId([ID] int? id) => id; + + public int?[] NullableIntIdList([ID] int?[] ids) => ids; + + public int? OptionalIntId([DefaultValue("UXVlcnk6MA==")][ID] Optional id) + => id.HasValue ? id.Value : null; + + public int[]? OptionalIntIdList([DefaultValue(new int[] {})][ID] Optional ids) + => ids.HasValue ? ids.Value : null; public string StringId([ID] string id) => id; - public string StringIdList([ID] string[] id) => - string.Join(", ", id.Select(t => t.ToString())); - - public string NullableStringId([ID] string? id) => id ?? "null"; - public string NullableStringIdList([ID] string?[] id) => - string.Join(", ", id.Select(t => t?.ToString() ?? "null")); - - public string OptionalStringId( - [DefaultValue("UXVlcnk6")][ID] Optional id) => - id.HasValue ? id.Value : "NO VALUE"; - public string OptionalStringIdList( - [DefaultValue(new string[] {})][ID] Optional id) => - id.HasValue ? string.Join(", ", id.Value) : "NO VALUE"; - - public string GuidId([ID] Guid id) => id.ToString(); - public string GuidIdList([ID] IReadOnlyList id) => - string.Join(", ", id.Select(t => t.ToString())); - - public string NullableGuidId([ID] Guid? id) => id?.ToString() ?? "null"; - public string NullableGuidIdList([ID] IReadOnlyList id) => - string.Join(", ", id.Select(t => t?.ToString() ?? "null")); - - public string OptionalGuidId( - [DefaultValue("UXVlcnk6AAAAAAAAAAAAAAAAAAAAAA==")][ID] Optional id) => - id.HasValue ? id.Value.ToString() : "NO VALUE"; - public string OptionalGuidIdList( - [DefaultValue(new object[] {})][ID] Optional id) => - id.HasValue ? string.Join(", ", id.Value.Select(t => t.ToString())) : "NO VALUE"; - - public string InterceptedId([InterceptedID("Query")] [ID] int id) => id.ToString(); - - public string InterceptedIds([InterceptedID("Query")] [ID] int[] id) => - string.Join(", ", id.Select(t => t.ToString())); - - public string CustomId([ID] StronglyTypedId id) => - id.ToString(); + + public string[] StringIdList([ID] string[] ids) => ids; + + public string? NullableStringId([ID] string? id) => id; + + public string?[] NullableStringIdList([ID] string?[] ids) => ids; + + public string? OptionalStringId([DefaultValue("UXVlcnk6")][ID] Optional id) + => id.HasValue ? id.Value : null; + + public string[]? OptionalStringIdList([DefaultValue(new string[] { })] [ID] Optional ids) + => ids.HasValue ? ids.Value : null; + + public Guid GuidId([ID] Guid id) => id; + + public IReadOnlyList GuidIdList([ID] IReadOnlyList ids) => ids; + + public Guid? NullableGuidId([ID] Guid? id) => id; + + public IReadOnlyList NullableGuidIdList([ID] IReadOnlyList ids) => ids; + + public Guid? OptionalGuidId([DefaultValue("UXVlcnk6AAAAAAAAAAAAAAAAAAAAAA==")][ID] Optional id) + => id.HasValue ? id.Value : null; + + public Guid[]? OptionalGuidIdList([DefaultValue(new object[] { })] [ID] Optional ids) + => ids.HasValue ? ids.Value : null; + + public int InterceptedId([InterceptedID("Query")] [ID] int id) => id; + + public int[] InterceptedIds([InterceptedID("Query")] [ID] int[] ids) => ids; + + public string CustomId([ID] StronglyTypedId id) => id.ToString(); public string NullableCustomId([ID] StronglyTypedId? id) => id?.ToString() ?? "null"; diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Arguments.snap b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Arguments.snap index 1df3eba32aa..27804d64c97 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Arguments.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Arguments.snap @@ -1,29 +1,53 @@ -{ +{ "data": { - "intId": "1", - "nullableIntId": "1", - "nullableIntIdGivenNull": "null", - "optionalIntId": "1", - "optionalIntIdGivenNothing": "NO VALUE", - "intIdList": "1", - "nullableIntIdList": "1, 0", - "optionalIntIdList": "1", + "intId": 1, + "nullableIntId": 1, + "nullableIntIdGivenNull": null, + "optionalIntId": 1, + "optionalIntIdGivenNothing": null, + "intIdList": [ + 1 + ], + "nullableIntIdList": [ + 1, + null + ], + "optionalIntIdList": [ + 1 + ], "stringId": "abc", "nullableStringId": "abc", - "nullableStringIdGivenNull": "null", + "nullableStringIdGivenNull": null, "optionalStringId": "abc", - "optionalStringIdGivenNothing": "NO VALUE", - "stringIdList": "abc", - "nullableStringIdList": "abc, null", - "optionalStringIdList": "abc", + "optionalStringIdGivenNothing": null, + "stringIdList": [ + "abc" + ], + "nullableStringIdList": [ + "abc", + null + ], + "optionalStringIdList": [ + "abc" + ], "guidId": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", "nullableGuidId": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", - "nullableGuidIdGivenNull": "null", + "nullableGuidIdGivenNull": null, "optionalGuidId": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", - "optionalGuidIdGivenNothing": "NO VALUE", - "guidIdList": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5, 26a2dc8f-4dab-408c-88c6-523a0a89a2b5", - "nullableGuidIdList": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5, 00000000-0000-0000-0000-000000000000, 26a2dc8f-4dab-408c-88c6-523a0a89a2b5", - "optionalGuidIdList": "26a2dc8f-4dab-408c-88c6-523a0a89a2b5, 26a2dc8f-4dab-408c-88c6-523a0a89a2b5", + "optionalGuidIdGivenNothing": null, + "guidIdList": [ + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5" + ], + "nullableGuidIdList": [ + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", + null, + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5" + ], + "optionalGuidIdList": [ + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5", + "26a2dc8f-4dab-408c-88c6-523a0a89a2b5" + ], "customId": "1-2", "nullableCustomId": "1-2", "nullableCustomIdGivenNull": "null", diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Objects_Given_Nulls.snap b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Objects_Given_Nulls.snap index 1508b3abee8..d78bb2d624c 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Objects_Given_Nulls.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_On_Objects_Given_Nulls.snap @@ -1,5 +1,5 @@ -{ - "result": "{\n \"data\": {\n \"foo\": {\n \"someId\": \"QmFyOjE=\",\n \"someNullableId\": null,\n \"someIds\": [\n \"QmF6OjE=\"\n ],\n \"someNullableIds\": [\n \"QmF6OjA=\",\n \"QmF6OjE=\"\n ]\n }\n }\n}", +{ + "result": "{\n \"data\": {\n \"foo\": {\n \"someId\": \"QmFyOjE=\",\n \"someNullableId\": null,\n \"someIds\": [\n \"QmF6OjE=\"\n ],\n \"someNullableIds\": [\n null,\n \"QmF6OjE=\"\n ]\n }\n }\n}", "someId": "U29tZTox", "someIntId": "U29tZTox" } diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_Type_Is_Correctly_Inferred.snap b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_Type_Is_Correctly_Inferred.snap index b8899292293..1b888ee3c62 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_Type_Is_Correctly_Inferred.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.Id_Type_Is_Correctly_Inferred.snap @@ -1,4 +1,4 @@ -schema { +schema { query: Query } @@ -23,26 +23,26 @@ type FooPayload implements IFooPayload { } type Query { - intId(id: ID!): String! - intIdList(id: [ID!]!): String! - nullableIntId(id: ID): String! - nullableIntIdList(id: [ID]!): String! - optionalIntId(id: ID = "UXVlcnk6MA=="): String! - optionalIntIdList(id: [ID!] = [ ]): String! + intId(id: ID!): Int! + intIdList(ids: [ID!]!): [Int!]! + nullableIntId(id: ID): Int + nullableIntIdList(ids: [ID]!): [Int]! + optionalIntId(id: ID = "UXVlcnk6MA=="): Int + optionalIntIdList(ids: [ID!] = [ ]): [Int!] stringId(id: ID!): String! - stringIdList(id: [ID!]!): String! - nullableStringId(id: ID): String! - nullableStringIdList(id: [ID]!): String! - optionalStringId(id: ID = "UXVlcnk6"): String! - optionalStringIdList(id: [ID] = [ ]): String! - guidId(id: ID!): String! - guidIdList(id: [ID!]!): String! - nullableGuidId(id: ID): String! - nullableGuidIdList(id: [ID]!): String! - optionalGuidId(id: ID = "UXVlcnk6AAAAAAAAAAAAAAAAAAAAAA=="): String! - optionalGuidIdList(id: [ID] = [ ]): String! - interceptedId(id: ID!): String! - interceptedIds(id: [ID!]!): String! + stringIdList(ids: [ID!]!): [String!]! + nullableStringId(id: ID): String + nullableStringIdList(ids: [ID]!): [String]! + optionalStringId(id: ID = "UXVlcnk6"): String + optionalStringIdList(ids: [ID] = [ ]): [String!] + guidId(id: ID!): UUID! + guidIdList(ids: [ID!]!): [UUID!]! + nullableGuidId(id: ID): UUID + nullableGuidIdList(ids: [ID]!): [UUID]! + optionalGuidId(id: ID = "UXVlcnk6AAAAAAAAAAAAAAAAAAAAAA=="): UUID + optionalGuidIdList(ids: [ID] = [ ]): [UUID!] + interceptedId(id: ID!): Int! + interceptedIds(ids: [ID!]!): [Int!]! customId(id: ID!): String! nullableCustomId(id: ID): String! customIds(ids: [ID!]!): String! @@ -60,3 +60,8 @@ input FooInput { interceptedId: ID interceptedIds: [ID!] } + +"The `@specifiedBy` directive is used within the type system definition language to provide a URL for specifying the behavior of custom scalar definitions." +directive @specifiedBy("The specifiedBy URL points to a human-readable specification. This field will only read a result for scalar types." url: String!) on SCALAR + +scalar UUID @specifiedBy(url: "https:\/\/tools.ietf.org\/html\/rfc4122") diff --git a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.InterceptedId_On_Arguments.snap b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.InterceptedId_On_Arguments.snap index 7ff6b6bcda4..3772a99b285 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.InterceptedId_On_Arguments.snap +++ b/src/HotChocolate/Core/test/Types.Tests/Types/Relay/__snapshots__/IdAttributeTests.InterceptedId_On_Arguments.snap @@ -1,6 +1,9 @@ -{ +{ "data": { - "interceptedId": "1", - "interceptedIds": "1, 2" + "interceptedId": 1, + "interceptedIds": [ + 1, + 2 + ] } }