Skip to content

Commit 047170a

Browse files
committed
Make 'extendSchema' assign 'astNode' & 'extensionASTNodes'
1 parent 3e34b17 commit 047170a

File tree

2 files changed

+118
-3
lines changed

2 files changed

+118
-3
lines changed

src/utilities/__tests__/extendSchema-test.js

+93-1
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99

1010
import { describe, it } from 'mocha';
1111
import { expect } from 'chai';
12+
import { buildSchema } from '../buildASTSchema';
1213
import { extendSchema } from '../extendSchema';
1314
import { execute } from '../../execution';
14-
import { parse } from '../../language';
15+
import { parse, print } from '../../language';
1516
import { printSchema } from '../schemaPrinter';
1617
import {
1718
GraphQLSchema,
@@ -193,6 +194,97 @@ interface SomeInterface {
193194
194195
union SomeUnion = Foo | Biz
195196
`);
197+
198+
});
199+
200+
it('correctly assign AST nodes to new and extended types', () => {
201+
const schemaFromIDL = buildSchema(`
202+
type Query {
203+
dummyField: String
204+
}
205+
`);
206+
const extensionAst = parse(`
207+
extend type Query {
208+
newField(testArg: TestInput): TestEnum
209+
}
210+
211+
enum TestEnum {
212+
TEST_VALUE
213+
}
214+
215+
input TestInput {
216+
testInputField: TestEnum
217+
}
218+
`);
219+
const extendedSchema = extendSchema(schemaFromIDL, extensionAst);
220+
const secondExtensionAst = parse(`
221+
extend type Query {
222+
oneMoreNewField: TestUnion
223+
}
224+
225+
union TestUnion = TestType
226+
227+
interface TestInterface {
228+
interfaceField: String
229+
}
230+
231+
type TestType implements TestInterface {
232+
interfaceField: String
233+
}
234+
235+
directive @test(arg: Int) on FIELD
236+
`);
237+
const extendedTwiceSchema = extendSchema(extendedSchema,
238+
secondExtensionAst);
239+
240+
const query = extendedTwiceSchema.getType('Query');
241+
const testInput = extendedTwiceSchema.getType('TestInput');
242+
const testEnum = extendedTwiceSchema.getType('TestEnum');
243+
const testUnion = extendedTwiceSchema.getType('TestUnion');
244+
const testInterface = extendedTwiceSchema.getType('TestInterface');
245+
const testType = extendedTwiceSchema.getType('TestType');
246+
const testDirective = extendedTwiceSchema.getDirective('test');
247+
248+
expect(query.extensionASTNodes).to.have.lengthOf(2);
249+
expect(testType.extensionASTNodes).to.have.lengthOf(0);
250+
251+
const restoredExtensionAST = parse(
252+
print(query.extensionASTNodes[0]) + '\n' +
253+
print(query.extensionASTNodes[1]) + '\n' +
254+
print(testInput.astNode) + '\n' +
255+
print(testEnum.astNode) + '\n' +
256+
print(testUnion.astNode) + '\n' +
257+
print(testInterface.astNode) + '\n' +
258+
print(testType.astNode) + '\n' +
259+
print(testDirective.astNode)
260+
);
261+
expect(
262+
printSchema(extendSchema(schemaFromIDL, restoredExtensionAST))
263+
).to.be.equal(printSchema(extendedTwiceSchema));
264+
265+
const newField = query.getFields().newField;
266+
expect(print(newField.astNode)).to.equal(
267+
'newField(testArg: TestInput): TestEnum'
268+
);
269+
expect(print(newField.args[0].astNode)).to.equal(
270+
'testArg: TestInput'
271+
);
272+
expect(print(query.getFields().oneMoreNewField.astNode)).to.equal(
273+
'oneMoreNewField: TestUnion'
274+
);
275+
expect(print(testInput.getFields().testInputField.astNode)).to.equal(
276+
'testInputField: TestEnum'
277+
);
278+
expect(print(testEnum.getValue('TEST_VALUE').astNode)).to.equal(
279+
'TEST_VALUE'
280+
);
281+
expect(print(testInterface.getFields().interfaceField.astNode)).to.equal(
282+
'interfaceField: String'
283+
);
284+
expect(print(testType.getFields().interfaceField.astNode)).to.equal(
285+
'interfaceField: String'
286+
);
287+
expect(print(testDirective.args[0].astNode)).to.equal('arg: Int');
196288
});
197289

198290
it('builds types with deprecated fields/values', () => {

src/utilities/extendSchema.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ export function extendSchema(
252252
subscription: subscriptionType,
253253
types,
254254
directives: getMergedDirectives(),
255+
astNode: schema.astNode,
255256
});
256257

257258
// Below are functions used for producing this schema that have closed over
@@ -344,11 +345,19 @@ export function extendSchema(
344345
}
345346

346347
function extendObjectType(type: GraphQLObjectType): GraphQLObjectType {
348+
const name = type.name;
349+
let extensionASTNodes = type.extensionASTNodes;
350+
if (typeExtensionsMap[name]) {
351+
extensionASTNodes = extensionASTNodes.concat(typeExtensionsMap[name]);
352+
}
353+
347354
return new GraphQLObjectType({
348-
name: type.name,
355+
name,
349356
description: type.description,
350357
interfaces: () => extendImplementedInterfaces(type),
351358
fields: () => extendFieldMap(type),
359+
astNode: type.astNode,
360+
extensionASTNodes,
352361
isTypeOf: type.isTypeOf,
353362
});
354363
}
@@ -360,6 +369,7 @@ export function extendSchema(
360369
name: type.name,
361370
description: type.description,
362371
fields: () => extendFieldMap(type),
372+
astNode: type.astNode,
363373
resolveType: type.resolveType,
364374
});
365375
}
@@ -369,6 +379,7 @@ export function extendSchema(
369379
name: type.name,
370380
description: type.description,
371381
types: type.getTypes().map(getTypeFromDef),
382+
astNode: type.astNode,
372383
resolveType: type.resolveType,
373384
});
374385
}
@@ -409,6 +420,7 @@ export function extendSchema(
409420
deprecationReason: field.deprecationReason,
410421
type: extendFieldType(field.type),
411422
args: keyMap(field.args, arg => arg.name),
423+
astNode: field.astNode,
412424
resolve: field.resolve,
413425
};
414426
});
@@ -430,6 +442,7 @@ export function extendSchema(
430442
description: getDescription(field),
431443
type: buildOutputFieldType(field.type),
432444
args: buildInputValues(field.arguments),
445+
astNode: field,
433446
deprecationReason: getDeprecationReason(field.directives),
434447
};
435448
});
@@ -467,6 +480,7 @@ export function extendSchema(
467480
description: getDescription(typeNode),
468481
interfaces: () => buildImplementedInterfaces(typeNode),
469482
fields: () => buildFieldMap(typeNode),
483+
astNode: typeNode,
470484
});
471485
}
472486

@@ -475,6 +489,7 @@ export function extendSchema(
475489
name: typeNode.name.value,
476490
description: getDescription(typeNode),
477491
fields: () => buildFieldMap(typeNode),
492+
astNode: typeNode,
478493
resolveType: cannotExecuteExtendedSchema,
479494
});
480495
}
@@ -484,6 +499,7 @@ export function extendSchema(
484499
name: typeNode.name.value,
485500
description: getDescription(typeNode),
486501
types: typeNode.types.map(getObjectTypeFromAST),
502+
astNode: typeNode,
487503
resolveType: cannotExecuteExtendedSchema,
488504
});
489505
}
@@ -492,6 +508,7 @@ export function extendSchema(
492508
return new GraphQLScalarType({
493509
name: typeNode.name.value,
494510
description: getDescription(typeNode),
511+
astNode: typeNode,
495512
serialize: id => id,
496513
// Note: validation calls the parse functions to determine if a
497514
// literal value is correct. Returning null would cause use of custom
@@ -512,8 +529,10 @@ export function extendSchema(
512529
enumValue => ({
513530
description: getDescription(enumValue),
514531
deprecationReason: getDeprecationReason(enumValue.directives),
532+
astNode: enumValue,
515533
}),
516534
),
535+
astNode: typeNode,
517536
});
518537
}
519538

@@ -522,6 +541,7 @@ export function extendSchema(
522541
name: typeNode.name.value,
523542
description: getDescription(typeNode),
524543
fields: () => buildInputValues(typeNode.fields),
544+
astNode: typeNode,
525545
});
526546
}
527547

@@ -535,6 +555,7 @@ export function extendSchema(
535555
),
536556
args:
537557
directiveNode.arguments && buildInputValues(directiveNode.arguments),
558+
astNode: directiveNode,
538559
});
539560
}
540561

@@ -552,6 +573,7 @@ export function extendSchema(
552573
description: getDescription(field),
553574
args: buildInputValues(field.arguments),
554575
deprecationReason: getDeprecationReason(field.directives),
576+
astNode: field,
555577
})
556578
);
557579
}
@@ -565,7 +587,8 @@ export function extendSchema(
565587
return {
566588
type,
567589
description: getDescription(value),
568-
defaultValue: valueFromAST(value.defaultValue, type)
590+
defaultValue: valueFromAST(value.defaultValue, type),
591+
astNode: value,
569592
};
570593
}
571594
);

0 commit comments

Comments
 (0)