@@ -6,9 +6,11 @@ import {
6
6
DirectiveDefinitionNode ,
7
7
EnumTypeDefinitionNode ,
8
8
FieldDefinitionNode ,
9
+ GraphQLInterfaceType ,
9
10
GraphQLNamedType ,
10
11
GraphQLObjectType ,
11
12
GraphQLSchema ,
13
+ GraphQLUnionType ,
12
14
InputValueDefinitionNode ,
13
15
InterfaceTypeDefinitionNode ,
14
16
isEnumType ,
@@ -33,8 +35,6 @@ import {
33
35
ConvertOptions ,
34
36
DeclarationKind ,
35
37
EnumValuesMap ,
36
- type NormalizedGenerateInternalResolversIfNeededConfig ,
37
- type GenerateInternalResolversIfNeededConfig ,
38
38
NormalizedAvoidOptionalsConfig ,
39
39
NormalizedScalarsMap ,
40
40
ParsedEnumValuesMap ,
@@ -77,7 +77,6 @@ export interface ParsedResolversConfig extends ParsedConfig {
77
77
resolverTypeSuffix : string ;
78
78
allResolversTypeName : string ;
79
79
internalResolversPrefix : string ;
80
- generateInternalResolversIfNeeded : NormalizedGenerateInternalResolversIfNeededConfig ;
81
80
directiveResolverMappings : Record < string , string > ;
82
81
resolversNonOptionalTypename : ResolversNonOptionalTypenameConfig ;
83
82
avoidCheckingAbstractTypesRecursively : boolean ;
@@ -584,15 +583,6 @@ export interface RawResolversConfig extends RawConfig {
584
583
* If you are using `mercurius-js`, please set this field to empty string for better compatibility.
585
584
*/
586
585
internalResolversPrefix ?: string ;
587
- /**
588
- * @type object
589
- * @default {}
590
- * @description If relevant internal resolvers are set to `true`, the resolver type will only be generated if the right conditions are met.
591
- * Enabling this allows a more correct type generation for the resolvers.
592
- * For example:
593
- * - `__isTypeOf` is generated for implementing types and union members
594
- */
595
- generateInternalResolversIfNeeded ?: GenerateInternalResolversIfNeededConfig ;
596
586
/**
597
587
* @description Makes `__typename` of resolver mappings non-optional without affecting the base types.
598
588
* @default false
@@ -671,6 +661,31 @@ export class BaseResolversVisitor<
671
661
baseGeneratedTypename ?: string ;
672
662
} ;
673
663
} = { } ;
664
+ protected _parsedSchemaMeta : {
665
+ types : {
666
+ interface : Record <
667
+ string ,
668
+ {
669
+ type : GraphQLInterfaceType ;
670
+ implementingTypes : Record < string , GraphQLObjectType > ;
671
+ }
672
+ > ;
673
+ union : Record <
674
+ string ,
675
+ {
676
+ type : GraphQLUnionType ;
677
+ unionMembers : Record < string , GraphQLObjectType > ;
678
+ }
679
+ > ;
680
+ } ;
681
+ typesWithIsTypeOf : Record < string , true > ;
682
+ } = {
683
+ types : {
684
+ interface : { } ,
685
+ union : { } ,
686
+ } ,
687
+ typesWithIsTypeOf : { } ,
688
+ } ;
674
689
protected _collectedDirectiveResolvers : { [ key : string ] : string } = { } ;
675
690
protected _variablesTransformer : OperationVariablesToObject ;
676
691
protected _usedMappers : { [ key : string ] : boolean } = { } ;
@@ -679,7 +694,6 @@ export class BaseResolversVisitor<
679
694
protected _hasReferencedResolversUnionTypes = false ;
680
695
protected _hasReferencedResolversInterfaceTypes = false ;
681
696
protected _resolversUnionTypes : Record < string , string > = { } ;
682
- protected _resolversUnionParentTypes : Record < string , string > = { } ;
683
697
protected _resolversInterfaceTypes : Record < string , string > = { } ;
684
698
protected _rootTypeNames = new Set < string > ( ) ;
685
699
protected _globalDeclarations = new Set < string > ( ) ;
@@ -745,6 +759,11 @@ export class BaseResolversVisitor<
745
759
this . config . namespacedImportName
746
760
) ;
747
761
762
+ // 1. Parse schema meta at the start once,
763
+ // so we can use it in subsequent generate functions
764
+ this . parseSchemaMeta ( ) ;
765
+
766
+ // 2. Generate types for resolvers
748
767
this . _resolversTypes = this . createResolversFields ( {
749
768
applyWrapper : type => this . applyResolverTypeWrapper ( type ) ,
750
769
clearWrapper : type => this . clearResolverTypeWrapper ( type ) ,
@@ -996,22 +1015,20 @@ export class BaseResolversVisitor<
996
1015
return { } ;
997
1016
}
998
1017
999
- const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1000
- const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1001
-
1002
- const unionTypes = typeNames . reduce < Record < string , string > > ( ( res , typeName ) => {
1003
- const schemaType = allSchemaTypes [ typeName ] ;
1004
-
1005
- if ( isUnionType ( schemaType ) ) {
1006
- const { unionMember, excludeTypes } = this . config . resolversNonOptionalTypename ;
1007
- res [ typeName ] = this . getAbstractMembersType ( {
1008
- typeName,
1009
- memberTypes : schemaType . getTypes ( ) ,
1010
- isTypenameNonOptional : unionMember && ! excludeTypes ?. includes ( typeName ) ,
1011
- } ) ;
1012
- }
1013
- return res ;
1014
- } , { } ) ;
1018
+ const unionTypes = Object . entries ( this . _parsedSchemaMeta . types . union ) . reduce < Record < string , string > > (
1019
+ ( res , [ typeName , { type : schemaType , unionMembers } ] ) => {
1020
+ if ( isUnionType ( schemaType ) ) {
1021
+ const { unionMember, excludeTypes } = this . config . resolversNonOptionalTypename ;
1022
+ res [ typeName ] = this . getAbstractMembersType ( {
1023
+ typeName,
1024
+ memberTypes : Object . values ( unionMembers ) ,
1025
+ isTypenameNonOptional : unionMember && ! excludeTypes ?. includes ( typeName ) ,
1026
+ } ) ;
1027
+ }
1028
+ return res ;
1029
+ } ,
1030
+ { }
1031
+ ) ;
1015
1032
1016
1033
return unionTypes ;
1017
1034
}
@@ -1021,37 +1038,22 @@ export class BaseResolversVisitor<
1021
1038
return { } ;
1022
1039
}
1023
1040
1024
- const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1025
- const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1026
-
1027
- const interfaceTypes = typeNames . reduce < Record < string , string > > ( ( res , typeName ) => {
1028
- const schemaType = allSchemaTypes [ typeName ] ;
1029
-
1030
- if ( isInterfaceType ( schemaType ) ) {
1031
- const allTypesMap = this . _schema . getTypeMap ( ) ;
1032
- const implementingTypes : GraphQLObjectType [ ] = [ ] ;
1033
-
1034
- for ( const graphqlType of Object . values ( allTypesMap ) ) {
1035
- if ( graphqlType instanceof GraphQLObjectType ) {
1036
- const allInterfaces = graphqlType . getInterfaces ( ) ;
1041
+ const interfaceTypes = Object . entries ( this . _parsedSchemaMeta . types . interface ) . reduce < Record < string , string > > (
1042
+ ( res , [ typeName , { type : schemaType , implementingTypes } ] ) => {
1043
+ if ( isInterfaceType ( schemaType ) ) {
1044
+ const { interfaceImplementingType, excludeTypes } = this . config . resolversNonOptionalTypename ;
1037
1045
1038
- if ( allInterfaces . some ( int => int . name === schemaType . name ) ) {
1039
- implementingTypes . push ( graphqlType ) ;
1040
- }
1041
- }
1046
+ res [ typeName ] = this . getAbstractMembersType ( {
1047
+ typeName,
1048
+ memberTypes : Object . values ( implementingTypes ) ,
1049
+ isTypenameNonOptional : interfaceImplementingType && ! excludeTypes ?. includes ( typeName ) ,
1050
+ } ) ;
1042
1051
}
1043
1052
1044
- const { interfaceImplementingType, excludeTypes } = this . config . resolversNonOptionalTypename ;
1045
-
1046
- res [ typeName ] = this . getAbstractMembersType ( {
1047
- typeName,
1048
- memberTypes : implementingTypes ,
1049
- isTypenameNonOptional : interfaceImplementingType && ! excludeTypes ?. includes ( typeName ) ,
1050
- } ) ;
1051
- }
1052
-
1053
- return res ;
1054
- } , { } ) ;
1053
+ return res ;
1054
+ } ,
1055
+ { }
1056
+ ) ;
1055
1057
1056
1058
return interfaceTypes ;
1057
1059
}
@@ -1584,6 +1586,46 @@ export class BaseResolversVisitor<
1584
1586
return contextType ;
1585
1587
}
1586
1588
1589
+ private parseSchemaMeta ( ) : void {
1590
+ const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1591
+ const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1592
+
1593
+ for ( const typeName of typeNames ) {
1594
+ const schemaType = allSchemaTypes [ typeName ] ;
1595
+
1596
+ if ( isUnionType ( schemaType ) ) {
1597
+ this . _parsedSchemaMeta . types . union [ schemaType . name ] = {
1598
+ type : schemaType ,
1599
+ unionMembers : { } ,
1600
+ } ;
1601
+
1602
+ const unionMemberTypes = schemaType . getTypes ( ) ;
1603
+ for ( const type of unionMemberTypes ) {
1604
+ this . _parsedSchemaMeta . types . union [ schemaType . name ] . unionMembers [ type . name ] = type ;
1605
+ this . _parsedSchemaMeta . typesWithIsTypeOf [ type . name ] = true ;
1606
+ }
1607
+ }
1608
+
1609
+ if ( isInterfaceType ( schemaType ) ) {
1610
+ this . _parsedSchemaMeta . types . interface [ schemaType . name ] = {
1611
+ type : schemaType ,
1612
+ implementingTypes : { } ,
1613
+ } ;
1614
+
1615
+ for ( const graphqlType of Object . values ( allSchemaTypes ) ) {
1616
+ if ( graphqlType instanceof GraphQLObjectType ) {
1617
+ const allInterfaces = graphqlType . getInterfaces ( ) ;
1618
+
1619
+ if ( allInterfaces . some ( int => int . name === schemaType . name ) ) {
1620
+ this . _parsedSchemaMeta . types . interface [ schemaType . name ] . implementingTypes [ graphqlType . name ] = graphqlType ;
1621
+ this . _parsedSchemaMeta . typesWithIsTypeOf [ graphqlType . name ] = true ;
1622
+ }
1623
+ }
1624
+ }
1625
+ }
1626
+ }
1627
+ }
1628
+
1587
1629
protected applyRequireFields ( argsType : string , fields : InputValueDefinitionNode [ ] ) : string {
1588
1630
this . _globalDeclarations . add ( REQUIRE_FIELDS_TYPE ) ;
1589
1631
return `RequireFields<${ argsType } , ${ fields . map ( f => `'${ f . name . value } '` ) . join ( ' | ' ) } >` ;
@@ -1624,7 +1666,7 @@ export class BaseResolversVisitor<
1624
1666
) . value ;
1625
1667
} ) ;
1626
1668
1627
- if ( ! rootType ) {
1669
+ if ( ! rootType && this . _parsedSchemaMeta . typesWithIsTypeOf [ typeName ] ) {
1628
1670
fieldsContent . push (
1629
1671
indent (
1630
1672
`${
@@ -1811,25 +1853,14 @@ export class BaseResolversVisitor<
1811
1853
suffix : this . config . resolverTypeSuffix ,
1812
1854
} ) ;
1813
1855
const declarationKind = 'type' ;
1814
- const allTypesMap = this . _schema . getTypeMap ( ) ;
1815
- const implementingTypes : string [ ] = [ ] ;
1816
-
1817
1856
const typeName = node . name as any as string ;
1857
+ const implementingTypes = Object . keys ( this . _parsedSchemaMeta . types . interface [ typeName ] . implementingTypes ) ;
1818
1858
1819
1859
this . _collectedResolvers [ typeName ] = {
1820
1860
typename : name + '<ContextType>' ,
1821
1861
baseGeneratedTypename : name ,
1822
1862
} ;
1823
1863
1824
- for ( const graphqlType of Object . values ( allTypesMap ) ) {
1825
- if ( graphqlType instanceof GraphQLObjectType ) {
1826
- const allInterfaces = graphqlType . getInterfaces ( ) ;
1827
- if ( allInterfaces . find ( int => int . name === typeName ) ) {
1828
- implementingTypes . push ( graphqlType . name ) ;
1829
- }
1830
- }
1831
- }
1832
-
1833
1864
const parentType = this . getParentTypeToUse ( typeName ) ;
1834
1865
1835
1866
const genericTypes : string [ ] = [
0 commit comments