@@ -92,20 +92,31 @@ export function isolateComputedFieldsTransformer(
92
92
const returnTypeMergeConfig = subschemaConfig . merge [ type . name ] ;
93
93
94
94
if ( isObjectType ( type ) ) {
95
- if ( returnTypeMergeConfig ?. selectionSet ) {
95
+ const returnTypeSelectionSet = returnTypeMergeConfig ?. selectionSet ;
96
+ if ( returnTypeSelectionSet ) {
96
97
// this is a merged type, include the selection set
97
- // TODO: how to handle entryPoints
98
98
const keyFieldNames : string [ ] = [ ] ;
99
- if ( isObjectType ( type ) ) {
100
- const parsedSelectionSet = parseSelectionSet ( returnTypeMergeConfig . selectionSet ! ) ;
101
- const keyFields = collectFields (
102
- subschemaConfig . schema ,
103
- { } ,
104
- { } ,
105
- type ,
106
- parsedSelectionSet ,
107
- ) ;
108
- keyFieldNames . push ( ...Array . from ( keyFields . fields . keys ( ) ) ) ;
99
+ const parsedSelectionSet = parseSelectionSet ( returnTypeSelectionSet ) ;
100
+ const keyFields = collectFields (
101
+ subschemaConfig . schema ,
102
+ { } ,
103
+ { } ,
104
+ type ,
105
+ parsedSelectionSet ,
106
+ ) ;
107
+ keyFieldNames . push ( ...Array . from ( keyFields . fields . keys ( ) ) ) ;
108
+ for ( const entryPoint of returnTypeMergeConfig . entryPoints ?? [ ] ) {
109
+ if ( entryPoint . selectionSet ) {
110
+ const parsedSelectionSet = parseSelectionSet ( entryPoint . selectionSet ) ;
111
+ const keyFields = collectFields (
112
+ subschemaConfig . schema ,
113
+ { } ,
114
+ { } ,
115
+ type ,
116
+ parsedSelectionSet ,
117
+ ) ;
118
+ keyFieldNames . push ( ...Array . from ( keyFields . fields . keys ( ) ) ) ;
119
+ }
109
120
}
110
121
111
122
isolatedSchemaTypes [ type . name ] = {
@@ -128,10 +139,12 @@ export function isolateComputedFieldsTransformer(
128
139
const implementingTypeFields = isolatedSchemaTypes [ implementingType ] ?. fields ;
129
140
if ( implementingTypeFields ) {
130
141
for ( const fieldName in implementingTypeFields ) {
131
- fields [ fieldName ] = {
132
- ...implementingTypeFields [ fieldName ] ,
133
- ...fields [ fieldName ] ,
134
- } ;
142
+ if ( implementingTypeFields [ fieldName ] ) {
143
+ fields [ fieldName ] = {
144
+ ...implementingTypeFields [ fieldName ] ,
145
+ ...fields [ fieldName ] ,
146
+ } ;
147
+ }
135
148
}
136
149
}
137
150
}
@@ -191,7 +204,7 @@ function isIsolatedField(
191
204
isolatedSchemaTypes : Record < string , ComputedTypeConfig > ,
192
205
) : boolean {
193
206
const fieldConfig = isolatedSchemaTypes [ typeName ] ?. fields ?. [ fieldName ] ;
194
- if ( fieldConfig && Object . keys ( fieldConfig ) . length > 0 ) {
207
+ if ( fieldConfig ) {
195
208
return true ;
196
209
}
197
210
return false ;
@@ -345,42 +358,37 @@ function filterIsolatedSubschema(subschemaConfig: IsolatedSubschemaInput): Subsc
345
358
}
346
359
}
347
360
348
- const interfaceFields : Record < string , Record < string , boolean > > = { } ;
349
- for ( const typeName in subschemaConfig . merge ) {
350
- const type = subschemaConfig . schema . getType ( typeName ) ;
351
- if ( ! type || isObjectType ( type ) ) {
352
- if ( ! type || ! ( 'getInterfaces' in type ) ) {
353
- throw new Error ( `${ typeName } expected to have 'getInterfaces' method` ) ;
354
- }
355
- for ( const int of type . getInterfaces ( ) ) {
356
- const intType = subschemaConfig . schema . getType ( int . name ) ;
357
- if ( ! intType || ! ( 'getFields' in intType ) ) {
358
- throw new Error ( `${ int . name } expected to have 'getFields' method` ) ;
359
- }
360
- for ( const intFieldName in intType . getFields ( ) ) {
361
- if (
362
- subschemaConfig . merge [ typeName ] . fields ?. [ intFieldName ] ||
363
- subschemaConfig . merge [ typeName ] . keyFieldNames . includes ( intFieldName )
364
- ) {
365
- interfaceFields [ int . name ] = interfaceFields [ int . name ] || { } ;
366
- interfaceFields [ int . name ] [ intFieldName ] = true ;
367
- }
368
- }
369
- }
370
- }
371
- }
372
-
361
+ const typesForInterface : Record < string , string [ ] > = { } ;
373
362
const filteredSchema = pruneSchema (
374
363
filterSchema ( {
375
364
schema : subschemaConfig . schema ,
376
- rootFieldFilter : ( operation , fieldName , config ) =>
377
- operation === 'Query' &&
378
- ( rootFields [ fieldName ] != null || computedFieldTypes [ getNamedType ( config . type ) . name ] ) ,
365
+ rootFieldFilter : ( _ , fieldName , config ) => {
366
+ if ( rootFields [ fieldName ] ) {
367
+ return true ;
368
+ }
369
+ const returnType = getNamedType ( config . type ) ;
370
+ if ( isAbstractType ( returnType ) ) {
371
+ const typesForInterface = getImplementingTypes ( returnType . name , subschemaConfig . schema ) ;
372
+ return typesForInterface . some ( t => computedFieldTypes [ t ] != null ) ;
373
+ }
374
+ return computedFieldTypes [ returnType . name ] != null ;
375
+ } ,
379
376
objectFieldFilter : ( typeName , fieldName ) =>
380
377
subschemaConfig . merge [ typeName ] == null ||
381
378
subschemaConfig . merge [ typeName ] ?. fields ?. [ fieldName ] != null ||
382
379
( subschemaConfig . merge [ typeName ] ?. keyFieldNames ?? [ ] ) . includes ( fieldName ) ,
383
- interfaceFieldFilter : ( typeName , fieldName ) => interfaceFields [ typeName ] ?. [ fieldName ] != null ,
380
+ interfaceFieldFilter : ( typeName , fieldName ) => {
381
+ if ( ! typesForInterface [ typeName ] ) {
382
+ typesForInterface [ typeName ] = getImplementingTypes ( typeName , subschemaConfig . schema ) ;
383
+ }
384
+ const isIsolatedFieldName = typesForInterface [ typeName ] . some ( implementingTypeName =>
385
+ isIsolatedField ( implementingTypeName , fieldName , subschemaConfig . merge ) ,
386
+ ) ;
387
+ return (
388
+ isIsolatedFieldName ||
389
+ ( subschemaConfig . merge [ typeName ] ?. keyFieldNames ?? [ ] ) . includes ( fieldName )
390
+ ) ;
391
+ } ,
384
392
} ) ,
385
393
{ skipPruning : typ => computedFieldTypes [ typ . name ] != null } ,
386
394
) ;
0 commit comments