Skip to content

Instantly share code, notes, and snippets.

@sungchuni
Last active December 10, 2020 16:22
Show Gist options
  • Save sungchuni/a628880f10b4a4cee5ce055a58ef6460 to your computer and use it in GitHub Desktop.
Save sungchuni/a628880f10b4a4cee5ce055a58ef6460 to your computer and use it in GitHub Desktop.
"use strict";
/**
* directive @paginate on FIELD_DEFINITION
* """
* abstract type Page {
* totalCount: Int!
* edges: [Edge!]!
* pageInfo: PageInfo!
* }
* abstract type Edge {
* node: Node!
* cursor: ID!
* }
* abstract type PageInfo {
* endCursor: ID
* hasNextPage: Boolean!
* }
* """
*/
const {
defaultFieldResolver,
GraphQLBoolean,
GraphQLID,
GraphQLInt,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType
} = require("graphql");
const {SchemaDirectiveVisitor} = require("apollo-server-express");
const PageInfoType = new GraphQLObjectType({
name: "PageInfo",
fields: {
endCursor: {type: GraphQLID},
hasNextPage: {type: new GraphQLNonNull(GraphQLBoolean)}
}
});
function createPaginatedType(field) {
const EdgeType = new GraphQLObjectType({
name: `${field.name}Edge`,
fields: {
node: {type: new GraphQLNonNull(field.type)},
cursor: {type: new GraphQLNonNull(GraphQLID)}
}
});
return new GraphQLObjectType({
name: `${field.name}Page`,
fields: {
totalCount: {type: new GraphQLNonNull(GraphQLInt)},
edges: {
type: new GraphQLNonNull(
new GraphQLList(
new GraphQLNonNull(EdgeType)
)
)
},
pageInfo: {type: new GraphQLNonNull(PageInfoType)}
}
});
}
class PaginateDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const {resolve = defaultFieldResolver} = field;
Object.assign(field, {
async resolve(...args) {
return await resolve.apply(this, args);
},
type: createPaginatedType(field)
});
}
}
module.exports = PaginateDirective;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment