Skip to content

Commit

Permalink
fix(TypeMapper): accept schema definition in SDL
Browse files Browse the repository at this point in the history
closes #157
  • Loading branch information
nodkz committed Jan 10, 2019
1 parent 6481fe5 commit 44a83d8
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
33 changes: 31 additions & 2 deletions src/TypeMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
DocumentNode,
ObjectTypeDefinitionNode,
InterfaceTypeDefinitionNode,
SchemaDefinitionNode,
TypeNode,
NamedTypeNode,
DirectiveNode,
Expand Down Expand Up @@ -208,7 +209,9 @@ export class TypeMapper<TContext> {
for (let i = 0; i < astDocument.definitions.length; i++) {
const def = astDocument.definitions[i];
const type = makeSchemaDef(def, this.schemaComposer);
typeStorage.set(type.name, type);
if (type) {
typeStorage.set(type.name, type);
}
}
return typeStorage;
}
Expand Down Expand Up @@ -620,7 +623,8 @@ function parseTypes(
const types = [];
for (let i = 0; i < astDocument.definitions.length; i++) {
const def = astDocument.definitions[i];
types[i] = makeSchemaDef(def, schema);
const type = makeSchemaDef(def, schema);
if (type) types[i] = type;
}
return types;
}
Expand Down Expand Up @@ -663,6 +667,9 @@ function makeSchemaDef(def, schema: SchemaComposer<any>) {
// return makeUnionDef(def);
// case SCALAR_TYPE_DEFINITION:
// return makeScalarDef(def);
case Kind.SCHEMA_DEFINITION:
checkSchemaDef(def);
return null;
case Kind.INPUT_OBJECT_TYPE_DEFINITION:
return makeInputObjectDef(def, schema);
default:
Expand Down Expand Up @@ -745,6 +752,28 @@ function makeInputObjectDef(def: InputObjectTypeDefinitionNode, schema: SchemaCo
});
}

function checkSchemaDef(def: SchemaDefinitionNode) {
const validNames = {
query: 'Query',
mutation: 'Mutation',
subscription: 'Subscription',
};

def.operationTypes.forEach(d => {
if (d.operation) {
const validTypeName = validNames[d.operation];
const actualTypeName = d.type.name.value;
if (actualTypeName !== validTypeName) {
throw new Error(
`Incorrect type name '${actualTypeName}' for '${
d.operation
}'. The valid definition is "schema { ${d.operation}: ${validTypeName} }"`
);
}
}
});
}

function getNamedTypeAST(typeAST: TypeNode): NamedTypeNode {
let namedType = typeAST;
while (namedType.kind === Kind.LIST_TYPE || namedType.kind === Kind.NON_NULL_TYPE) {
Expand Down
4 changes: 4 additions & 0 deletions src/__tests__/SchemaComposer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@ describe('SchemaComposer', () => {
it('should add resolve methods to fields in graphql-tools way', async () => {
const sc = new SchemaComposer();
sc.addTypeDefs(`
schema {
query: Query
}
type Post {
id: Int!
title: String
Expand Down
23 changes: 23 additions & 0 deletions src/__tests__/TypeMapper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,29 @@ describe('TypeMapper', () => {
expect(ts.get('Article')).toBeInstanceOf(GraphQLObjectType);
expect(ts.get('Record')).toBeInstanceOf(GraphQLInputObjectType);
});

it('parseTypesFromString() should strictly accept schema definition', () => {
const ts = TypeMapper.parseTypesFromString(`
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
`);
expect(ts.size).toEqual(0);

expect(() => {
TypeMapper.parseTypesFromString(`schema { query: ErrName }`);
}).toThrow("Incorrect type name 'ErrName' for 'query'");

expect(() => {
TypeMapper.parseTypesFromString(`schema { mutation: ErrName }`);
}).toThrow("Incorrect type name 'ErrName' for 'mutation'");

expect(() => {
TypeMapper.parseTypesFromString(`schema { subscription: ErrName }`);
}).toThrow("Incorrect type name 'ErrName' for 'subscription'");
});
});

describe('createType()', () => {
Expand Down

0 comments on commit 44a83d8

Please sign in to comment.