@@ -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 ;
@@ -618,15 +617,6 @@ export interface RawResolversConfig extends RawConfig {
618
617
* If you are using `mercurius-js`, please set this field to empty string for better compatibility.
619
618
*/
620
619
internalResolversPrefix ?: string ;
621
- /**
622
- * @type object
623
- * @default {}
624
- * @description If relevant internal resolvers are set to `true`, the resolver type will only be generated if the right conditions are met.
625
- * Enabling this allows a more correct type generation for the resolvers.
626
- * For example:
627
- * - `__isTypeOf` is generated for implementing types and union members
628
- */
629
- generateInternalResolversIfNeeded ?: GenerateInternalResolversIfNeededConfig ;
630
620
/**
631
621
* @description Makes `__typename` of resolver mappings non-optional without affecting the base types.
632
622
* @default false
@@ -705,6 +695,31 @@ export class BaseResolversVisitor<
705
695
baseGeneratedTypename ?: string ;
706
696
} ;
707
697
} = { } ;
698
+ protected _parsedSchemaMeta : {
699
+ types : {
700
+ interface : Record <
701
+ string ,
702
+ {
703
+ type : GraphQLInterfaceType ;
704
+ implementingTypes : Record < string , GraphQLObjectType > ;
705
+ }
706
+ > ;
707
+ union : Record <
708
+ string ,
709
+ {
710
+ type : GraphQLUnionType ;
711
+ unionMembers : Record < string , GraphQLObjectType > ;
712
+ }
713
+ > ;
714
+ } ;
715
+ typesWithIsTypeOf : Record < string , true > ;
716
+ } = {
717
+ types : {
718
+ interface : { } ,
719
+ union : { } ,
720
+ } ,
721
+ typesWithIsTypeOf : { } ,
722
+ } ;
708
723
protected _collectedDirectiveResolvers : { [ key : string ] : string } = { } ;
709
724
protected _variablesTransformer : OperationVariablesToObject ;
710
725
protected _usedMappers : { [ key : string ] : boolean } = { } ;
@@ -713,7 +728,6 @@ export class BaseResolversVisitor<
713
728
protected _hasReferencedResolversUnionTypes = false ;
714
729
protected _hasReferencedResolversInterfaceTypes = false ;
715
730
protected _resolversUnionTypes : Record < string , string > = { } ;
716
- protected _resolversUnionParentTypes : Record < string , string > = { } ;
717
731
protected _resolversInterfaceTypes : Record < string , string > = { } ;
718
732
protected _rootTypeNames = new Set < string > ( ) ;
719
733
protected _globalDeclarations = new Set < string > ( ) ;
@@ -779,6 +793,11 @@ export class BaseResolversVisitor<
779
793
this . config . namespacedImportName
780
794
) ;
781
795
796
+ // 1. Parse schema meta at the start once,
797
+ // so we can use it in subsequent generate functions
798
+ this . parseSchemaMeta ( ) ;
799
+
800
+ // 2. Generate types for resolvers
782
801
this . _resolversTypes = this . createResolversFields ( {
783
802
applyWrapper : type => this . applyResolverTypeWrapper ( type ) ,
784
803
clearWrapper : type => this . clearResolverTypeWrapper ( type ) ,
@@ -1030,22 +1049,20 @@ export class BaseResolversVisitor<
1030
1049
return { } ;
1031
1050
}
1032
1051
1033
- const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1034
- const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1035
-
1036
- const unionTypes = typeNames . reduce < Record < string , string > > ( ( res , typeName ) => {
1037
- const schemaType = allSchemaTypes [ typeName ] ;
1038
-
1039
- if ( isUnionType ( schemaType ) ) {
1040
- const { unionMember, excludeTypes } = this . config . resolversNonOptionalTypename ;
1041
- res [ typeName ] = this . getAbstractMembersType ( {
1042
- typeName,
1043
- memberTypes : schemaType . getTypes ( ) ,
1044
- isTypenameNonOptional : unionMember && ! excludeTypes ?. includes ( typeName ) ,
1045
- } ) ;
1046
- }
1047
- return res ;
1048
- } , { } ) ;
1052
+ const unionTypes = Object . entries ( this . _parsedSchemaMeta . types . union ) . reduce < Record < string , string > > (
1053
+ ( res , [ typeName , { type : schemaType , unionMembers } ] ) => {
1054
+ if ( isUnionType ( schemaType ) ) {
1055
+ const { unionMember, excludeTypes } = this . config . resolversNonOptionalTypename ;
1056
+ res [ typeName ] = this . getAbstractMembersType ( {
1057
+ typeName,
1058
+ memberTypes : Object . values ( unionMembers ) ,
1059
+ isTypenameNonOptional : unionMember && ! excludeTypes ?. includes ( typeName ) ,
1060
+ } ) ;
1061
+ }
1062
+ return res ;
1063
+ } ,
1064
+ { }
1065
+ ) ;
1049
1066
1050
1067
return unionTypes ;
1051
1068
}
@@ -1055,37 +1072,22 @@ export class BaseResolversVisitor<
1055
1072
return { } ;
1056
1073
}
1057
1074
1058
- const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1059
- const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1060
-
1061
- const interfaceTypes = typeNames . reduce < Record < string , string > > ( ( res , typeName ) => {
1062
- const schemaType = allSchemaTypes [ typeName ] ;
1063
-
1064
- if ( isInterfaceType ( schemaType ) ) {
1065
- const allTypesMap = this . _schema . getTypeMap ( ) ;
1066
- const implementingTypes : GraphQLObjectType [ ] = [ ] ;
1067
-
1068
- for ( const graphqlType of Object . values ( allTypesMap ) ) {
1069
- if ( graphqlType instanceof GraphQLObjectType ) {
1070
- const allInterfaces = graphqlType . getInterfaces ( ) ;
1075
+ const interfaceTypes = Object . entries ( this . _parsedSchemaMeta . types . interface ) . reduce < Record < string , string > > (
1076
+ ( res , [ typeName , { type : schemaType , implementingTypes } ] ) => {
1077
+ if ( isInterfaceType ( schemaType ) ) {
1078
+ const { interfaceImplementingType, excludeTypes } = this . config . resolversNonOptionalTypename ;
1071
1079
1072
- if ( allInterfaces . some ( int => int . name === schemaType . name ) ) {
1073
- implementingTypes . push ( graphqlType ) ;
1074
- }
1075
- }
1080
+ res [ typeName ] = this . getAbstractMembersType ( {
1081
+ typeName,
1082
+ memberTypes : Object . values ( implementingTypes ) ,
1083
+ isTypenameNonOptional : interfaceImplementingType && ! excludeTypes ?. includes ( typeName ) ,
1084
+ } ) ;
1076
1085
}
1077
1086
1078
- const { interfaceImplementingType, excludeTypes } = this . config . resolversNonOptionalTypename ;
1079
-
1080
- res [ typeName ] = this . getAbstractMembersType ( {
1081
- typeName,
1082
- memberTypes : implementingTypes ,
1083
- isTypenameNonOptional : interfaceImplementingType && ! excludeTypes ?. includes ( typeName ) ,
1084
- } ) ;
1085
- }
1086
-
1087
- return res ;
1088
- } , { } ) ;
1087
+ return res ;
1088
+ } ,
1089
+ { }
1090
+ ) ;
1089
1091
1090
1092
return interfaceTypes ;
1091
1093
}
@@ -1637,6 +1639,46 @@ export class BaseResolversVisitor<
1637
1639
return contextType ;
1638
1640
}
1639
1641
1642
+ private parseSchemaMeta ( ) : void {
1643
+ const allSchemaTypes = this . _schema . getTypeMap ( ) ;
1644
+ const typeNames = this . _federation . filterTypeNames ( Object . keys ( allSchemaTypes ) ) ;
1645
+
1646
+ for ( const typeName of typeNames ) {
1647
+ const schemaType = allSchemaTypes [ typeName ] ;
1648
+
1649
+ if ( isUnionType ( schemaType ) ) {
1650
+ this . _parsedSchemaMeta . types . union [ schemaType . name ] = {
1651
+ type : schemaType ,
1652
+ unionMembers : { } ,
1653
+ } ;
1654
+
1655
+ const unionMemberTypes = schemaType . getTypes ( ) ;
1656
+ for ( const type of unionMemberTypes ) {
1657
+ this . _parsedSchemaMeta . types . union [ schemaType . name ] . unionMembers [ type . name ] = type ;
1658
+ this . _parsedSchemaMeta . typesWithIsTypeOf [ type . name ] = true ;
1659
+ }
1660
+ }
1661
+
1662
+ if ( isInterfaceType ( schemaType ) ) {
1663
+ this . _parsedSchemaMeta . types . interface [ schemaType . name ] = {
1664
+ type : schemaType ,
1665
+ implementingTypes : { } ,
1666
+ } ;
1667
+
1668
+ for ( const graphqlType of Object . values ( allSchemaTypes ) ) {
1669
+ if ( graphqlType instanceof GraphQLObjectType ) {
1670
+ const allInterfaces = graphqlType . getInterfaces ( ) ;
1671
+
1672
+ if ( allInterfaces . some ( int => int . name === schemaType . name ) ) {
1673
+ this . _parsedSchemaMeta . types . interface [ schemaType . name ] . implementingTypes [ graphqlType . name ] = graphqlType ;
1674
+ this . _parsedSchemaMeta . typesWithIsTypeOf [ graphqlType . name ] = true ;
1675
+ }
1676
+ }
1677
+ }
1678
+ }
1679
+ }
1680
+ }
1681
+
1640
1682
protected applyRequireFields ( argsType : string , fields : InputValueDefinitionNode [ ] ) : string {
1641
1683
this . _globalDeclarations . add ( REQUIRE_FIELDS_TYPE ) ;
1642
1684
return `RequireFields<${ argsType } , ${ fields . map ( f => `'${ f . name . value } '` ) . join ( ' | ' ) } >` ;
@@ -1677,7 +1719,7 @@ export class BaseResolversVisitor<
1677
1719
) . value ;
1678
1720
} ) ;
1679
1721
1680
- if ( ! rootType ) {
1722
+ if ( ! rootType && this . _parsedSchemaMeta . typesWithIsTypeOf [ typeName ] ) {
1681
1723
fieldsContent . push (
1682
1724
indent (
1683
1725
`${
@@ -1864,25 +1906,14 @@ export class BaseResolversVisitor<
1864
1906
suffix : this . config . resolverTypeSuffix ,
1865
1907
} ) ;
1866
1908
const declarationKind = 'type' ;
1867
- const allTypesMap = this . _schema . getTypeMap ( ) ;
1868
- const implementingTypes : string [ ] = [ ] ;
1869
-
1870
1909
const typeName = node . name as any as string ;
1910
+ const implementingTypes = Object . keys ( this . _parsedSchemaMeta . types . interface [ typeName ] . implementingTypes ) ;
1871
1911
1872
1912
this . _collectedResolvers [ typeName ] = {
1873
1913
typename : name + '<ContextType>' ,
1874
1914
baseGeneratedTypename : name ,
1875
1915
} ;
1876
1916
1877
- for ( const graphqlType of Object . values ( allTypesMap ) ) {
1878
- if ( graphqlType instanceof GraphQLObjectType ) {
1879
- const allInterfaces = graphqlType . getInterfaces ( ) ;
1880
- if ( allInterfaces . find ( int => int . name === typeName ) ) {
1881
- implementingTypes . push ( graphqlType . name ) ;
1882
- }
1883
- }
1884
- }
1885
-
1886
1917
const parentType = this . getParentTypeToUse ( typeName ) ;
1887
1918
1888
1919
const genericTypes : string [ ] = [
0 commit comments