@@ -230,7 +230,7 @@ import {
230230 InvalidRequiredInputValueData ,
231231} from '../../utils/types' ;
232232import { FederateSubgraphsContractV1Params , FederateSubgraphsWithContractsV1Params , FederationParams } from './types' ;
233- import { ContractName , FieldCoords , TypeName } from '../../types/types' ;
233+ import { ContractName , FieldCoords , SubgraphName , TypeName } from '../../types/types' ;
234234
235235export class FederationFactory {
236236 authorizationDataByParentTypeName : Map < string , AuthorizationData > ;
@@ -1617,7 +1617,7 @@ export class FederationFactory {
16171617 if ( ! isObjectDefinitionData ( concreteTypeData ) ) {
16181618 continue ;
16191619 }
1620- // The subgraph locations of the interface object must be added to the concrete types that implement it
1620+ // The subgraph locations of the Interface Object must be added to the concrete types that implement it
16211621 const entityData = getOrThrowError ( this . entityDataByTypeName , concreteTypeName , 'entityDataByTypeName' ) ;
16221622 entityData . subgraphNames . add ( subgraphName ) ;
16231623 const configurationData = configurationDataByTypeName . get ( concreteTypeName ) ;
@@ -1673,10 +1673,16 @@ export class FederationFactory {
16731673 }
16741674 }
16751675 const existingFieldData = concreteTypeData . fieldDataByName . get ( fieldName ) ;
1676+ // @shareable and @external need to be propagated (e.g., to satisfy interfaces)
16761677 if ( existingFieldData ) {
16771678 const isShareable = fieldData . isShareableBySubgraphName . get ( subgraphName ) ?? false ;
16781679 existingFieldData . isShareableBySubgraphName . set ( subgraphName , isShareable ) ;
16791680 existingFieldData . subgraphNames . add ( subgraphName ) ;
1681+ const externalData = fieldData . externalFieldDataBySubgraphName . get ( subgraphName ) ;
1682+ if ( ! externalData ) {
1683+ continue ;
1684+ }
1685+ existingFieldData . externalFieldDataBySubgraphName . set ( subgraphName , { ...externalData } ) ;
16801686 continue ;
16811687 }
16821688 const isInaccessible =
@@ -3061,18 +3067,31 @@ function initializeFederationFactory({
30613067 }
30623068 }
30633069 const entityInterfaceErrors = new Array < Error > ( ) ;
3070+ const definedConcreteTypeNamesBySubgraphName = new Map < SubgraphName , Set < TypeName > > ( ) ;
30643071 for ( const [ typeName , entityInterfaceData ] of entityInterfaceFederationDataByTypeName ) {
30653072 const implementations = entityInterfaceData . concreteTypeNames . size ;
30663073 for ( const [ subgraphName , subgraphData ] of entityInterfaceData . subgraphDataByTypeName ) {
3074+ const definedConcreteTypeNames = getValueOrDefault (
3075+ definedConcreteTypeNamesBySubgraphName ,
3076+ subgraphName ,
3077+ ( ) => new Set < TypeName > ( ) ,
3078+ ) ;
3079+ addIterableValuesToSet ( subgraphData . concreteTypeNames , definedConcreteTypeNames ) ;
30673080 if ( ! subgraphData . isInterfaceObject ) {
30683081 if ( subgraphData . resolvable && subgraphData . concreteTypeNames . size !== implementations ) {
3069- getValueOrDefault ( invalidEntityInterfacesByTypeName , typeName , ( ) => [ ] ) . push ( {
3082+ getValueOrDefault (
3083+ invalidEntityInterfacesByTypeName ,
3084+ typeName ,
3085+ ( ) => new Array < InvalidEntityInterface > ( ) ,
3086+ ) . push ( {
30703087 subgraphName,
3071- concreteTypeNames : subgraphData . concreteTypeNames ,
3088+ definedConcreteTypeNames : new Set < TypeName > ( subgraphData . concreteTypeNames ) ,
3089+ requiredConcreteTypeNames : new Set < TypeName > ( entityInterfaceData . concreteTypeNames ) ,
30723090 } ) ;
30733091 }
30743092 continue ;
30753093 }
3094+ addIterableValuesToSet ( entityInterfaceData . concreteTypeNames , definedConcreteTypeNames ) ;
30763095 const { parentDefinitionDataByTypeName } = getOrThrowError (
30773096 result . internalSubgraphBySubgraphName ,
30783097 subgraphName ,
@@ -3091,6 +3110,26 @@ function initializeFederationFactory({
30913110 }
30923111 }
30933112 }
3113+ for ( const [ typeName , invalidInterfaces ] of invalidEntityInterfacesByTypeName ) {
3114+ const checkedInvalidInterfaces = new Array < InvalidEntityInterface > ( ) ;
3115+ for ( const invalidInterface of invalidInterfaces ) {
3116+ const validTypeNames = definedConcreteTypeNamesBySubgraphName . get ( invalidInterface . subgraphName ) ;
3117+ if ( ! validTypeNames ) {
3118+ checkedInvalidInterfaces . push ( invalidInterface ) ;
3119+ continue ;
3120+ }
3121+ const definedTypeNames = invalidInterface . requiredConcreteTypeNames . intersection ( validTypeNames ) ;
3122+ if ( invalidInterface . requiredConcreteTypeNames . size !== definedTypeNames . size ) {
3123+ invalidInterface . definedConcreteTypeNames = definedTypeNames ;
3124+ checkedInvalidInterfaces . push ( invalidInterface ) ;
3125+ }
3126+ }
3127+ if ( checkedInvalidInterfaces . length > 0 ) {
3128+ invalidEntityInterfacesByTypeName . set ( typeName , checkedInvalidInterfaces ) ;
3129+ continue ;
3130+ }
3131+ invalidEntityInterfacesByTypeName . delete ( typeName ) ;
3132+ }
30943133 if ( invalidEntityInterfacesByTypeName . size > 0 ) {
30953134 entityInterfaceErrors . push (
30963135 undefinedEntityInterfaceImplementationsError (
0 commit comments