From f43d0b4f25d6b03c9030d9b44749dcd99d0fc67c Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 26 Apr 2024 08:23:46 -0500 Subject: [PATCH 1/5] failing test --- .../expected.kt | 29 ++++++++++ .../schema.graphql | 54 +++++++++++++++++++ .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 8 files changed, 83 insertions(+) create mode 100644 test/unit/should_consolidate_input_and_output_types/expected.kt create mode 100644 test/unit/should_consolidate_input_and_output_types/schema.graphql rename test/unit/{should_default_non-nullable_boolean_fields_to_false => should_default_non_nullable_boolean_fields_to_false}/expected.kt (100%) rename test/unit/{should_default_non-nullable_boolean_fields_to_false => should_default_non_nullable_boolean_fields_to_false}/schema.graphql (100%) rename test/unit/{should_generate_multi-union_types_properly => should_generate_multi_union_types_properly}/expected.kt (100%) rename test/unit/{should_generate_multi-union_types_properly => should_generate_multi_union_types_properly}/schema.graphql (100%) rename test/unit/{should_generate_non-nullable_union_list_types_properly => should_generate_non_nullable_union_list_types_properly}/expected.kt (100%) rename test/unit/{should_generate_non-nullable_union_list_types_properly => should_generate_non_nullable_union_list_types_properly}/schema.graphql (100%) diff --git a/test/unit/should_consolidate_input_and_output_types/expected.kt b/test/unit/should_consolidate_input_and_output_types/expected.kt new file mode 100644 index 0000000..541c1be --- /dev/null +++ b/test/unit/should_consolidate_input_and_output_types/expected.kt @@ -0,0 +1,29 @@ +package com.kotlin.generated + +import com.expediagroup.graphql.generator.annotations.* + +data class MyTypeToConsolidate1( + val field: String? = null +) + +@GraphQLDescription("A description for MyTypeToConsolidate2") +data class MyTypeToConsolidate2( + val field: String? = null +) + +data class MyTypeToConsolidate3( + val field: String? = null +) + +@GraphQLDescription("It always uses the type description when consolidating") +data class MyTypeToConsolidate4( + val field: String? = null +) + +data class MyTypeNotToConsolidate( + val field: String? = null +) + +data class MyTypeToNotConsolidateInput( + val field: String? = null +) diff --git a/test/unit/should_consolidate_input_and_output_types/schema.graphql b/test/unit/should_consolidate_input_and_output_types/schema.graphql new file mode 100644 index 0000000..5cc4e03 --- /dev/null +++ b/test/unit/should_consolidate_input_and_output_types/schema.graphql @@ -0,0 +1,54 @@ +# typical case where input and output types are consolidated + +type MyTypeToConsolidate { + field: String +} + +input MyTypeToConsolidateInput { + field: String +} + +# case where type has description but input does not + +"A description for MyTypeToConsolidate2" +type MyTypeToConsolidate2 { + field: String +} + +input MyTypeToConsolidate2Input { + field: String +} + +# case where input has description but type does not + +type MyTypeToConsolidate3 { + field: String +} + +"It ignores the description on the input when consolidating" +input MyTypeToConsolidate3Input { + field: String +} + +# case where both type and input have descriptions + +"It always uses the type description when consolidating" +type MyTypeToConsolidate4 { + field: String +} + +"A description for MyTypeToConsolidateInput4" +input MyTypeToConsolidate4Input { + field: String +} + +# case where type and input names do not match + +type MyTypeNotToConsolidate { + field: String +} + +"The type name must exactly match in order to consolidate" +input MyTypeToNotConsolidateInput { + field: String +} diff --git a/test/unit/should_default_non-nullable_boolean_fields_to_false/expected.kt b/test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt similarity index 100% rename from test/unit/should_default_non-nullable_boolean_fields_to_false/expected.kt rename to test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt diff --git a/test/unit/should_default_non-nullable_boolean_fields_to_false/schema.graphql b/test/unit/should_default_non_nullable_boolean_fields_to_false/schema.graphql similarity index 100% rename from test/unit/should_default_non-nullable_boolean_fields_to_false/schema.graphql rename to test/unit/should_default_non_nullable_boolean_fields_to_false/schema.graphql diff --git a/test/unit/should_generate_multi-union_types_properly/expected.kt b/test/unit/should_generate_multi_union_types_properly/expected.kt similarity index 100% rename from test/unit/should_generate_multi-union_types_properly/expected.kt rename to test/unit/should_generate_multi_union_types_properly/expected.kt diff --git a/test/unit/should_generate_multi-union_types_properly/schema.graphql b/test/unit/should_generate_multi_union_types_properly/schema.graphql similarity index 100% rename from test/unit/should_generate_multi-union_types_properly/schema.graphql rename to test/unit/should_generate_multi_union_types_properly/schema.graphql diff --git a/test/unit/should_generate_non-nullable_union_list_types_properly/expected.kt b/test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt similarity index 100% rename from test/unit/should_generate_non-nullable_union_list_types_properly/expected.kt rename to test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt diff --git a/test/unit/should_generate_non-nullable_union_list_types_properly/schema.graphql b/test/unit/should_generate_non_nullable_union_list_types_properly/schema.graphql similarity index 100% rename from test/unit/should_generate_non-nullable_union_list_types_properly/schema.graphql rename to test/unit/should_generate_non_nullable_union_list_types_properly/schema.graphql From aad9208bf150489d22430973257c098d9c8c2f67 Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 26 Apr 2024 08:28:43 -0500 Subject: [PATCH 2/5] pass test --- src/definitions/input.ts | 6 ++++++ src/definitions/object.ts | 8 +++++++- .../should_consolidate_input_and_output_types/expected.kt | 7 ++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/definitions/input.ts b/src/definitions/input.ts index ddca970..5807424 100644 --- a/src/definitions/input.ts +++ b/src/definitions/input.ts @@ -27,6 +27,12 @@ export function buildInputObjectDefinition( return ""; } + const typeNameWithoutInput = node.name.value.replace("Input", ""); + const correspondingType = schema.getType(typeNameWithoutInput); + if (correspondingType) { + return ""; + } + const classMembers = (node.fields ?? []) .map((arg) => { const typeToUse = buildTypeMetadata(arg.type, schema, config); diff --git a/src/definitions/object.ts b/src/definitions/object.ts index 29dbcb5..1a39ee8 100644 --- a/src/definitions/object.ts +++ b/src/definitions/object.ts @@ -34,6 +34,12 @@ export function buildObjectTypeDefinition( return ""; } + const typeNameWithInput = `${node.name.value}Input`; + const correspondingInput = schema.getType(typeNameWithInput); + const inputOutputAnnotation = correspondingInput + ? "@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT])\n" + : ""; + const annotations = buildAnnotations({ config, definitionNode: node, @@ -57,7 +63,7 @@ ${getDataClassMembers({ node, schema, config, completableFuture: true })} }`; } - return `${annotations}data class ${name}( + return `${annotations}${inputOutputAnnotation}data class ${name}( ${getDataClassMembers({ node, schema, config })} )${interfaceInheritance}`; } diff --git a/test/unit/should_consolidate_input_and_output_types/expected.kt b/test/unit/should_consolidate_input_and_output_types/expected.kt index 541c1be..0878c5f 100644 --- a/test/unit/should_consolidate_input_and_output_types/expected.kt +++ b/test/unit/should_consolidate_input_and_output_types/expected.kt @@ -2,20 +2,24 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* -data class MyTypeToConsolidate1( +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) +data class MyTypeToConsolidate( val field: String? = null ) @GraphQLDescription("A description for MyTypeToConsolidate2") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate2( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate3( val field: String? = null ) @GraphQLDescription("It always uses the type description when consolidating") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate4( val field: String? = null ) @@ -24,6 +28,7 @@ data class MyTypeNotToConsolidate( val field: String? = null ) +@GraphQLDescription("The type name must exactly match in order to consolidate") data class MyTypeToNotConsolidateInput( val field: String? = null ) From ebd835da9851651371353ba35d0f3f8f5eeb7952 Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 26 Apr 2024 08:46:15 -0500 Subject: [PATCH 3/5] refactor --- src/definitions/input.ts | 4 ++-- src/definitions/object.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/definitions/input.ts b/src/definitions/input.ts index 5807424..26802e7 100644 --- a/src/definitions/input.ts +++ b/src/definitions/input.ts @@ -28,8 +28,8 @@ export function buildInputObjectDefinition( } const typeNameWithoutInput = node.name.value.replace("Input", ""); - const correspondingType = schema.getType(typeNameWithoutInput); - if (correspondingType) { + const matchingType = schema.getType(typeNameWithoutInput); + if (matchingType) { return ""; } diff --git a/src/definitions/object.ts b/src/definitions/object.ts index 1a39ee8..618c89d 100644 --- a/src/definitions/object.ts +++ b/src/definitions/object.ts @@ -35,8 +35,8 @@ export function buildObjectTypeDefinition( } const typeNameWithInput = `${node.name.value}Input`; - const correspondingInput = schema.getType(typeNameWithInput); - const inputOutputAnnotation = correspondingInput + const matchingInput = schema.getType(typeNameWithInput); + const typeConsolidationAnnotation = matchingInput ? "@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT])\n" : ""; @@ -63,7 +63,7 @@ ${getDataClassMembers({ node, schema, config, completableFuture: true })} }`; } - return `${annotations}${inputOutputAnnotation}data class ${name}( + return `${annotations}${typeConsolidationAnnotation}data class ${name}( ${getDataClassMembers({ node, schema, config })} )${interfaceInheritance}`; } From c6f38ab3127749845440e21ba789f7a464e1bf4c Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 26 Apr 2024 10:25:08 -0500 Subject: [PATCH 4/5] improve test cases --- src/definitions/input.ts | 52 +++++++++++++++++-- src/definitions/object.ts | 8 +-- .../expected.kt | 27 ++++++++-- .../schema.graphql | 34 +++++++++++- 4 files changed, 105 insertions(+), 16 deletions(-) diff --git a/src/definitions/input.ts b/src/definitions/input.ts index 26802e7..ae78bcf 100644 --- a/src/definitions/input.ts +++ b/src/definitions/input.ts @@ -11,7 +11,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { GraphQLSchema, InputObjectTypeDefinitionNode } from "graphql"; +import { + GraphQLSchema, + InputObjectTypeDefinitionNode, + Kind, + TypeNode, +} from "graphql"; import { shouldIncludeTypeDefinition } from "../helpers/should-include-type-definition"; import { buildTypeMetadata } from "../helpers/build-type-metadata"; import { buildAnnotations } from "../helpers/build-annotations"; @@ -27,9 +32,21 @@ export function buildInputObjectDefinition( return ""; } - const typeNameWithoutInput = node.name.value.replace("Input", ""); - const matchingType = schema.getType(typeNameWithoutInput); - if (matchingType) { + const typeNameWithoutInput = getTypeNameWithoutInput(node.name.value); + const matchingType = schema.getType(typeNameWithoutInput)?.astNode; + const matchingTypeFields = + matchingType?.kind === Kind.OBJECT_TYPE_DEFINITION + ? matchingType.fields + : []; + const inputFields = node.fields; + const fieldsMatch = matchingTypeFields?.every((field) => { + const matchingInputField = inputFields?.find( + (inputField) => inputField.name.value === field.name.value, + ); + if (!matchingInputField) return false; + return fieldsAreEquivalent(field.type, matchingInputField.type); + }); + if (matchingTypeFields?.length && fieldsMatch) { return ""; } @@ -60,3 +77,30 @@ export function buildInputObjectDefinition( ${classMembers} )`; } + +function getTypeNameWithoutInput(name: string) { + return name.endsWith("Input") ? name.replace("Input", "") : name; +} + +function fieldsAreEquivalent( + typeField: TypeNode, + inputField: TypeNode, +): boolean { + switch (typeField.kind) { + case Kind.NAMED_TYPE: + return ( + inputField.kind === Kind.NAMED_TYPE && + typeField.name.value === getTypeNameWithoutInput(inputField.name.value) + ); + case Kind.LIST_TYPE: + return ( + inputField.kind === Kind.LIST_TYPE && + fieldsAreEquivalent(typeField.type, inputField.type) + ); + case Kind.NON_NULL_TYPE: + return ( + inputField.kind === Kind.NON_NULL_TYPE && + fieldsAreEquivalent(typeField.type, inputField.type) + ); + } +} diff --git a/src/definitions/object.ts b/src/definitions/object.ts index 618c89d..29dbcb5 100644 --- a/src/definitions/object.ts +++ b/src/definitions/object.ts @@ -34,12 +34,6 @@ export function buildObjectTypeDefinition( return ""; } - const typeNameWithInput = `${node.name.value}Input`; - const matchingInput = schema.getType(typeNameWithInput); - const typeConsolidationAnnotation = matchingInput - ? "@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT])\n" - : ""; - const annotations = buildAnnotations({ config, definitionNode: node, @@ -63,7 +57,7 @@ ${getDataClassMembers({ node, schema, config, completableFuture: true })} }`; } - return `${annotations}${typeConsolidationAnnotation}data class ${name}( + return `${annotations}data class ${name}( ${getDataClassMembers({ node, schema, config })} )${interfaceInheritance}`; } diff --git a/test/unit/should_consolidate_input_and_output_types/expected.kt b/test/unit/should_consolidate_input_and_output_types/expected.kt index 0878c5f..5ad0a2a 100644 --- a/test/unit/should_consolidate_input_and_output_types/expected.kt +++ b/test/unit/should_consolidate_input_and_output_types/expected.kt @@ -2,24 +2,25 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* -@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate( + val field: List? = null, + val field2: NestedTypeToConsolidate? = null +) + +data class NestedTypeToConsolidate( val field: String? = null ) @GraphQLDescription("A description for MyTypeToConsolidate2") -@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate2( val field: String? = null ) -@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate3( val field: String? = null ) @GraphQLDescription("It always uses the type description when consolidating") -@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT, GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToConsolidate4( val field: String? = null ) @@ -32,3 +33,21 @@ data class MyTypeNotToConsolidate( data class MyTypeToNotConsolidateInput( val field: String? = null ) + +data class MyTypeToNotConsolidate2( + val field: String? = null +) + +data class MyTypeInputToNotConsolidate2( + val field: String? = null +) + +data class MyTypeWhereFieldsDoNotMatch( + val field: String? = null, + val field2: String? = null +) + +data class MyTypeWhereFieldsDoNotMatchInput( + val field: String? = null, + val field2: Int? = null +) diff --git a/test/unit/should_consolidate_input_and_output_types/schema.graphql b/test/unit/should_consolidate_input_and_output_types/schema.graphql index 5cc4e03..2cacc6a 100644 --- a/test/unit/should_consolidate_input_and_output_types/schema.graphql +++ b/test/unit/should_consolidate_input_and_output_types/schema.graphql @@ -1,10 +1,20 @@ # typical case where input and output types are consolidated type MyTypeToConsolidate { - field: String + field: [String!] + field2: NestedTypeToConsolidate } input MyTypeToConsolidateInput { + field: [String!] + field2: NestedTypeToConsolidateInput +} + +type NestedTypeToConsolidate { + field: String +} + +input NestedTypeToConsolidateInput { field: String } @@ -52,3 +62,25 @@ type MyTypeNotToConsolidate { input MyTypeToNotConsolidateInput { field: String } + +# case where type has input in the middle of the name + +type MyTypeToNotConsolidate2 { + field: String +} + +input MyTypeInputToNotConsolidate2 { + field: String +} + +# case where type and input names match but fields do not match + +type MyTypeWhereFieldsDoNotMatch { + field: String + field2: String +} + +input MyTypeWhereFieldsDoNotMatchInput { + field: String + field2: Int +} From 0ec20175e953120d1dbdafca774c784992d33d1f Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Fri, 26 Apr 2024 11:07:26 -0500 Subject: [PATCH 5/5] fix: include GraphQLValidObject annotation on all input and output types --- src/definitions/input.ts | 56 +++---------------- src/definitions/object.ts | 10 +++- .../input-type-has-matching-output-type.ts | 52 +++++++++++++++++ .../expected.kt | 1 + .../expected.kt | 6 ++ .../expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 2 + .../expected.kt | 1 + .../expected.kt | 3 + .../expected.kt | 3 + .../expected.kt | 1 + .../expected.kt | 3 + .../expected.kt | 3 + .../expected.kt | 3 + .../expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 2 + .../expected.kt | 1 + .../should_honor_onlyTypes_config/expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 1 + .../expected.kt | 3 + .../expected.kt | 12 ++++ .../expected.kt | 1 + .../should_support_custom_scalars/expected.kt | 2 + 28 files changed, 124 insertions(+), 50 deletions(-) create mode 100644 src/helpers/input-type-has-matching-output-type.ts diff --git a/src/definitions/input.ts b/src/definitions/input.ts index ae78bcf..0fd416c 100644 --- a/src/definitions/input.ts +++ b/src/definitions/input.ts @@ -11,17 +11,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { - GraphQLSchema, - InputObjectTypeDefinitionNode, - Kind, - TypeNode, -} from "graphql"; +import { GraphQLSchema, InputObjectTypeDefinitionNode } from "graphql"; import { shouldIncludeTypeDefinition } from "../helpers/should-include-type-definition"; import { buildTypeMetadata } from "../helpers/build-type-metadata"; import { buildAnnotations } from "../helpers/build-annotations"; import { indent } from "@graphql-codegen/visitor-plugin-common"; import { CodegenConfigWithDefaults } from "../helpers/build-config-with-defaults"; +import { inputTypeHasMatchingOutputType } from "../helpers/input-type-has-matching-output-type"; export function buildInputObjectDefinition( node: InputObjectTypeDefinitionNode, @@ -32,21 +28,8 @@ export function buildInputObjectDefinition( return ""; } - const typeNameWithoutInput = getTypeNameWithoutInput(node.name.value); - const matchingType = schema.getType(typeNameWithoutInput)?.astNode; - const matchingTypeFields = - matchingType?.kind === Kind.OBJECT_TYPE_DEFINITION - ? matchingType.fields - : []; - const inputFields = node.fields; - const fieldsMatch = matchingTypeFields?.every((field) => { - const matchingInputField = inputFields?.find( - (inputField) => inputField.name.value === field.name.value, - ); - if (!matchingInputField) return false; - return fieldsAreEquivalent(field.type, matchingInputField.type); - }); - if (matchingTypeFields?.length && fieldsMatch) { + const typeWillBeConsolidated = inputTypeHasMatchingOutputType(node, schema); + if (typeWillBeConsolidated) { return ""; } @@ -73,34 +56,9 @@ export function buildInputObjectDefinition( definitionNode: node, }); - return `${annotations}data class ${node.name.value}( + const inputRestrictionAnnotation = + "@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT])\n"; + return `${annotations}${inputRestrictionAnnotation}data class ${node.name.value}( ${classMembers} )`; } - -function getTypeNameWithoutInput(name: string) { - return name.endsWith("Input") ? name.replace("Input", "") : name; -} - -function fieldsAreEquivalent( - typeField: TypeNode, - inputField: TypeNode, -): boolean { - switch (typeField.kind) { - case Kind.NAMED_TYPE: - return ( - inputField.kind === Kind.NAMED_TYPE && - typeField.name.value === getTypeNameWithoutInput(inputField.name.value) - ); - case Kind.LIST_TYPE: - return ( - inputField.kind === Kind.LIST_TYPE && - fieldsAreEquivalent(typeField.type, inputField.type) - ); - case Kind.NON_NULL_TYPE: - return ( - inputField.kind === Kind.NON_NULL_TYPE && - fieldsAreEquivalent(typeField.type, inputField.type) - ); - } -} diff --git a/src/definitions/object.ts b/src/definitions/object.ts index 29dbcb5..c16d3ef 100644 --- a/src/definitions/object.ts +++ b/src/definitions/object.ts @@ -24,6 +24,7 @@ import { isResolverType } from "../helpers/is-resolver-type"; import { buildFieldDefinition } from "../helpers/build-field-definition"; import { isExternalField } from "../helpers/is-external-field"; import { CodegenConfigWithDefaults } from "../helpers/build-config-with-defaults"; +import { inputTypeHasMatchingOutputType } from "../helpers/input-type-has-matching-output-type"; export function buildObjectTypeDefinition( node: ObjectTypeDefinitionNode, @@ -57,7 +58,14 @@ ${getDataClassMembers({ node, schema, config, completableFuture: true })} }`; } - return `${annotations}data class ${name}( + const potentialMatchingInputType = schema.getType(`${name}Input`)?.astNode; + const typeWillBeConsolidated = + potentialMatchingInputType?.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && + inputTypeHasMatchingOutputType(potentialMatchingInputType, schema); + const outputRestrictionAnnotation = typeWillBeConsolidated + ? "" + : "@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])\n"; + return `${annotations}${outputRestrictionAnnotation}data class ${name}( ${getDataClassMembers({ node, schema, config })} )${interfaceInheritance}`; } diff --git a/src/helpers/input-type-has-matching-output-type.ts b/src/helpers/input-type-has-matching-output-type.ts new file mode 100644 index 0000000..590657e --- /dev/null +++ b/src/helpers/input-type-has-matching-output-type.ts @@ -0,0 +1,52 @@ +import { Kind, TypeNode } from "graphql/index"; +import { GraphQLSchema, InputObjectTypeDefinitionNode } from "graphql"; + +export function inputTypeHasMatchingOutputType( + inputTypeNode: InputObjectTypeDefinitionNode, + schema: GraphQLSchema, +) { + const typeNameWithoutInput = getTypeNameWithoutInput( + inputTypeNode.name.value, + ); + const matchingType = schema.getType(typeNameWithoutInput)?.astNode; + const matchingTypeFields = + matchingType?.kind === Kind.OBJECT_TYPE_DEFINITION + ? matchingType.fields + : []; + const inputFields = inputTypeNode.fields; + const fieldsMatch = matchingTypeFields?.every((field) => { + const matchingInputField = inputFields?.find( + (inputField) => inputField.name.value === field.name.value, + ); + if (!matchingInputField) return false; + return fieldsAreEquivalent(field.type, matchingInputField.type); + }); + return Boolean(matchingTypeFields?.length && fieldsMatch); +} + +function getTypeNameWithoutInput(name: string) { + return name.endsWith("Input") ? name.replace("Input", "") : name; +} + +function fieldsAreEquivalent( + typeField: TypeNode, + inputField: TypeNode, +): boolean { + switch (typeField.kind) { + case Kind.NAMED_TYPE: + return ( + inputField.kind === Kind.NAMED_TYPE && + typeField.name.value === getTypeNameWithoutInput(inputField.name.value) + ); + case Kind.LIST_TYPE: + return ( + inputField.kind === Kind.LIST_TYPE && + fieldsAreEquivalent(typeField.type, inputField.type) + ); + case Kind.NON_NULL_TYPE: + return ( + inputField.kind === Kind.NON_NULL_TYPE && + fieldsAreEquivalent(typeField.type, inputField.type) + ); + } +} diff --git a/test/unit/should_annotate_types_properly/expected.kt b/test/unit/should_annotate_types_properly/expected.kt index 1ad5a55..2f578ac 100644 --- a/test/unit/should_annotate_types_properly/expected.kt +++ b/test/unit/should_annotate_types_properly/expected.kt @@ -3,6 +3,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for MyType") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeThatShouldBeProperlyAnnotated( val field: String? = null, @GraphQLDescription("A description for fieldWithDescription") diff --git a/test/unit/should_consolidate_input_and_output_types/expected.kt b/test/unit/should_consolidate_input_and_output_types/expected.kt index 5ad0a2a..ecb33e7 100644 --- a/test/unit/should_consolidate_input_and_output_types/expected.kt +++ b/test/unit/should_consolidate_input_and_output_types/expected.kt @@ -25,28 +25,34 @@ data class MyTypeToConsolidate4( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeNotToConsolidate( val field: String? = null ) @GraphQLDescription("The type name must exactly match in order to consolidate") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyTypeToNotConsolidateInput( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeToNotConsolidate2( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyTypeInputToNotConsolidate2( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeWhereFieldsDoNotMatch( val field: String? = null, val field2: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyTypeWhereFieldsDoNotMatchInput( val field: String? = null, val field2: Int? = null diff --git a/test/unit/should_convert_graphql_float_to_kotlin_double/expected.kt b/test/unit/should_convert_graphql_float_to_kotlin_double/expected.kt index 64d6c41..8b5ace2 100644 --- a/test/unit/should_convert_graphql_float_to_kotlin_double/expected.kt +++ b/test/unit/should_convert_graphql_float_to_kotlin_double/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyFloatType( val field: Double? = null ) diff --git a/test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt b/test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt index 4a8680a..e466ee1 100644 --- a/test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt +++ b/test/unit/should_default_non_nullable_boolean_fields_to_false/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyBooleanType( val field: Boolean = false, val field2: Boolean? = null diff --git a/test/unit/should_generate_field_resolver_interfaces/expected.kt b/test/unit/should_generate_field_resolver_interfaces/expected.kt index 12d5406..f0a6055 100644 --- a/test/unit/should_generate_field_resolver_interfaces/expected.kt +++ b/test/unit/should_generate_field_resolver_interfaces/expected.kt @@ -18,6 +18,7 @@ interface QueryCompletableFuture { fun nonNullableResolver(arg: InputTypeGenerateFieldResolverInterfaces): java.util.concurrent.CompletableFuture } +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class InputTypeGenerateFieldResolverInterfaces( val field: String? = null ) diff --git a/test/unit/should_generate_input_types_properly/expected.kt b/test/unit/should_generate_input_types_properly/expected.kt index ac9316d..3d5e1fd 100644 --- a/test/unit/should_generate_input_types_properly/expected.kt +++ b/test/unit/should_generate_input_types_properly/expected.kt @@ -3,6 +3,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for MyInputType") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class InputTypeThatShouldBeGeneratedProperly( val field1: String? = null, @GraphQLDescription("A description for field2") diff --git a/test/unit/should_generate_interfaces_with_inheritance/expected.kt b/test/unit/should_generate_interfaces_with_inheritance/expected.kt index 972bbe0..9868688 100644 --- a/test/unit/should_generate_interfaces_with_inheritance/expected.kt +++ b/test/unit/should_generate_interfaces_with_inheritance/expected.kt @@ -9,6 +9,7 @@ interface InterfaceWithInheritance { } @GraphQLDescription("A description for MyInterfaceImplementation") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyInterfaceImplementation( override val field: String? = null, override val field2: String @@ -22,6 +23,7 @@ interface InheritedInterface2 { val field2: String } +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyMergedInterfaceImplementation( override val field: String? = null, override val field2: String diff --git a/test/unit/should_generate_list_types_properly/expected.kt b/test/unit/should_generate_list_types_properly/expected.kt index 0211f11..9a51690 100644 --- a/test/unit/should_generate_list_types_properly/expected.kt +++ b/test/unit/should_generate_list_types_properly/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyListType( val field: List = emptyList(), val field2: List = emptyList(), diff --git a/test/unit/should_generate_multi_union_types_properly/expected.kt b/test/unit/should_generate_multi_union_types_properly/expected.kt index f5bd4a8..438919a 100644 --- a/test/unit/should_generate_multi_union_types_properly/expected.kt +++ b/test/unit/should_generate_multi_union_types_properly/expected.kt @@ -2,10 +2,12 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyType3( val field: String? = null ) : MyUnion1, MyUnion2 +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyType4( val field: String? = null ) : MyUnion1, MyUnion2 @@ -14,6 +16,7 @@ interface MyUnion1 interface MyUnion2 +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyMultiUnionType( val field: MyUnion1? = null, val field2: MyUnion2? = null diff --git a/test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt b/test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt index aa7142b..4a32299 100644 --- a/test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt +++ b/test/unit/should_generate_non_nullable_union_list_types_properly/expected.kt @@ -3,10 +3,12 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for MyType1") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForNonNullableUnionList1( val field: String? = null ) : UnionForNonNullableList +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForNonNullableUnionList2( val field: String? = null ) : UnionForNonNullableList @@ -14,6 +16,7 @@ data class TypeForNonNullableUnionList2( @GraphQLDescription("A description for UnionForNonNullableList") interface UnionForNonNullableList +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyNonNullableUnionListType( val field: List = emptyList(), val field2: List = emptyList() diff --git a/test/unit/should_generate_type_with_interface_field_type/expected.kt b/test/unit/should_generate_type_with_interface_field_type/expected.kt index a9b8498..bf2df51 100644 --- a/test/unit/should_generate_type_with_interface_field_type/expected.kt +++ b/test/unit/should_generate_type_with_interface_field_type/expected.kt @@ -8,6 +8,7 @@ interface MyInterface { val field2: String } +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyInterfaceFieldType( val field: MyInterface? = null, val field2: MyInterface diff --git a/test/unit/should_generate_union_list_types_properly/expected.kt b/test/unit/should_generate_union_list_types_properly/expected.kt index d35f292..da3c097 100644 --- a/test/unit/should_generate_union_list_types_properly/expected.kt +++ b/test/unit/should_generate_union_list_types_properly/expected.kt @@ -3,10 +3,12 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for TypeForGeneratingUnionListTypes1") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForGeneratingUnionListTypes1( val field: String? = null ) : UnionForGeneratingUnionListTypes +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForGeneratingUnionListTypes2( val field: String? = null ) : UnionForGeneratingUnionListTypes @@ -14,6 +16,7 @@ data class TypeForGeneratingUnionListTypes2( @GraphQLDescription("A description for UnionForGeneratingUnionListTypes") interface UnionForGeneratingUnionListTypes +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyUnionListType( @GraphQLDescription("A description for field") val field: List? = null, diff --git a/test/unit/should_generate_union_types_properly/expected.kt b/test/unit/should_generate_union_types_properly/expected.kt index a06a063..6078ae7 100644 --- a/test/unit/should_generate_union_types_properly/expected.kt +++ b/test/unit/should_generate_union_types_properly/expected.kt @@ -3,10 +3,12 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for MyType1") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForGeneratingUnionTypesProperly1( val field: String? = null ) : UnionForGeneratingUnionsProperly +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForGeneratingUnionTypesProperly2( val field: String? = null ) : UnionForGeneratingUnionsProperly @@ -14,6 +16,7 @@ data class TypeForGeneratingUnionTypesProperly2( @GraphQLDescription("A trimmed description for UnionForGeneratingUnionsProperly") interface UnionForGeneratingUnionsProperly +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyUnionType( @GraphQLDescription("A description for field") val field: UnionForGeneratingUnionsProperly? = null, diff --git a/test/unit/should_honor_dependentTypesInScope_config/expected.kt b/test/unit/should_honor_dependentTypesInScope_config/expected.kt index e7ea92e..e247581 100644 --- a/test/unit/should_honor_dependentTypesInScope_config/expected.kt +++ b/test/unit/should_honor_dependentTypesInScope_config/expected.kt @@ -3,11 +3,13 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* import should_honor_dependentTypesInScope_config.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyTypeInOnlyTypes( val field: TypeInScope, val field2: TypeOutOfScope ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeInScope( val field: String? = null, val unionInScopeField: UnionInScope? = null, @@ -17,6 +19,7 @@ data class TypeInScope( interface UnionInScope +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class Type1( val field: String? = null ) : UnionInScope, ExternalUnionAsInterface diff --git a/test/unit/should_honor_directiveReplacements_config/expected.kt b/test/unit/should_honor_directiveReplacements_config/expected.kt index b353397..8292a5c 100644 --- a/test/unit/should_honor_directiveReplacements_config/expected.kt +++ b/test/unit/should_honor_directiveReplacements_config/expected.kt @@ -7,6 +7,7 @@ import should_honor_directiveReplacements_config.* @SomeAnnotation1 @SomeAnnotation2 @SomeAnnotationWithArgs(arg1 = "arg1", arg2 = 0) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringDirectiveReplacements( val field: String? = null ) : MyDirectiveUnion diff --git a/test/unit/should_honor_directiveReplacements_config_with_multiple_directives/expected.kt b/test/unit/should_honor_directiveReplacements_config_with_multiple_directives/expected.kt index 2f115f8..01eaa19 100644 --- a/test/unit/should_honor_directiveReplacements_config_with_multiple_directives/expected.kt +++ b/test/unit/should_honor_directiveReplacements_config_with_multiple_directives/expected.kt @@ -6,6 +6,7 @@ import should_honor_directiveReplacements_config.* @GraphQLDescription("A description for MyDirectiveType") @SomeAnnotation1 @SomeAnnotation2 +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringDirectiveReplacementsMultipleDirectives( val field: String? = null ) diff --git a/test/unit/should_honor_directiveReplacements_definitionType_config/expected.kt b/test/unit/should_honor_directiveReplacements_definitionType_config/expected.kt index 77c0abd..6529c6b 100644 --- a/test/unit/should_honor_directiveReplacements_definitionType_config/expected.kt +++ b/test/unit/should_honor_directiveReplacements_definitionType_config/expected.kt @@ -5,12 +5,14 @@ import should_honor_directiveReplacements_config.* @SomeAnnotation1 @CommonAnnotation +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringDirectiveReplacementsDefinitionType( val field: String? = null ) @SomeAnnotation2 @CommonAnnotation +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyDirectiveTypeInput( val field: String? = null ) diff --git a/test/unit/should_honor_includeDependentTypes_config/expected.kt b/test/unit/should_honor_includeDependentTypes_config/expected.kt index 3224d78..a90f0f8 100644 --- a/test/unit/should_honor_includeDependentTypes_config/expected.kt +++ b/test/unit/should_honor_includeDependentTypes_config/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringIncludeDependentTypesConfig( val field: MyNestedType? = null ) diff --git a/test/unit/should_honor_onlyTypes_config/expected.kt b/test/unit/should_honor_onlyTypes_config/expected.kt index 6997a70..f3b955d 100644 --- a/test/unit/should_honor_onlyTypes_config/expected.kt +++ b/test/unit/should_honor_onlyTypes_config/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringOnlyTypesConfig( val field1: String? = null, @GraphQLDescription("A description for field2") diff --git a/test/unit/should_honor_packageName_config/expected.kt b/test/unit/should_honor_packageName_config/expected.kt index 1be7ccb..62b3684 100644 --- a/test/unit/should_honor_packageName_config/expected.kt +++ b/test/unit/should_honor_packageName_config/expected.kt @@ -2,6 +2,7 @@ package com.some.custom.name import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeHonoringPackageNameConfig( val field: String? = null ) diff --git a/test/unit/should_honor_resolverTypes_config/expected.kt b/test/unit/should_honor_resolverTypes_config/expected.kt index 71216a2..efa09f7 100644 --- a/test/unit/should_honor_resolverTypes_config/expected.kt +++ b/test/unit/should_honor_resolverTypes_config/expected.kt @@ -30,6 +30,7 @@ interface MyIncludedResolverTypeCompletableFuture { fun nonNullableField(): java.util.concurrent.CompletableFuture } +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyExcludedResolverType( val nullableField: String? = null, val nonNullableField: String diff --git a/test/unit/should_honor_union_generation_config/expected.kt b/test/unit/should_honor_union_generation_config/expected.kt index faab3b8..e8d5b95 100644 --- a/test/unit/should_honor_union_generation_config/expected.kt +++ b/test/unit/should_honor_union_generation_config/expected.kt @@ -3,10 +3,12 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* @GraphQLDescription("A description for TypeForHonoringUnionGenerationConfig1") +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForHonoringUnionGenerationConfig1( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class TypeForHonoringUnionGenerationConfig2( val field: String? = null ) @@ -18,6 +20,7 @@ data class TypeForHonoringUnionGenerationConfig2( ) annotation class UnionAsAnnotation +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class UnionForHonoringUnionGenerationConfig( @UnionAsAnnotation @GraphQLDescription("A description for field") diff --git a/test/unit/should_include_dependent_types_in_onlyTypes_config/expected.kt b/test/unit/should_include_dependent_types_in_onlyTypes_config/expected.kt index 1895564..4b9bc86 100644 --- a/test/unit/should_include_dependent_types_in_onlyTypes_config/expected.kt +++ b/test/unit/should_include_dependent_types_in_onlyTypes_config/expected.kt @@ -2,6 +2,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyType( val typeField: MyNestedType, val typeListField: List = emptyList(), @@ -12,14 +13,17 @@ data class MyType( val interfaceImplementationField: MyImplementedInterface ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyNestedType( val field: String? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class ListType( val field: List? = null ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class NestedListType( val field: String? = null ) @@ -35,14 +39,17 @@ enum class MyEnum { interface MyUnion +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyType1( val field: String? = null ) : MyUnion +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyType2( val field: String? = null ) : MyUnion +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class UnionImplementation( val field: String? = null ) : MyUnion2 @@ -55,24 +62,29 @@ interface MyInterfaceToImplement { val field: String? } +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyImplementedInterface( override val field: String? = null ) : MyInterfaceToImplement +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyInput( val field: MyNestedInput ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) data class MyNestedInput( val field: String? = null ) interface MyStandaloneUnion +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class StandaloneUnionType( val field: StandaloneNestedType? = null ) : MyStandaloneUnion +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class StandaloneNestedType( val field: String? = null ) diff --git a/test/unit/should_replace_federation_directives/expected.kt b/test/unit/should_replace_federation_directives/expected.kt index 7e94aa0..fb52b50 100644 --- a/test/unit/should_replace_federation_directives/expected.kt +++ b/test/unit/should_replace_federation_directives/expected.kt @@ -4,6 +4,7 @@ import com.expediagroup.graphql.generator.annotations.* @com.expediagroup.graphql.generator.federation.directives.ExtendsDirective @com.expediagroup.graphql.generator.federation.directives.KeyDirective(com.expediagroup.graphql.generator.federation.directives.FieldSet("some field")) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class FederatedType( @com.expediagroup.graphql.generator.federation.directives.ExternalDirective val field: String diff --git a/test/unit/should_support_custom_scalars/expected.kt b/test/unit/should_support_custom_scalars/expected.kt index c290325..4543a7a 100644 --- a/test/unit/should_support_custom_scalars/expected.kt +++ b/test/unit/should_support_custom_scalars/expected.kt @@ -2,12 +2,14 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyScalarType( val idField: com.expediagroup.graphql.generator.scalars.ID? = null, val field: java.net.URL? = null, val field2: java.net.URL ) +@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) data class MyCustomScalarType( val field: String? = null, val field2: String