@@ -38,7 +38,13 @@ import {
3838 type SchemaData ,
3939} from './types' ;
4040import { type MutableDefinitionNode , type MutableFieldNode , type MutableInputValueNode } from './ast' ;
41- import { type ObjectTypeNode , setToNameNodeArray , stringToNameNode } from '../ast/utils' ;
41+ import {
42+ type InterfaceTypeNode ,
43+ type ObjectTypeNode ,
44+ type ParentTypeNode ,
45+ setToNameNodeArray ,
46+ stringToNameNode ,
47+ } from '../ast/utils' ;
4248import {
4349 incompatibleInputValueDefaultValuesError ,
4450 invalidRepeatedFederatedDirectiveErrorMessage ,
@@ -58,6 +64,7 @@ import {
5864 INPUT_FIELD ,
5965 INPUT_NODE_KINDS ,
6066 INT_SCALAR ,
67+ INTERFACE_NODE_KINDS ,
6168 MUTATION ,
6269 OUTPUT_NODE_KINDS ,
6370 PERSISTED_CLIENT_DIRECTIVES ,
@@ -80,6 +87,7 @@ import {
8087import { type InputNodeKind , type InvalidRequiredInputValueData , type OutputNodeKind } from '../utils/types' ;
8188import { getDescriptionFromString } from '../v1/federation/utils' ;
8289import { type DirectiveName , type FieldName , type SubgraphName , type TypeName } from '../types/types' ;
90+ import { type IsTypeValidImplementationParams } from './params' ;
8391
8492export function newPersistedDirectivesData ( ) : PersistedDirectivesData {
8593 return {
@@ -620,19 +628,30 @@ export enum MergeMethod {
620628 CONSISTENT ,
621629}
622630
623- export function isTypeValidImplementation (
624- originalType : TypeNode ,
625- implementationType : TypeNode ,
626- concreteTypeNamesByAbstractTypeName : Map < TypeName , Set < TypeName > > ,
627- ) : boolean {
631+ export function isTypeValidImplementation ( {
632+ concreteTypeNamesByAbstractTypeName,
633+ implementationType,
634+ interfaceImplementationTypeNamesByInterfaceTypeName,
635+ originalType,
636+ } : IsTypeValidImplementationParams ) : boolean {
628637 if ( originalType . kind === Kind . NON_NULL_TYPE ) {
629638 if ( implementationType . kind !== Kind . NON_NULL_TYPE ) {
630639 return false ;
631640 }
632- return isTypeValidImplementation ( originalType . type , implementationType . type , concreteTypeNamesByAbstractTypeName ) ;
641+ return isTypeValidImplementation ( {
642+ concreteTypeNamesByAbstractTypeName,
643+ implementationType : implementationType . type ,
644+ interfaceImplementationTypeNamesByInterfaceTypeName,
645+ originalType : originalType . type ,
646+ } ) ;
633647 }
634648 if ( implementationType . kind === Kind . NON_NULL_TYPE ) {
635- return isTypeValidImplementation ( originalType , implementationType . type , concreteTypeNamesByAbstractTypeName ) ;
649+ return isTypeValidImplementation ( {
650+ concreteTypeNamesByAbstractTypeName,
651+ implementationType : implementationType . type ,
652+ interfaceImplementationTypeNamesByInterfaceTypeName,
653+ originalType,
654+ } ) ;
636655 }
637656 switch ( originalType . kind ) {
638657 case Kind . NAMED_TYPE :
@@ -642,20 +661,19 @@ export function isTypeValidImplementation(
642661 if ( originalTypeName === implementationTypeName ) {
643662 return true ;
644663 }
664+ const abstractTypes = interfaceImplementationTypeNamesByInterfaceTypeName . get ( originalTypeName ) ;
645665 const concreteTypes = concreteTypeNamesByAbstractTypeName . get ( originalTypeName ) ;
646- if ( ! concreteTypes ) {
647- return false ;
648- }
649- return concreteTypes . has ( implementationTypeName ) ;
666+ return ! ! ( concreteTypes ?. has ( implementationTypeName ) || abstractTypes ?. has ( implementationTypeName ) ) ;
650667 }
651668 return false ;
652669 default :
653670 if ( implementationType . kind === Kind . LIST_TYPE ) {
654- return isTypeValidImplementation (
655- originalType . type ,
656- implementationType . type ,
671+ return isTypeValidImplementation ( {
657672 concreteTypeNamesByAbstractTypeName,
658- ) ;
673+ implementationType : implementationType . type ,
674+ interfaceImplementationTypeNamesByInterfaceTypeName,
675+ originalType : originalType . type ,
676+ } ) ;
659677 }
660678 return false ;
661679 }
@@ -775,3 +793,7 @@ export function isInputNodeKind(kind: Kind): kind is InputNodeKind {
775793export function isOutputNodeKind ( kind : Kind ) : kind is OutputNodeKind {
776794 return OUTPUT_NODE_KINDS . has ( kind ) ;
777795}
796+
797+ export function isInterfaceNode ( node : ParentTypeNode ) : node is InterfaceTypeNode {
798+ return INTERFACE_NODE_KINDS . has ( node . kind ) ;
799+ }
0 commit comments