@@ -12,6 +12,7 @@ import {
1212 isObjectType ,
1313 isInterfaceType ,
1414 ValuesOfCorrectTypeRule ,
15+ DefinitionNode ,
1516} from 'graphql' ;
1617
1718// FIXME
@@ -220,6 +221,8 @@ const fakeDefinitionAST = parse(/* GraphQL */ `
220221
221222 scalar examples__JSON
222223 directive @examples(values: [examples__JSON]!) on FIELD_DEFINITION | SCALAR
224+
225+ directive @override on FIELD_DEFINITION
223226` ) ;
224227
225228function defToName ( defNode ) {
@@ -256,6 +259,14 @@ export function buildWithFakeDefinitions(
256259 } ) ,
257260 } ;
258261
262+ if ( extensionSDL != null ) {
263+ // Remove fields marked with the @override annotation
264+ filteredAST . definitions = filterFields (
265+ filteredAST . definitions ,
266+ findFieldsWithOverrideDirective ( extensionSDL ) ,
267+ ) ;
268+ }
269+
259270 let schema = extendSchemaWithAST ( schemaWithOnlyFakedDefinitions , filteredAST ) ;
260271
261272 const config = schema . toConfig ( ) ;
@@ -311,6 +322,54 @@ export function buildWithFakeDefinitions(
311322 commentDescriptions : true ,
312323 } ) ;
313324 }
325+
326+ function findFieldsWithOverrideDirective (
327+ extensionSDL : Source ,
328+ ) : Map < string , string [ ] > {
329+ const res = new Map ( ) ;
330+ parseSDL ( extensionSDL ) . definitions . map ( ( d ) => {
331+ if ( d . kind !== 'ObjectTypeExtension' ) {
332+ return ;
333+ }
334+
335+ const filteredFields = d
336+ . fields ! . filter (
337+ ( f ) =>
338+ f . directives ! . findIndex ( ( d ) => d . name . value === 'override' ) !== - 1 ,
339+ )
340+ . map ( ( f ) => f . name . value ) ;
341+
342+ if ( filteredFields . length > 0 ) {
343+ res . set ( d . name . value , filteredFields ) ;
344+ }
345+ } ) ;
346+
347+ return res ;
348+ }
349+
350+ function filterFields (
351+ definitions : DefinitionNode [ ] ,
352+ fieldsToRemove : Map < string , string [ ] > ,
353+ ) : DefinitionNode [ ] {
354+ return definitions . map ( ( d ) => {
355+ if (
356+ d . kind === 'ObjectTypeDefinition' &&
357+ fieldsToRemove . has ( d . name . value )
358+ ) {
359+ const toRemove = fieldsToRemove . get ( d . name . value ) ;
360+ const filteredFields = d . fields ! . filter (
361+ ( f ) => toRemove ! . indexOf ( f . name . value ) === - 1 ,
362+ ) ;
363+
364+ return {
365+ ...d ,
366+ fields : filteredFields ,
367+ } ;
368+ }
369+
370+ return d ;
371+ } ) ;
372+ }
314373}
315374
316375// FIXME: move to 'graphql-js'
0 commit comments