@@ -17,7 +17,6 @@ import {
1717 ValueNode ,
1818 GraphQLUnionType ,
1919 GraphQLFieldMap ,
20- GraphQLField ,
2120} from 'graphql' ;
2221import { ObjMap } from 'graphql/jsutils/ObjMap' ;
2322import { GraphQLSchema } from 'graphql/type/schema' ;
@@ -28,6 +27,8 @@ import {
2827 Variables ,
2928 Type ,
3029 Fields ,
30+ FieldWeight ,
31+ FieldMap ,
3132} from '../@types/buildTypeWeights' ;
3233
3334export const KEYWORDS = [ 'first' , 'last' , 'limit' ] ;
@@ -158,10 +159,6 @@ function parseObjectFields(
158159 // Users must query union types using inline fragments to resolve field specific to one of the types in the union
159160 // however, if a type is shared by all types in the union it can be queried outside of the inline fragment
160161 // any common fields should be added to fields on the union type itself in addition to the comprising types
161- // Get all types in the union
162- // iterate through all types creating a set of type names
163- // add resulting set to fields
164- // FIXME: What happens if two types share a name that resolve to different types => invalid query?
165162 result . fields [ field ] = {
166163 resolveTo : fieldType . name . toLocaleLowerCase ( ) ,
167164 } ;
@@ -230,11 +227,8 @@ function parseTypes(schema: GraphQLSchema, typeWeights: TypeWeightSet): TypeWeig
230227 }
231228 } ) ;
232229
233- type FieldMap = { [ index : string ] : GraphQLOutputType } ;
234- type CommonFields = { [ index : string ] : Type } ;
235-
236230 unions . forEach ( ( unionType : GraphQLUnionType ) => {
237- /** Start with the fields for the first object. Store fieldnamd and type
231+ /** Start with the fields for the first object. Store fieldname, type, weight and resolve to for later use
238232 * reduce by selecting fields common to each type
239233 * compare both fieldname and output type accounting for lists and non-nulls
240234 * for object
@@ -249,9 +243,17 @@ function parseTypes(schema: GraphQLSchema, typeWeights: TypeWeightSet): TypeWeig
249243 const types : FieldMap [ ] = unionType . getTypes ( ) . map ( ( objectType : GraphQLObjectType ) => {
250244 const fields : GraphQLFieldMap < any , any > = objectType . getFields ( ) ;
251245
252- const fieldMap : { [ index : string ] : GraphQLOutputType } = { } ;
246+ const fieldMap : FieldMap = { } ;
253247 Object . keys ( fields ) . forEach ( ( field : string ) => {
254- fieldMap [ field ] = fields [ field ] . type ;
248+ // Get the weight of this field on from parent type on the root typeWeight object.
249+ // this only exists for scalars and lists (which resolve to a function);
250+ const { weight, resolveTo } = result [ objectType . name . toLowerCase ( ) ] . fields [ field ] ;
251+
252+ fieldMap [ field ] = {
253+ type : fields [ field ] . type ,
254+ weight, // will only be undefined for object types
255+ resolveTo,
256+ } ;
255257 } ) ;
256258 return fieldMap ;
257259 } ) ;
@@ -261,7 +263,7 @@ function parseTypes(schema: GraphQLSchema, typeWeights: TypeWeightSet): TypeWeig
261263 const commonFields : FieldMap = { } ;
262264 Object . keys ( prev ) . forEach ( ( field : string ) => {
263265 if ( fieldMap [ field ] ) {
264- if ( compareTypes ( prev [ field ] , fieldMap [ field ] ) ) {
266+ if ( compareTypes ( prev [ field ] . type , fieldMap [ field ] . type ) ) {
265267 // they match add the type to the next set
266268 commonFields [ field ] = prev [ field ] ;
267269 }
@@ -274,48 +276,30 @@ function parseTypes(schema: GraphQLSchema, typeWeights: TypeWeightSet): TypeWeig
274276 const fieldTypes : Fields = { } ;
275277
276278 Object . keys ( common ) . forEach ( ( field : string ) => {
277- // if a scalar => weight
278- // object => resolveTo
279- // list => // resolveTo + weight(function)
280- const current = common [ field ] ;
279+ // scalar => weight
280+ // list => resolveTo + weight(function)
281+ // fields that resolve to objects do not need to appear on the union type
282+ const current = common [ field ] . type ;
281283 if ( isScalarType ( current ) ) {
282284 fieldTypes [ field ] = {
283- weight : typeWeights . scalar ,
285+ weight : common [ field ] . weight ,
284286 } ;
285- }
286- // else if (isObjectType(current)) {
287- // fieldTypes[field] = {
288- // resolveTo: current.name,
289- // };
290- // }
291- else if ( isListType ( current ) ) {
292- throw new Error ( 'list types not supported on unions' ) ;
287+ } else if ( isListType ( current ) ) {
293288 fieldTypes [ field ] = {
294- resolveTo : 'test' , // get resolve type problem is recursive data structure (i.e. list of lists)
295- // weight: TODO: Get the function for resolving
289+ resolveTo : common [ field ] . resolveTo ,
290+ weight : common [ field ] . weight ,
296291 } ;
297292 } else if ( isNonNullType ( current ) ) {
298293 throw new Error ( 'non null types not supported on unions' ) ;
299294 // TODO: also a recursive data structure
300295 } else {
301- throw new Error ( 'Unandled union type. Should never get here' ) ;
296+ throw new Error ( 'Unhandled union type. Should never get here' ) ;
302297 }
303298 } ) ;
304299 result [ unionType . name . toLowerCase ( ) ] = {
305300 fields : fieldTypes ,
306301 weight : typeWeights . object ,
307302 } ;
308-
309- //
310- // objects are not. they exist at the root.
311- // FIXME: Is it worth adding objects as a field?
312- // yes, I think so => refactor fieldNode parser
313- // if it resolves to object then add commonFields set
314- // i think we have this already.
315- // double check the non-null tests
316- // commonFields.add({
317- // weight,
318- // });
319303 } ) ;
320304
321305 return result ;
0 commit comments