1
- // Flow currently disabled for this file.
1
+ /* @flow */
2
2
/**
3
3
* Copyright (c) 2015, Facebook, Inc.
4
4
* All rights reserved.
@@ -18,12 +18,16 @@ import type {
18
18
SelectionSet ,
19
19
Field ,
20
20
Argument ,
21
- InlineFragment ,
22
- FragmentSpread ,
23
21
Directive
24
22
} from '../../language/ast' ;
23
+ import {
24
+ getNamedType ,
25
+ GraphQLObjectType ,
26
+ GraphQLInterfaceType ,
27
+ } from '../../type/definition' ;
25
28
import type {
26
29
GraphQLType ,
30
+ GraphQLNamedType ,
27
31
GraphQLFieldDefinition
28
32
} from '../../type/definition' ;
29
33
import { typeFromAST } from '../../utilities/typeFromAST' ;
@@ -83,25 +87,21 @@ export default function OverlappingFieldsCanBeMerged(
83
87
84
88
var type1 = def1 && def1 . type ;
85
89
var type2 = def2 && def2 . type ;
86
- if ( ! sameType ( type1 , type2 ) ) {
90
+ if ( type1 && type2 && ! sameType ( type1 , type2 ) ) {
87
91
return [
88
92
[ responseName , `they return differing types ${ type1 } and ${ type2 } ` ] ,
89
93
[ ast1 , ast2 ]
90
94
] ;
91
95
}
92
96
93
- var arguments1 = ast1 . arguments || [ ] ;
94
- var arguments2 = ast2 . arguments || [ ] ;
95
- if ( ! sameArguments ( arguments1 , arguments2 ) ) {
97
+ if ( ! sameArguments ( ast1 . arguments || [ ] , ast2 . arguments || [ ] ) ) {
96
98
return [
97
99
[ responseName , 'they have differing arguments' ] ,
98
100
[ ast1 , ast2 ]
99
101
] ;
100
102
}
101
103
102
- var directives1 = ast1 . directives || [ ] ;
103
- var directives2 = ast2 . directives || [ ] ;
104
- if ( ! sameDirectives ( directives1 , directives2 ) ) {
104
+ if ( ! sameDirectives ( ast1 . directives || [ ] , ast2 . directives || [ ] ) ) {
105
105
return [
106
106
[ responseName , 'they have differing directives' ] ,
107
107
[ ast1 , ast2 ]
@@ -114,13 +114,13 @@ export default function OverlappingFieldsCanBeMerged(
114
114
var visitedFragmentNames = { } ;
115
115
var subfieldMap = collectFieldASTsAndDefs (
116
116
context ,
117
- type1 ,
117
+ getNamedType ( type1 ) ,
118
118
selectionSet1 ,
119
119
visitedFragmentNames
120
120
) ;
121
121
subfieldMap = collectFieldASTsAndDefs (
122
122
context ,
123
- type2 ,
123
+ getNamedType ( type2 ) ,
124
124
selectionSet2 ,
125
125
visitedFragmentNames ,
126
126
subfieldMap
@@ -130,7 +130,7 @@ export default function OverlappingFieldsCanBeMerged(
130
130
return [
131
131
[ responseName , conflicts . map ( ( [ reason ] ) => reason ) ] ,
132
132
conflicts . reduce (
133
- ( list : Array < Field > , [ , blameNodes ] ) => list . concat ( blameNodes ) ,
133
+ ( allFields , [ , fields ] ) => allFields . concat ( fields ) ,
134
134
[ ast1 , ast2 ]
135
135
)
136
136
] ;
@@ -145,15 +145,15 @@ export default function OverlappingFieldsCanBeMerged(
145
145
leave ( selectionSet ) {
146
146
var fieldMap = collectFieldASTsAndDefs (
147
147
context ,
148
- context . getType ( ) ,
148
+ context . getParentType ( ) ,
149
149
selectionSet
150
150
) ;
151
151
var conflicts = findConflicts ( fieldMap ) ;
152
152
if ( conflicts . length ) {
153
- return conflicts . map ( ( [ [ responseName , reason ] , blameNodes ] ) =>
153
+ return conflicts . map ( ( [ [ responseName , reason ] , fields ] ) =>
154
154
new GraphQLError (
155
155
fieldsConflictMessage ( responseName , reason ) ,
156
- blameNodes
156
+ fields
157
157
)
158
158
) ;
159
159
}
@@ -164,7 +164,7 @@ export default function OverlappingFieldsCanBeMerged(
164
164
165
165
type Conflict = [ ConflictReason , Array < Field > ] ;
166
166
// Field name and reason, or field name and list of sub-conflicts.
167
- type ConflictReason = [ string , string ] | [ string , Array < ConflictReason > ] ;
167
+ type ConflictReason = [ string , string | Array < ConflictReason > ] ;
168
168
169
169
function sameDirectives (
170
170
directives1 : Array < Directive > ,
@@ -181,7 +181,10 @@ function sameDirectives(
181
181
if ( ! directive2 ) {
182
182
return false ;
183
183
}
184
- return sameArguments ( directive1 . arguments , directive2 . arguments ) ;
184
+ return sameArguments (
185
+ directive1 . arguments || [ ] ,
186
+ directive2 . arguments || [ ]
187
+ ) ;
185
188
} ) ;
186
189
}
187
190
@@ -208,8 +211,8 @@ function sameValue(value1, value2) {
208
211
return ( ! value1 && ! value2 ) || print ( value1 ) === print ( value2 ) ;
209
212
}
210
213
211
- function sameType ( type1 , type2 ) {
212
- return ( ! type1 && ! type2 ) || String ( type1 ) === String ( type2 ) ;
214
+ function sameType ( type1 : GraphQLType , type2 : GraphQLType ) {
215
+ return String ( type1 ) === String ( type2 ) ;
213
216
}
214
217
215
218
@@ -223,40 +226,40 @@ function sameType(type1, type2) {
223
226
*/
224
227
function collectFieldASTsAndDefs (
225
228
context : ValidationContext ,
226
- parentType : ?GraphQLType ,
229
+ parentType : ?GraphQLNamedType ,
227
230
selectionSet : SelectionSet ,
228
231
visitedFragmentNames ?: { [ key : string ] : boolean } ,
229
- astAndDefs ?: { [ key : string ] : Array < [ Field , GraphQLFieldDefinition ] > }
230
- ) : { [ key : string ] : Array < [ Field , GraphQLFieldDefinition ] > } {
232
+ astAndDefs ?: { [ key : string ] : Array < [ Field , ? GraphQLFieldDefinition ] > }
233
+ ) : { [ key : string ] : Array < [ Field , ? GraphQLFieldDefinition ] > } {
231
234
var _visitedFragmentNames = visitedFragmentNames || { } ;
232
235
var _astAndDefs = astAndDefs || { } ;
233
236
for ( var i = 0 ; i < selectionSet . selections . length ; i ++ ) {
234
237
var selection = selectionSet . selections [ i ] ;
235
238
switch ( selection . kind ) {
236
239
case FIELD :
237
- var fieldAST = ( selection : Field ) ;
238
- var fieldName = fieldAST . name . value ;
239
- var fieldDef = parentType && parentType . getFields &&
240
- parentType . getFields ( ) [ fieldName ] ;
241
- var responseName = fieldAST . alias ? fieldAST . alias . value : fieldName ;
240
+ var fieldName = selection . name . value ;
241
+ var fieldDef ;
242
+ if ( parentType instanceof GraphQLObjectType ||
243
+ parentType instanceof GraphQLInterfaceType ) {
244
+ fieldDef = parentType . getFields ( ) [ fieldName ] ;
245
+ }
246
+ var responseName = selection . alias ? selection . alias . value : fieldName ;
242
247
if ( ! _astAndDefs [ responseName ] ) {
243
248
_astAndDefs [ responseName ] = [ ] ;
244
249
}
245
- _astAndDefs [ responseName ] . push ( [ fieldAST , fieldDef ] ) ;
250
+ _astAndDefs [ responseName ] . push ( [ selection , fieldDef ] ) ;
246
251
break ;
247
252
case INLINE_FRAGMENT :
248
- var inlineFragment = ( selection : InlineFragment ) ;
249
253
_astAndDefs = collectFieldASTsAndDefs (
250
254
context ,
251
- typeFromAST ( context . getSchema ( ) , inlineFragment . typeCondition ) ,
252
- inlineFragment . selectionSet ,
255
+ typeFromAST ( context . getSchema ( ) , selection . typeCondition ) ,
256
+ selection . selectionSet ,
253
257
_visitedFragmentNames ,
254
258
_astAndDefs
255
259
) ;
256
260
break ;
257
261
case FRAGMENT_SPREAD :
258
- var fragmentSpread = ( selection : FragmentSpread ) ;
259
- var fragName = fragmentSpread . name . value ;
262
+ var fragName = selection . name . value ;
260
263
if ( _visitedFragmentNames [ fragName ] ) {
261
264
continue;
262
265
}
0 commit comments