Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
fix(generation): allow modification of default scalar types
Browse files Browse the repository at this point in the history
Add back support, although still not recommended.
  • Loading branch information
yaacovCR committed Feb 6, 2020
1 parent 3503c5e commit 722abfa
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 17 deletions.
47 changes: 30 additions & 17 deletions src/generate/addResolversToSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
GraphQLSchema,
GraphQLObjectType,
GraphQLInterfaceType,
isSpecifiedScalarType,
} from 'graphql';

import {
Expand Down Expand Up @@ -83,23 +84,35 @@ function addResolversToSchema(
}

if (type instanceof GraphQLScalarType) {
const config = type.toConfig();

Object.keys(resolverValue).forEach(fieldName => {
// Below is necessary as legacy code for scalar type specification allowed
// hardcoding within the resolver an object with fields '__serialize',
// '__parse', and '__parseLiteral', see examples in testMocking.ts.
// Luckily, the fields on GraphQLScalarType and GraphQLScalarTypeConfig
// are named the same.
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
} else {
config[fieldName] = resolverValue[fieldName];
}
});
if (isSpecifiedScalarType(type)) {
// Support -- without recommending -- overriding default scalar types
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
} else {
type[fieldName] = resolverValue[fieldName];
}
});
} else {
// Otherwise the existing schema types are not changed, just replaced.
const config = type.toConfig();

Object.keys(resolverValue).forEach(fieldName => {
// Below is necessary as legacy code for scalar type specification allowed
// hardcoding within the resolver an object with fields '__serialize',
// '__parse', and '__parseLiteral', see examples in testMocking.ts.
// Luckily, the fields on GraphQLScalarType and GraphQLScalarTypeConfig
// are named the same.
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
} else {
config[fieldName] = resolverValue[fieldName];
}
});

// healSchema called later to update all fields to new type
typeMap[type.name] = new GraphQLScalarType(config);
// healSchema called later to update all fields to new type
typeMap[typeName] = new GraphQLScalarType(config);
}
} else if (type instanceof GraphQLEnumType) {
// We've encountered an enum resolver that is being used to provide an
// internal enum value.
Expand Down Expand Up @@ -134,7 +147,7 @@ function addResolversToSchema(
});

// healSchema called later to update all fields to new type
typeMap[type.name] = new GraphQLEnumType({
typeMap[typeName] = new GraphQLEnumType({
...config,
values: newValues,
});
Expand Down
66 changes: 66 additions & 0 deletions src/test/testSchemaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
execute,
VariableDefinitionNode,
DocumentNode,
GraphQLBoolean,
graphqlSync,
} from 'graphql';
// import { printSchema } from 'graphql';
const { GraphQLJSON } = require('graphql-type-json');
Expand Down Expand Up @@ -754,6 +756,70 @@ describe('generating schema from shorthand', () => {
expect(jsSchema.getType('JSON')['description']).to.have.length.above(0);
});

it('supports passing a default scalar type', () => {
const shorthand = `
type Foo {
aField: Boolean
}
type Query {
foo: Foo
}
`;
const resolveFunctions = {
Boolean: GraphQLBoolean,
};
const jsSchema = makeExecutableSchema({
typeDefs: shorthand,
resolvers: resolveFunctions,
});
expect(jsSchema.getQueryType().name).to.equal('Query');
expect(jsSchema.getType('Boolean')).to.equal(GraphQLBoolean);
});

it('allow overriding default scalar type fields', () => {
const originalSerialize = GraphQLBoolean.serialize;
const shorthand = `
type Foo {
aField: Boolean
}
type Query {
foo: Foo
}
`;
const resolveFunctions = {
Boolean: new GraphQLScalarType({
name: 'Boolean',
serialize: () => false,
}),
Query: {
foo: () => ({ aField: true }),
}
};
const jsSchema = makeExecutableSchema({
typeDefs: shorthand,
resolvers: resolveFunctions,
});
const testQuery = `
{
foo {
aField
}
}
`;
const result = graphqlSync(jsSchema, testQuery);
expect(result.data.foo.aField).to.equal(false);
addResolversToSchema({
schema: jsSchema,
resolvers: {
Boolean: {
serialize: originalSerialize,
}
}
});
});

it('retains scalars after walking/recreating the schema', () => {
const shorthand = `
scalar Test
Expand Down

0 comments on commit 722abfa

Please sign in to comment.