Skip to content

Commit

Permalink
feat(hooks): hook for individual enum value (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjie committed Jul 26, 2017
1 parent 77edca3 commit 3d82458
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/graphql-build/__tests__/__snapshots__/enum.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`generated schema 1`] = `
"enum MyEnum {
ONE @deprecated(reason: \\"We no longer support numbers smaller than PI\\")
TWO @deprecated(reason: \\"We no longer support numbers smaller than PI\\")
THREE @deprecated(reason: \\"We no longer support numbers smaller than PI\\")
FOUR
}
# An object with a globally unique \`ID\`.
interface Node {
# A globally unique identifier. Can be used in various places throughout the system to identify this single value.
nodeId: ID!
}
# The root query type which gives access points into the data universe.
type Query implements Node {
# Exposes the root query type nested one level down. This is helpful for Relay 1
# which can only query top level fields if they are in a particular form.
query: Query!
# The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`.
nodeId: ID!
# Fetches an object given its globally unique \`ID\`.
node(
# The globally unique \`ID\`.
nodeId: ID!
): Node
enum: MyEnum
}
"
`;
88 changes: 88 additions & 0 deletions packages/graphql-build/__tests__/enum.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
const {
graphql,
GraphQLObjectType,
GraphQLEnumType,
GraphQLInt,
GraphQLString,
GraphQLNonNull,
GraphQLList,
} = require("graphql");
const { printSchema } = require("graphql/utilities");
const { buildSchema, defaultPlugins, MutationPlugin } = require("../");

const base64 = str => new Buffer(String(str)).toString("base64");
const base64Decode = str => new Buffer(String(str), "base64").toString("utf8");

const dummyData = [
{ ID: "foo", CAPS: "FOO" },
{ ID: "bar", CAPS: "BAR" },
{ ID: "baz", CAPS: "BAZ" },
{ ID: "qux", CAPS: "QUX" },
];

const compare = (a, b, ascending) => {
if (a === b) return 0;
if (ascending) {
return a > b ? 1 : -1;
} else {
return a < b ? 1 : -1;
}
};

function EnumPlugin(builder) {
builder.hook(
"GraphQLObjectType:fields",
(fields, { extend, newWithHooks }, { scope: { isRootQuery } }) => {
if (!isRootQuery) {
return fields;
}
const MyEnum = newWithHooks(
GraphQLEnumType,
{
name: "MyEnum",
values: {
ONE: { value: 1 },
TWO: { value: 2 },
THREE: { value: 3 },
},
},
{
isMyEnum: true,
}
);
return extend(fields, {
enum: {
type: MyEnum,
},
});
}
);
builder.hook(
"GraphQLEnumType:values",
(values, { extend }, { scope: { isMyEnum } }) => {
if (!isMyEnum) {
return values;
}
return extend(values, {
FOUR: { value: 4 },
});
}
);
builder.hook(
"GraphQLEnumType:values:value",
(value, { extend }, { scope: { isMyEnum } }) => {
if (isMyEnum && value.value < 4) {
return extend(value, {
deprecationReason: "We no longer support numbers smaller than PI",
});
} else {
return value;
}
}
);
}

test("generated schema", async () => {
const schema = await buildSchema([...defaultPlugins, EnumPlugin]);
expect(printSchema(schema)).toMatchSnapshot();
});
2 changes: 2 additions & 0 deletions packages/graphql-build/src/SchemaBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,10 @@ class SchemaBuilder extends EventEmitter {
// execute, the following hooks:
// - 'GraphQLEnumType' to add any root-level attributes, e.g. add a description
// - 'GraphQLEnumType:values' to add additional values
// - 'GraphQLEnumType:values:value' to change an individual value
GraphQLEnumType: [],
"GraphQLEnumType:values": [],
"GraphQLEnumType:values:value": [],
};
}

Expand Down
15 changes: 15 additions & 0 deletions packages/graphql-build/src/makeNewBuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,21 @@ export default function makeNewBuild(builder: SchemaBuilder): Build {
},
`|${newSpec.name}`
);
const values = newSpec.values;
newSpec.values = Object.keys(values).reduce((memo, valueKey) => {
const value = values[valueKey];
const newValue = builder.applyHooks(
this,
"GraphQLEnumType:values:value",
value,
{
scope,
},
`|${newSpec.name}|${valueKey}`
);
memo[valueKey] = newValue;
return memo;
}, {});
}
const finalSpec: ConfigType = newSpec;

Expand Down

0 comments on commit 3d82458

Please sign in to comment.