From f521ece8ec99e3a374e6b48fb000d21bf565370a Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 10:13:49 +0100 Subject: [PATCH 1/6] Fix #7938 --- .../other/visitor-plugin-common/src/base-types-visitor.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index c991d3351ca..600df4f6d82 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -624,9 +624,10 @@ export class BaseTypesVisitor< } getInputObjectOneOfDeclarationBlock(node: InputObjectTypeDefinitionNode): DeclarationBlock { + const declarationKind = 'type'; return new DeclarationBlock(this._declarationBlockConfig) .export() - .asKind(this._parsedConfig.declarationKind.input) + .asKind(declarationKind) .withName(this.convertName(node)) .withComment(node.description as any as string) .withContent(`\n` + node.fields.join('\n |')); From fa9b379df84717bd51994b56daad5d41b858a001 Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 10:14:44 +0100 Subject: [PATCH 2/6] add comment --- .../other/visitor-plugin-common/src/base-types-visitor.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index 600df4f6d82..d9141f8e659 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -624,6 +624,8 @@ export class BaseTypesVisitor< } getInputObjectOneOfDeclarationBlock(node: InputObjectTypeDefinitionNode): DeclarationBlock { + // Since a oneOf declaration is always a union + // we have to force a type declaration kind. const declarationKind = 'type'; return new DeclarationBlock(this._declarationBlockConfig) .export() From cb78404b383287f07f88f06f5687e182e533582d Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 10:23:51 +0100 Subject: [PATCH 3/6] add test case --- .../typescript/tests/typescript.spec.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/plugins/typescript/typescript/tests/typescript.spec.ts b/packages/plugins/typescript/typescript/tests/typescript.spec.ts index e7360b70daf..b56fee9b92b 100644 --- a/packages/plugins/typescript/typescript/tests/typescript.spec.ts +++ b/packages/plugins/typescript/typescript/tests/typescript.spec.ts @@ -2635,6 +2635,29 @@ describe('TypeScript', () => { `); }); + it('forces type declaration kind', async () => { + const schema = buildSchema( + /* GraphQL */ ` + input Input @oneOf { + int: Int + boolean: Boolean + } + + type Query { + foo(input: Input!): Boolean! + } + `.concat(oneOfDirectiveDefinition) + ); + + const result = await plugin(schema, [], { declarationKind: 'interface' }, { outputFile: '' }); + + expect(result.content).toBeSimilarStringTo(` + export type Input = + { int: Scalars['Int']; boolean?: never; } + | { int?: never; boolean: Scalars['Boolean']; }; + `); + }); + it('raises exception for type with non-optional fields', async () => { const schema = buildSchema( /* GraphQL */ ` From 159e96415a9c8e0b36ad3780afd392f2a5b5fbf3 Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 10:27:39 +0100 Subject: [PATCH 4/6] refine comment --- .../other/visitor-plugin-common/src/base-types-visitor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index d9141f8e659..ca753fcad2b 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -624,8 +624,8 @@ export class BaseTypesVisitor< } getInputObjectOneOfDeclarationBlock(node: InputObjectTypeDefinitionNode): DeclarationBlock { - // Since a oneOf declaration is always a union - // we have to force a type declaration kind. + // Since oneOf declarations (almost) always result in a + // union, we have to force a declaration kind of `type`. const declarationKind = 'type'; return new DeclarationBlock(this._declarationBlockConfig) .export() From 4120eb0867e9d8868112b65452f7c4e15ab9b437 Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 10:35:49 +0100 Subject: [PATCH 5/6] respect declaration kind with single field --- .../src/base-types-visitor.ts | 6 ++--- .../typescript/tests/typescript.spec.ts | 24 ++++++++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts index ca753fcad2b..624ceab739f 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-types-visitor.ts @@ -624,9 +624,9 @@ export class BaseTypesVisitor< } getInputObjectOneOfDeclarationBlock(node: InputObjectTypeDefinitionNode): DeclarationBlock { - // Since oneOf declarations (almost) always result in a - // union, we have to force a declaration kind of `type`. - const declarationKind = 'type'; + // As multiple fields always result in a union, we have + // to force a declaration kind of `type` in this case + const declarationKind = node.fields.length === 1 ? this._parsedConfig.declarationKind.input : 'type'; return new DeclarationBlock(this._declarationBlockConfig) .export() .asKind(declarationKind) diff --git a/packages/plugins/typescript/typescript/tests/typescript.spec.ts b/packages/plugins/typescript/typescript/tests/typescript.spec.ts index b56fee9b92b..eb71b656c52 100644 --- a/packages/plugins/typescript/typescript/tests/typescript.spec.ts +++ b/packages/plugins/typescript/typescript/tests/typescript.spec.ts @@ -2635,7 +2635,29 @@ describe('TypeScript', () => { `); }); - it('forces type declaration kind', async () => { + it('respects configured declaration kind with single field', async () => { + const schema = buildSchema( + /* GraphQL */ ` + input Input @oneOf { + int: Int + } + + type Query { + foo(input: Input!): Boolean! + } + `.concat(oneOfDirectiveDefinition) + ); + + const result = await plugin(schema, [], { declarationKind: 'interface' }, { outputFile: '' }); + + expect(result.content).toBeSimilarStringTo(` + export interface Input { + int: Scalars['Int']; + } + `); + }); + + it('forces declaration kind of type with multiple fields', async () => { const schema = buildSchema( /* GraphQL */ ` input Input @oneOf { From 60270c4cad4d6d6ed04ee1c5fc192f84131c889b Mon Sep 17 00:00:00 2001 From: Levin Rickert Date: Tue, 8 Nov 2022 13:49:07 +0100 Subject: [PATCH 6/6] add changeset --- .changeset/afraid-maps-complain.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/afraid-maps-complain.md diff --git a/.changeset/afraid-maps-complain.md b/.changeset/afraid-maps-complain.md new file mode 100644 index 00000000000..b418393a505 --- /dev/null +++ b/.changeset/afraid-maps-complain.md @@ -0,0 +1,6 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +'@graphql-codegen/typescript': patch +--- + +Fix incompatibility between `@oneOf` input types and declaration kind other than `type`