Skip to content

Commit fe27d28

Browse files
committed
Allows to add schema definition missing in the original schema
1 parent e895df7 commit fe27d28

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

src/utilities/__tests__/extendSchema-test.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,7 @@ describe('extendSchema', () => {
12871287
expect(schema.getMutationType()).to.equal(null);
12881288
});
12891289

1290-
it('does not allow new schema within an extension', () => {
1290+
it('does not allow overriding schema within an extension', () => {
12911291
const sdl = `
12921292
schema {
12931293
mutation: Mutation
@@ -1302,6 +1302,31 @@ describe('extendSchema', () => {
13021302
);
13031303
});
13041304

1305+
it('adds schema definition missing in the original schema', () => {
1306+
let schema = new GraphQLSchema({
1307+
directives: [
1308+
new GraphQLDirective({
1309+
name: 'onSchema',
1310+
locations: ['SCHEMA'],
1311+
}),
1312+
],
1313+
});
1314+
expect(schema.getQueryType()).to.equal(undefined);
1315+
1316+
const ast = parse(`
1317+
schema @onSchema {
1318+
query: Foo
1319+
}
1320+
1321+
type Foo {
1322+
bar: String
1323+
}
1324+
`);
1325+
schema = extendSchema(schema, ast);
1326+
const queryType = schema.getQueryType();
1327+
expect(queryType).to.have.property('name', 'Foo');
1328+
});
1329+
13051330
it('adds new root types via schema extension', () => {
13061331
const schema = extendTestSchema(`
13071332
extend schema {

src/utilities/extendSchema.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import { Kind } from '../language/kinds';
5353
import type {
5454
DocumentNode,
5555
DirectiveDefinitionNode,
56+
SchemaDefinitionNode,
5657
SchemaExtensionNode,
5758
} from '../language/ast';
5859

@@ -118,12 +119,16 @@ export function extendSchema(
118119
// have the same name. For example, a type named "skip".
119120
const directiveDefinitions: Array<DirectiveDefinitionNode> = [];
120121

122+
let schemaDef: ?SchemaDefinitionNode;
121123
// Schema extensions are collected which may add additional operation types.
122124
const schemaExtensions: Array<SchemaExtensionNode> = [];
123125

124126
for (let i = 0; i < documentAST.definitions.length; i++) {
125127
const def = documentAST.definitions[i];
126128
switch (def.kind) {
129+
case Kind.SCHEMA_DEFINITION:
130+
schemaDef = def;
131+
break;
127132
case Kind.SCHEMA_EXTENSION:
128133
schemaExtensions.push(def);
129134
break;
@@ -190,7 +195,8 @@ export function extendSchema(
190195
Object.keys(typeExtensionsMap).length === 0 &&
191196
Object.keys(typeDefinitionMap).length === 0 &&
192197
directiveDefinitions.length === 0 &&
193-
schemaExtensions.length === 0
198+
schemaExtensions.length === 0 &&
199+
!schemaDef
194200
) {
195201
return schema;
196202
}
@@ -222,9 +228,9 @@ export function extendSchema(
222228
subscription: extendMaybeNamedType(schema.getSubscriptionType()),
223229
};
224230

225-
// Then, incorporate all schema extensions.
226-
for (const schemaExtension of schemaExtensions) {
227-
if (schemaExtension.operationTypes) {
231+
// Then, incorporate schema definition and all schema extensions.
232+
for (const schemaExtension of [schemaDef, ...schemaExtensions]) {
233+
if (schemaExtension && schemaExtension.operationTypes) {
228234
for (const operationType of schemaExtension.operationTypes) {
229235
const operation = operationType.operation;
230236
if (operationTypes[operation]) {

src/validation/rules/LoneSchemaDefinition.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,18 @@ export function canNotDefineSchemaWithinExtension(): string {
2727
export function LoneSchemaDefinition(
2828
context: SDLValidationContext,
2929
): ASTVisitor {
30+
const oldSchema = context.getSchema();
31+
const alreadyDefined =
32+
oldSchema &&
33+
(oldSchema.astNode ||
34+
oldSchema.getQueryType() ||
35+
oldSchema.getMutationType() ||
36+
oldSchema.getSubscriptionType());
37+
3038
const schemaNodes = [];
3139
return {
3240
SchemaDefinition(node) {
33-
if (context.getSchema()) {
41+
if (alreadyDefined) {
3442
context.reportError(
3543
new GraphQLError(canNotDefineSchemaWithinExtension(), [node]),
3644
);

0 commit comments

Comments
 (0)