src/paginate.js
"use strict";
var url = require('url');
module.exports = paginate;
// We want to preserve these query string parameters when paginating.
var queryParamsToKeep = ['per_page', 'embed', 'q'];
function filterQuery(query) {
var filtered = {};
queryParamsToKeep.forEach(function(param) {
if (query[param] !== undefined) {
filtered[param] = query[param];
}
});
return filtered;
}
/**
* Turns page/per_page parameters into mongo-friendly skip/limit parameters.
*
* @param {Object} [options]
* @param {Integer} [options.page=1] Page of results to display
* @param {Integer} [options.per_page=30] Number of results per page
* @return {Object}
*/
function paginate(options) {
options = options || {};
var page = parseInt(options.page, 10) || 1;
var perPage = parseInt(options.per_page, 10) || 30;
if (page < 1 || page > 1000) {
page = 1;
}
if (perPage < 1 || perPage > 200) {
perPage = 30;
}
var skip = (page - 1) * perPage;
var limit = perPage;
function metadata(total, currentUrl) {
var hasMore = (skip + limit) < total;
var body = {
total: total,
page: page,
per_page: perPage,
has_more: hasMore
};
if (currentUrl) {
var parsedUrl = url.parse(currentUrl, true);
delete parsedUrl.search;
parsedUrl.query = filterQuery(parsedUrl.query);
if (hasMore) {
parsedUrl.query.page = (page + 1);
body.next_url = url.format(parsedUrl);
}
if (page > 1) {
parsedUrl.query.page = (page - 1);
body.prev_url = url.format(parsedUrl);
}
}
return body;
}
return {
metadata: metadata,
skip: skip,
limit: limit
};
}