UNPKG

loopback-graphql-relay

Version:

Add Relay based Apollo Server or GraphQL queries on your Loopback server

87 lines (69 loc) 1.98 kB
const _ = require('lodash'); const utils = require('./utils'); /** * Inspired by https://www.reindex.io/blog/relay-graphql-pagination-with-mongodb/ */ function sortFilter(filter, order, before, idName) { const end = utils.getId(before); const idSort = idName + (end ? ' DESC' : ' ASC'); if (!order) { filter.order = idSort; } else { filter.order = _.concat(order, idSort); } } function limitFilter(model, filter, before, after, order, idName) { let begin = after; let end = before; if (model.definition.settings['loopback-graphql-relay'] && model.definition.settings['loopback-graphql-relay'].idField) { idName = model.definition.settings['loopback-graphql-relay'].idField; } else { begin = utils.getId(after); end = utils.getId(before); } if (begin) { filter.where[idName] = filter[idName] || {}; filter.where[idName].gt = begin; } if (end) { filter.where[idName] = filter[idName] || {}; filter.where[idName].lt = end; } } function applyPagination(filter, first, last, count) { if (first || last) { let limit; let skip; if (first && count > first) { limit = first; } if (last) { if (limit && limit > last) { skip = limit - last; limit -= skip; } else if (!limit && count > last) { skip = count - last; } } if (skip) { filter.skip = skip; } if (limit) { filter.limit = limit; } } return { hasNextPage: Boolean(first && count > first), hasPreviousPage: Boolean(last && count > last), }; } module.exports = function buildFilter(model, args) { const idName = (model.getIdName && model.getIdName()) ? model.getIdName() : 'id'; const filter = { where: args.where || {}, }; sortFilter(filter, args.order, args.before, idName); limitFilter(model, filter, args.before, args.after, null, idName); applyPagination(filter, args.first, args.last, args.count); return filter; };