UNPKG

graphql-compose-pagination

Version:

Plugin for `graphql-compose` which provide a pagination resolver for types.

123 lines 5.86 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.preparePaginationResolver = exports.DEFAULT_PER_PAGE = exports.DEFAULT_RESOLVER_NAME = void 0; const graphql_compose_1 = require("graphql-compose"); const types_1 = require("./types"); exports.DEFAULT_RESOLVER_NAME = 'pagination'; exports.DEFAULT_PER_PAGE = 20; const ALLOWED_TYPE_COMPOSERS = [ 'ObjectTypeComposer', 'InterfaceTypeComposer', 'UnionTypeComposer', 'ScalarTypeComposer', 'EnumTypeComposer', ]; function preparePaginationResolver(tc, opts) { if (!tc || !ALLOWED_TYPE_COMPOSERS.includes(tc.constructor.name)) { throw new Error(`First arg for preparePaginationResolver() should be instance of ${ALLOWED_TYPE_COMPOSERS.join(' or ')}`); } const resolverName = opts.name || exports.DEFAULT_RESOLVER_NAME; if (!opts.countResolver || !(opts.countResolver instanceof graphql_compose_1.Resolver)) { throw new Error(`Option 'opts.countResolver' must be a Resolver instance. Received ${graphql_compose_1.inspect(opts.countResolver)}`); } const countResolve = opts.countResolver.getResolve(); if (!opts.findManyResolver || !(opts.findManyResolver instanceof graphql_compose_1.Resolver)) { throw new Error(`Option 'opts.findManyResolver' must be a Resolver instance. Received ${graphql_compose_1.inspect(opts.findManyResolver)}`); } const findManyResolver = opts.findManyResolver; const findManyResolve = findManyResolver.getResolve(); const additionalArgs = {}; if (findManyResolver.hasArg('filter')) { const filter = findManyResolver.getArg('filter'); if (filter) { additionalArgs.filter = filter; } } if (findManyResolver.hasArg('sort')) { const sort = findManyResolver.getArg('sort'); if (sort) { additionalArgs.sort = sort; } } return tc.schemaComposer.createResolver({ type: types_1.preparePaginationTC(tc, resolverName), name: resolverName, kind: 'query', args: Object.assign({ page: { type: 'Int', description: 'Page number for displaying', }, perPage: { type: 'Int', description: '', defaultValue: opts.perPage || exports.DEFAULT_PER_PAGE, } }, additionalArgs), resolve: (rp) => __awaiter(this, void 0, void 0, function* () { let countPromise; let findManyPromise; const { projection = {}, args, rawQuery } = rp; const page = parseInt(args.page, 10) || 1; if (page <= 0) { throw new Error('Argument `page` should be positive number.'); } const perPage = parseInt(args.perPage, 10) || opts.perPage || exports.DEFAULT_PER_PAGE; if (perPage <= 0) { throw new Error('Argument `perPage` should be positive number.'); } const countParams = Object.assign(Object.assign({}, rp), { rawQuery, args: Object.assign(Object.assign({}, rp.args), { filter: Object.assign({}, rp.args.filter) }) }); if (projection.count || (projection.pageInfo && (projection.pageInfo.itemCount || projection.pageInfo.pageCount))) { countPromise = countResolve(countParams); } else { countPromise = Promise.resolve(0); } const findManyParams = Object.assign({}, rp); if (projection && projection.items) { findManyParams.projection = Object.assign(Object.assign({}, projection), projection.items); } else { findManyParams.projection = Object.assign({}, projection); } const limit = perPage; const skip = (page - 1) * perPage; findManyParams.args.limit = limit + 1; if (skip > 0) { findManyParams.args.skip = skip; } rp.findManyResolveParams = findManyParams; rp.countResolveParams = countParams; if ((projection.count || projection.pageInfo) && Object.keys(projection).length === 1) { findManyPromise = Promise.resolve([]); } else { findManyPromise = findManyResolve(findManyParams); } return Promise.all([findManyPromise, countPromise]).then(([items, count]) => { const result = { count, items: items.length > limit ? items.slice(0, limit) : items, pageInfo: { currentPage: page, perPage, itemCount: count, pageCount: Math.ceil(count / perPage), hasPreviousPage: page > 1, hasNextPage: items.length > limit || page * perPage < count, }, }; return result; }); }), }); } exports.preparePaginationResolver = preparePaginationResolver; //# sourceMappingURL=pagination.js.map