From 0b434400b6a78def37de53468ddbca46a0b0c061 Mon Sep 17 00:00:00 2001 From: lesleydreyer <38596053+lesleydreyer@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:36:08 -0700 Subject: [PATCH] fix: check directive isNode on merge if inherited from obj (#5973) --- .../merge/src/typedefs-mergers/merge-nodes.ts | 9 ++++++++ packages/merge/tests/merge-nodes.spec.ts | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/merge/src/typedefs-mergers/merge-nodes.ts b/packages/merge/src/typedefs-mergers/merge-nodes.ts index 3cc11ea0914..56eab73b03f 100644 --- a/packages/merge/src/typedefs-mergers/merge-nodes.ts +++ b/packages/merge/src/typedefs-mergers/merge-nodes.ts @@ -5,6 +5,7 @@ import { SchemaDefinitionNode, SchemaExtensionNode, } from 'graphql'; +import { isNode } from 'graphql/language/ast.js'; import { collectComment, NamedDefinitionNode } from '@graphql-tools/utils'; import { mergeDirective } from './directives.js'; import { mergeEnum } from './enum.js'; @@ -104,6 +105,14 @@ export function mergeGraphQLNodes( ); break; case Kind.DIRECTIVE_DEFINITION: + if (mergedResultMap[name]) { + const isInheritedFromPrototype = name in {}; + if (isInheritedFromPrototype) { + if (!isNode(mergedResultMap[name])) { + mergedResultMap[name] = undefined as any; + } + } + } mergedResultMap[name] = mergeDirective(nodeDefinition, mergedResultMap[name] as any); break; } diff --git a/packages/merge/tests/merge-nodes.spec.ts b/packages/merge/tests/merge-nodes.spec.ts index 3d6ff9a3017..f735dc136ae 100644 --- a/packages/merge/tests/merge-nodes.spec.ts +++ b/packages/merge/tests/merge-nodes.spec.ts @@ -280,6 +280,27 @@ describe('Merge Nodes', () => { 'Unable to merge GraphQL type "A": Field "f1" already defined with a different type. Declared as "String", but you tried to override with "Int"', ); }); + + it('Should merge GraphQL Types and merge directives (when the directive is inherited from the Object prototype)', () => { + const type1 = parse(/* GraphQL */ ` + type A @toString { + f1: String + } + `); + const type2 = parse(/* GraphQL */ ` + type A @test2 { + f2: Int + } + `); + const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); + const type = merged['A']; + assertObjectTypeDefinitionNode(type); + assertSome(type.directives); + + expect(type.directives.length).toBe(2); + expect(type.directives[0].name.value).toBe('toString'); + expect(type.directives[1].name.value).toBe('test2'); + }); }); describe('enum', () => {