graphile-build
Version:
Build a GraphQL schema from plugins
100 lines (97 loc) • 3.1 kB
Flow
// @flow
import type { Plugin, Build } from "../SchemaBuilder";
import { Kind } from "graphql/language";
export default (function StandardTypesPlugin(builder) {
// XXX: this should be in an "init" plugin, but PgTypesPlugin requires it in build - fix that, then fix this
builder.hook(
"build",
(build: Build): Build => {
const stringType = (name, description) =>
new build.graphql.GraphQLScalarType({
name,
description,
serialize: value => String(value),
parseValue: value => String(value),
parseLiteral: ast => {
if (ast.kind !== Kind.STRING) {
throw new Error("Can only parse string values");
}
return ast.value;
},
});
const Cursor = stringType(
"Cursor",
"A location in a connection that can be used for resuming pagination."
);
build.addType(Cursor, "graphile-build built-in");
return build;
},
["StandardTypes"]
);
builder.hook(
"init",
(_: {}, build) => {
const {
newWithHooks,
graphql: { GraphQLNonNull, GraphQLObjectType, GraphQLBoolean },
inflection,
} = build;
// https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo
/* const PageInfo = */
newWithHooks(
GraphQLObjectType,
{
name: inflection.builtin("PageInfo"),
description: build.wrapDescription(
"Information about pagination in a connection.",
"type"
),
fields: ({ fieldWithHooks }) => ({
hasNextPage: fieldWithHooks(
"hasNextPage",
({ addDataGenerator }) => {
addDataGenerator(() => {
return {
calculateHasNextPage: true,
};
});
return {
description: build.wrapDescription(
"When paginating forwards, are there more items?",
"field"
),
type: new GraphQLNonNull(GraphQLBoolean),
};
},
{ isPageInfoHasNextPageField: true }
),
hasPreviousPage: fieldWithHooks(
"hasPreviousPage",
({ addDataGenerator }) => {
addDataGenerator(() => {
return {
calculateHasPreviousPage: true,
};
});
return {
description: build.wrapDescription(
"When paginating backwards, are there more items?",
"field"
),
type: new GraphQLNonNull(GraphQLBoolean),
};
},
{ isPageInfoHasPreviousPageField: true }
),
}),
},
{
__origin: `graphile-build built-in`,
isPageInfo: true,
}
);
return _;
},
["StandardTypes", "PageInfo"]
);
}: Plugin);