Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mongoose-paginate-v2

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mongoose-paginate-v2 - npm Package Compare versions

Comparing version 1.3.52 to 1.4.0

.eslintrc.js

20

CODE_OF_CONDUCT.md

@@ -11,15 +11,15 @@ # Contributor Covenant Code of Conduct

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

@@ -26,0 +26,0 @@ ## Our Responsibilities

"use strict";
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -32,2 +36,5 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

* @param {Number} [options.limit=10]
* @param {Boolean} [options.useEstimatedCount=true] - Enable estimatedDocumentCount for larger datasets. As the name says, the count may not abe accurate.
* @param {Function} [options.useCustomCountFn=false] - use custom function for count datasets.
* @param {Object} [options.read={}] - Determines the MongoDB nodes from which to read.
* @param {Function} [callback]

@@ -58,7 +65,11 @@ *

options: {},
pagination: true
pagination: true,
useEstimatedCount: false,
useCustomCountFn: false,
forceCountFn: false,
allowDiskUse: false
};
function paginate(query, options, callback) {
options = _objectSpread({}, defaultOptions, {}, paginate.options, {}, options);
options = _objectSpread(_objectSpread(_objectSpread({}, defaultOptions), paginate.options), options);
query = query || {};

@@ -71,9 +82,19 @@ var _options = options,

projection = _options.projection,
read = _options.read,
select = _options.select,
sort = _options.sort,
pagination = _options.pagination;
pagination = _options.pagination,
useEstimatedCount = _options.useEstimatedCount,
useCustomCountFn = _options.useCustomCountFn,
forceCountFn = _options.forceCountFn,
allowDiskUse = _options.allowDiskUse;
var customLabels = _objectSpread({}, defaultOptions.customLabels, {}, options.customLabels);
var customLabels = _objectSpread(_objectSpread({}, defaultOptions.customLabels), options.customLabels);
var limit = parseInt(options.limit, 10) > 0 ? parseInt(options.limit, 10) : 0;
var limit = defaultOptions.limit;
if (pagination) {
limit = parseInt(options.limit, 10) > 0 ? parseInt(options.limit, 10) : 0;
}
var isCallbackSpecified = typeof callback === 'function';

@@ -84,4 +105,3 @@ var findOptions = options.options;

var skip;
var docsPromise = [];
var docs = []; // Labels
var docsPromise = []; // Labels

@@ -100,7 +120,7 @@ var labelDocs = customLabels.docs;

if (options.hasOwnProperty('offset')) {
if (Object.prototype.hasOwnProperty.call(options, 'offset')) {
offset = parseInt(options.offset, 10);
skip = offset;
} else if (options.hasOwnProperty('page')) {
page = parseInt(options.page, 10);
} else if (Object.prototype.hasOwnProperty.call(options, 'page')) {
page = parseInt(options.page, 10) < 1 ? 1 : parseInt(options.page, 10);
skip = (page - 1) * limit;

@@ -113,10 +133,52 @@ } else {

var countPromise = this.countDocuments(query).exec();
if (!pagination) {
page = 1;
}
var countPromise;
if (forceCountFn === true) {
// Deprecated since starting from MongoDB Node.JS driver v3.1
// Hack for mongo < v3.4
if (Object.keys(collation).length > 0) {
countPromise = this.count(query).collation(collation).exec();
} else {
countPromise = this.count(query).exec();
}
} else {
if (useEstimatedCount === true) {
countPromise = this.estimatedDocumentCount().exec();
} else if (typeof useCustomCountFn === 'function') {
countPromise = useCustomCountFn();
} else {
// Hack for mongo < v3.4
if (Object.keys(collation).length > 0) {
countPromise = this.countDocuments(query).collation(collation).exec();
} else {
countPromise = this.countDocuments(query).exec();
}
}
}
if (limit) {
var mQuery = this.find(query, projection, findOptions);
if (populate) {
mQuery.populate(populate);
}
mQuery.select(select);
mQuery.sort(sort);
mQuery.lean(lean); // Hack for mongo < v3.4
mQuery.lean(lean);
if (read && read.pref) {
/**
* Determines the MongoDB nodes from which to read.
* @param read.pref one of the listed preference options or aliases
* @param read.tags optional tags for this query
*/
mQuery.read(read.pref, read.tags);
} // Hack for mongo < v3.4
if (Object.keys(collation).length > 0) {

@@ -126,6 +188,2 @@ mQuery.collation(collation);

if (populate) {
mQuery.populate(populate);
}
if (pagination) {

@@ -136,2 +194,10 @@ mQuery.skip(skip);

try {
if (allowDiskUse === true) {
mQuery.allowDiskUse();
}
} catch (ex) {
console.error('Your MongoDB version does not support `allowDiskUse`.');
}
docsPromise = mQuery.exec();

@@ -142,3 +208,5 @@

docs.forEach(function (doc) {
doc.id = String(doc._id);
if (doc._id) {
doc.id = String(doc._id);
}
});

@@ -183,4 +251,2 @@ return docs;

meta[labelPrevPage] = page - 1;
} else {
meta[labelPrevPage] = null;
} // Set next page

@@ -192,4 +258,2 @@

meta[labelNextPage] = page + 1;
} else {
meta[labelNextPage] = null;
}

@@ -203,5 +267,5 @@ } // Remove customLabels set to false

meta[labelLimit] = 0;
meta[labelTotalPages] = null;
meta[labelPage] = null;
meta[labelPagingCounter] = null;
meta[labelTotalPages] = 1;
meta[labelPage] = 1;
meta[labelPagingCounter] = 1;
meta[labelPrevPage] = null;

@@ -208,0 +272,0 @@ meta[labelNextPage] = null;

{
"name": "mongoose-paginate-v2",
"version": "1.3.52",
"description": "A cursor based custom pagination library for Mongoose with customizable labels.",
"main": "dist/index.js",
"scripts": {
"pretest": "npm run build",
"test": "./node_modules/.bin/mocha tests/*.js -R spec --ui bdd --timeout 9999999",
"build": "babel src -d dist",
"prepublish": "npm run test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/aravindnc/mongoose-paginate-v2.git"
},
"keywords": [
"mongoose",
"pagination",
"plugin",
"mongodb",
"paginate",
"paging",
"next",
"prev",
"nextpage",
"prevpage",
"total",
"paginator",
"plugin"
],
"author": "Aravind NC <aravind_n_c@yahoo.co.in> (https://aravindnc.com)",
"contributors": [
"Fernando López Guevara (fernando.lguevara@gmail.com)"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/aravindnc/mongoose-paginate-v2/issues"
},
"homepage": "https://github.com/aravindnc/mongoose-paginate-v2#readme",
"dependencies": {},
"devDependencies": {
"@babel/cli": "^7.4.3",
"@babel/core": "^7.4.3",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.3.1",
"chai": "^4.2.0",
"mocha": "^6.0.1",
"mongoose": "^5.2.4"
},
"engines": {
"node": ">=4.0.0"
}
"name": "mongoose-paginate-v2",
"version": "1.4.0",
"description": "A cursor based custom pagination library for Mongoose with customizable labels.",
"main": "dist/index.js",
"scripts": {
"pretest": "npm run build",
"test": "./node_modules/.bin/mocha tests/*.js -R spec --ui bdd --timeout 9999999",
"build": "babel src -d dist",
"lint": "./node_modules/.bin/eslint \"tests\" \"src\" \".eslintrc.js\" --fix",
"prettier": "./node_modules/.bin/prettier --write \"{src,tests}/**/*.js\" \"*.md\"",
"prepublish": "npm run test"
},
"husky": {
"hooks": {
"pre-commit": "./node_modules/.bin/lint-staged"
}
},
"lint-staged": {
"*.js": [
"./node_modules/.bin/eslint --fix",
"./node_modules/.bin/prettier --write"
],
"*.md": [
"./node_modules/.bin/prettier --write"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/aravindnc/mongoose-paginate-v2.git"
},
"keywords": [
"mongoose",
"pagination",
"plugin",
"mongodb",
"paginate",
"paging",
"next",
"prev",
"nextpage",
"prevpage",
"total",
"paginator",
"plugin"
],
"author": "Aravind NC <aravind_n_c@yahoo.co.in> (https://aravindnc.com)",
"contributors": [
"Fernando López Guevara (fernando.lguevara@gmail.com)"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/aravindnc/mongoose-paginate-v2/issues"
},
"homepage": "https://github.com/aravindnc/mongoose-paginate-v2#readme",
"dependencies": {},
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-decorators": "^7.14.5",
"@babel/plugin-proposal-do-expressions": "^7.14.5",
"@babel/plugin-proposal-export-default-from": "^7.14.5",
"@babel/plugin-proposal-export-namespace-from": "^7.14.5",
"@babel/plugin-proposal-function-bind": "^7.14.5",
"@babel/plugin-proposal-function-sent": "^7.14.5",
"@babel/plugin-proposal-json-strings": "^7.14.5",
"@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
"@babel/plugin-proposal-numeric-separator": "^7.14.5",
"@babel/plugin-proposal-optional-chaining": "^7.14.5",
"@babel/plugin-proposal-pipeline-operator": "^7.14.5",
"@babel/plugin-proposal-throw-expressions": "^7.14.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/preset-env": "^7.14.7",
"babel-eslint": "^10.1.0",
"chai": "^4.3.4",
"eslint": "^7.30.0",
"eslint-config-prettier": "^6.15.0",
"husky": "^4.3.8",
"lint-staged": "^10.5.4",
"mocha": "^8.4.0",
"mongoose": "^5.13.2",
"prettier": "^2.3.2"
},
"engines": {
"node": ">=4.0.0"
}
}
![Banner](static/banner.jpg)
# mongoose-paginate-v2
[![npm version](https://img.shields.io/npm/v/mongoose-paginate-v2.svg)](https://www.npmjs.com/package/mongoose-paginate-v2)
[![Dependency Status](https://david-dm.org/aravindnc/mongoose-paginate-v2.svg)](https://david-dm.org/aravindnc/mongoose-paginate-v2)
[![devDependency Status](https://david-dm.org/aravindnc/mongoose-paginate-v2/dev-status.svg)](https://david-dm.org/aravindnc/mongoose-paginate-v2#info=devDependencies)
[![Build Status](https://travis-ci.com/aravindnc/mongoose-paginate-v2.svg?branch=master)](https://travis-ci.com/aravindnc/mongoose-paginate-v2)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/aravindnc/mongoose-paginate-v2/issues)
[![Downloads](https://img.shields.io/npm/dm/mongoose-paginate-v2.svg)](https://img.shields.io/npm/dm/mongoose-paginate-v2.svg)
[![HitCount](http://hits.dwyl.io/aravindnc/mongoose-paginate-v2.svg)](http://hits.dwyl.io/aravindnc/mongoose-paginate-v2)

@@ -17,2 +16,8 @@ > A cursor based custom pagination library for [Mongoose](http://mongoosejs.com) with customizable labels.

## Why This Plugin
mongoose-paginate-v2 is a cursor based pagination library having a page wrapper. The plugin can be used as both page as well as cursor based pagination. The main usage of the plugin is you can alter the return value keys directly in the query itself so that you don't need any extra code for transformation. The initial idea of this plugin is loosely based on mongoose-paginate package by github.com/edwardhotchkiss/. So this can be considered as an upgraded version of mongoose-paginate with much more options.
The below documentation is not perfect. Feel free to contribute. :)
## Installation

@@ -29,7 +34,7 @@

```js
const mongoose = require('mongoose');
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const mySchema = new mongoose.Schema({
/* your schema definition */
const mySchema = new mongoose.Schema({
/* your schema definition */
});

@@ -39,5 +44,5 @@

const myModel = mongoose.model('SampleModel', mySchema);
const myModel = mongoose.model('SampleModel', mySchema);
myModel.paginate().then({}) // Usage
myModel.paginate().then({}); // Usage
```

@@ -51,9 +56,10 @@

* `[query]` {Object} - Query criteria. [Documentation](https://docs.mongodb.org/manual/tutorial/query-documents)
* `[options]` {Object}
- `[select]` {Object | String} - Fields to return (by default returns all fields). [Documentation](http://mongoosejs.com/docs/api.html#query_Query-select)
- `[query]` {Object} - Query criteria. [Documentation](https://docs.mongodb.org/manual/tutorial/query-documents)
- `[options]` {Object}
- `[select]` {Object | String} - Fields to return (by default returns all fields). [Documentation](http://mongoosejs.com/docs/api.html#query_Query-select)
- `[collation]` {Object} - Specify the collation [Documentation](https://docs.mongodb.com/manual/reference/collation/)
- `[sort]` {Object | String} - Sort order. [Documentation](http://mongoosejs.com/docs/api.html#query_Query-sort)
- `[sort]` {Object | String} - Sort order. [Documentation](http://mongoosejs.com/docs/api.html#query_Query-sort)
- `[populate]` {Array | Object | String} - Paths which should be populated with other documents. [Documentation](http://mongoosejs.com/docs/api.html#query_Query-populate)
- `[lean=false]` {Boolean} - Should return plain javascript objects instead of Mongoose documents? [Documentation](http://mongoosejs.com/docs/api.html#query_Query-lean)
- `[projection]` {String | Object} - Get/set the query projection. [Documentation](https://mongoosejs.com/docs/api/query.html#query_Query-projection)
- `[lean=false]` {Boolean} - Should return plain javascript objects instead of Mongoose documents? [Documentation](http://mongoosejs.com/docs/api.html#query_Query-lean)
- `[leanWithId=true]` {Boolean} - If `lean` and `leanWithId` are `true`, adds `id` field with string representation of `_id` to every document

@@ -65,3 +71,11 @@ - `[offset=0]` {Number} - Use `offset` or `page` to set skip position

- `[pagination]` {Boolean} - If `pagination` is set to false, it will return all docs without adding limit condition. (Default: True)
* `[callback(err, result)]` - If specified the callback is called once pagination results are retrieved or when an error has occurred
- `[useEstimatedCount]` - Enable [estimatedDocumentCount](https://docs.mongodb.com/manual/reference/method/db.collection.estimatedDocumentCount/) for larger datasets. Does not count based on given query, so the count will match entire collection size. (Default: False)
- `[useCustomCountFn]` - Enable custom function for count datasets. (Default: False)
- `[forceCountFn]` {Boolean} - Set this to true, if you need to support \$geo queries. (Default: False)
- `[allowDiskUse]` {Boolean} - Set this to true, which allows the MongoDB server to use more than 100 MB for query. This option can let you work around QueryExceededMemoryLimitNoDiskUseAllowed errors from the MongoDB server. (Default: False)
- `[read]` {Object} - Determines the MongoDB nodes from which to read. Below are the available options.
- `[pref]`: One of the listed preference options or aliases.
- `[tags]`: Optional tags for this query. (Must be used with `[pref]`)
- `[options]` {Object} - Options passed to Mongoose's `find()` function. [Documentation](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
- `[callback(err, result)]` - If specified, the callback is called once pagination results are retrieved or when an error has occurred

@@ -72,24 +86,17 @@ **Return value**

* `docs` {Array} - Array of documents
* `totalDocs` {Number} - Total number of documents in collection that match a query
* `limit` {Number} - Limit that was used
* `hasPrevPage` {Bool} - Availability of prev page.
* `hasNextPage` {Bool} - Availability of next page.
* `page` {Number} - Current page number
* `totalPages` {Number} - Total number of pages.
* `offset` {Number} - Only if specified or default `page`/`offset` values were used
* `prevPage` {Number} - Previous page number if available or NULL
* `nextPage` {Number} - Next page number if available or NULL
* `pagingCounter` {Number} - The starting sl. number of first document.
* `meta` {Object} - Object of pagination meta data (Default false).
- `docs` {Array} - Array of documents
- `totalDocs` {Number} - Total number of documents in collection that match a query
- `limit` {Number} - Limit that was used
- `hasPrevPage` {Bool} - Availability of prev page.
- `hasNextPage` {Bool} - Availability of next page.
- `page` {Number} - Current page number
- `totalPages` {Number} - Total number of pages.
- `offset` {Number} - Only if specified or default `page`/`offset` values were used
- `prevPage` {Number} - Previous page number if available or NULL
- `nextPage` {Number} - Next page number if available or NULL
- `pagingCounter` {Number} - The starting index/serial/chronological number of first document in current page. (Eg: if page=2 and limit=10, then pagingCounter will be 11)
- `meta` {Object} - Object of pagination meta data (Default false).
Please note that the above properties can be renamed by setting customLabel attribute.
Please note that the above properties can be renamed by setting customLabels attribute.
### Note
There are few operators that this plugin does not support, below are the list and suggested replacements
* $where: $expr
* $near: $geoWithin with $center
* $nearSphere: $geoWithin with $centerSphere
### Sample Usage

@@ -104,7 +111,7 @@

collation: {
locale: 'en'
}
locale: 'en',
},
};
Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.docs

@@ -114,3 +121,3 @@ // result.totalDocs = 100

// result.page = 1
// result.totalPages = 10
// result.totalPages = 10
// result.hasNextPage = true

@@ -128,13 +135,13 @@ // result.nextPage = 2

* totalDocs
* docs
* limit
* page
* nextPage
* prevPage
* hasNextPage
* hasPrevPage
* totalPages
* pagingCounter
* meta
- totalDocs
- docs
- limit
- page
- nextPage
- prevPage
- hasNextPage
- hasPrevPage
- totalPages
- pagingCounter
- meta

@@ -155,3 +162,3 @@ You should pass the names of the properties you wish to changes using `customLabels` object in options.

pagingCounter: 'slNo',
meta: 'paginator'
meta: 'paginator',
};

@@ -162,6 +169,6 @@

limit: 10,
customLabels: myCustomLabels
customLabels: myCustomLabels,
};
Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.itemsList [here docs become itemsList]

@@ -185,3 +192,3 @@ // result.paginator.itemCount = 100 [here totalDocs becomes itemCount]

```javascript
Model.paginate({}, { offset: 30, limit: 10 }, function(err, result) {
Model.paginate({}, { offset: 30, limit: 10 }, function (err, result) {
// result.docs

@@ -197,3 +204,3 @@ // result.totalPages

```js
Model.paginate({}, { offset: 30, limit: 10 }).then(function(result) {
Model.paginate({}, { offset: 30, limit: 10 }).then(function (result) {
// ...

@@ -206,13 +213,13 @@ });

```javascript
var query = {};
var query = {};
var options = {
select: 'title date author',
sort: { date: -1 },
select: 'title date author',
sort: { date: -1 },
populate: 'author',
lean: true,
offset: 20,
limit: 10
lean: true,
offset: 20,
limit: 10,
};
Book.paginate(query, options).then(function(result) {
Book.paginate(query, options).then(function (result) {
// ...

@@ -227,6 +234,6 @@ });

```javascript
Model.paginate({}, { limit: 0 }).then(function(result) {
Model.paginate({}, { limit: 0 }).then(function (result) {
// result.docs - empty array
// result.totalDocs
// result.limit - 0
// result.limit - 0
});

@@ -242,5 +249,5 @@ ```

mongoosePaginate.paginate.options = {
lean: true,
limit: 20
mongoosePaginate.paginate.options = {
lean: true,
limit: 20,
};

@@ -252,3 +259,3 @@ ```

```javascript
Model.paginate().then(function(result) {
Model.paginate().then(function (result) {
// result.docs - array of plain javascript objects

@@ -259,3 +266,4 @@ // result.limit - 20

#### Fetch all docs without pagination.
#### Fetch all docs without pagination
If you need to fetch all the documents in the collection without applying a limit. Then set `pagination` as false,

@@ -265,6 +273,6 @@

const options = {
pagination: false
pagination: false,
};
Model.paginate({}, options, function(err, result) {
Model.paginate({}, options, function (err, result) {
// result.docs

@@ -274,3 +282,3 @@ // result.totalDocs = 100

// result.page = 1
// result.totalPages = 1
// result.totalPages = 1
// result.hasNextPage = false

@@ -284,4 +292,102 @@ // result.nextPage = null

#### Using custom count function
If you need to use your own custom count function, then set `useCustomCountFn` as your custom count function. Make sure the function is returning count as a **promise**.
```javascript
const options = {
useCustomCountFn: function () {
return Promise.resolve(100);
},
};
Model.paginate({}, options, function (err, result) {
// result.docs
});
```
#### Setting read preference
Determines the MongoDB nodes from which to read.
```js
const options = {
lean: true,
limit: 10,
page: 1,
read: {
pref: 'secondary',
tags: [
{
region: 'South',
},
],
},
};
Model.paginate({}, options, function (err, result) {
// Result
});
```
#### AllowDiskUse for large datasets
Sets the allowDiskUse option, which allows the MongoDB server to use more than 100 MB for query. This option can let you work around `QueryExceededMemoryLimitNoDiskUseAllowed` errors from the MongoDB server.
**Note that this option requires MongoDB server >= 4.4. Setting this option is a no-op for MongoDB 4.2 and earlier.**
```js
const options = {
limit: 10,
page: 1,
allowDiskUse: true,
};
Model.paginate({}, options, function (err, result) {
// Result
});
```
Below are some references to understand more about preferences,
- https://github.com/Automattic/mongoose/blob/master/lib/query.js#L1008
- https://docs.mongodb.com/manual/core/read-preference/
- http://mongodb.github.io/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences
## Note
There are few operators that this plugin does not support natively, below are the list and suggested replacements,
- $where: $expr
- $near: $geoWithin with \$center
- $nearSphere: $geoWithin with \$centerSphere
But we have added another option. So if you need to use $near and $nearSphere please set `forceCountFn` as true and try running the query.
```js
const options = {
lean: true,
limit: 10,
page: 1,
forceCountFn: true,
};
Model.paginate({}, options, function (err, result) {
// Result
});
```
## Development
- Ensure all tests pass before you commit by running `npm run test`
- There are pre-commit hooks that run to ensure the _files you've changed_ are formatted correctly.
- Optionally you can manually run `npm run lint && npm run prettier` to lint and format every relevant file
- If using VS Code, install eslint and prettier for easy editor integration.
## Changelog
[View Changelog](CHANGELOG.md)
## License
[MIT](LICENSE)

@@ -16,2 +16,5 @@ /**

* @param {Number} [options.limit=10]
* @param {Boolean} [options.useEstimatedCount=true] - Enable estimatedDocumentCount for larger datasets. As the name says, the count may not abe accurate.
* @param {Function} [options.useCustomCountFn=false] - use custom function for count datasets.
* @param {Object} [options.read={}] - Determines the MongoDB nodes from which to read.
* @param {Function} [callback]

@@ -43,3 +46,7 @@ *

options: {},
pagination: true
pagination: true,
useEstimatedCount: false,
useCustomCountFn: false,
forceCountFn: false,
allowDiskUse: false,
};

@@ -51,3 +58,3 @@

...paginate.options,
...options
...options,
};

@@ -62,5 +69,10 @@ query = query || {};

projection,
read,
select,
sort,
pagination
pagination,
useEstimatedCount,
useCustomCountFn,
forceCountFn,
allowDiskUse,
} = options;

@@ -70,7 +82,11 @@

...defaultOptions.customLabels,
...options.customLabels
...options.customLabels,
};
const limit = parseInt(options.limit, 10) > 0 ? parseInt(options.limit, 10) : 0;
let limit = defaultOptions.limit;
if (pagination) {
limit = parseInt(options.limit, 10) > 0 ? parseInt(options.limit, 10) : 0;
}
const isCallbackSpecified = typeof callback === 'function';

@@ -84,3 +100,2 @@ const findOptions = options.options;

let docsPromise = [];
let docs = [];

@@ -100,7 +115,7 @@ // Labels

if (options.hasOwnProperty('offset')) {
if (Object.prototype.hasOwnProperty.call(options, 'offset')) {
offset = parseInt(options.offset, 10);
skip = offset;
} else if (options.hasOwnProperty('page')) {
page = parseInt(options.page, 10);
} else if (Object.prototype.hasOwnProperty.call(options, 'page')) {
page = parseInt(options.page, 10) < 1 ? 1 : parseInt(options.page, 10);
skip = (page - 1) * limit;

@@ -113,6 +128,39 @@ } else {

const countPromise = this.countDocuments(query).exec();
if (!pagination) {
page = 1;
}
let countPromise;
if (forceCountFn === true) {
// Deprecated since starting from MongoDB Node.JS driver v3.1
// Hack for mongo < v3.4
if (Object.keys(collation).length > 0) {
countPromise = this.count(query).collation(collation).exec();
} else {
countPromise = this.count(query).exec();
}
} else {
if (useEstimatedCount === true) {
countPromise = this.estimatedDocumentCount().exec();
} else if (typeof useCustomCountFn === 'function') {
countPromise = useCustomCountFn();
} else {
// Hack for mongo < v3.4
if (Object.keys(collation).length > 0) {
countPromise = this.countDocuments(query).collation(collation).exec();
} else {
countPromise = this.countDocuments(query).exec();
}
}
}
if (limit) {
const mQuery = this.find(query, projection, findOptions);
if (populate) {
mQuery.populate(populate);
}
mQuery.select(select);

@@ -122,2 +170,11 @@ mQuery.sort(sort);

if (read && read.pref) {
/**
* Determines the MongoDB nodes from which to read.
* @param read.pref one of the listed preference options or aliases
* @param read.tags optional tags for this query
*/
mQuery.read(read.pref, read.tags);
}
// Hack for mongo < v3.4

@@ -128,6 +185,2 @@ if (Object.keys(collation).length > 0) {

if (populate) {
mQuery.populate(populate);
}
if (pagination) {

@@ -138,2 +191,10 @@ mQuery.skip(skip);

try {
if (allowDiskUse === true) {
mQuery.allowDiskUse();
}
} catch (ex) {
console.error('Your MongoDB version does not support `allowDiskUse`.');
}
docsPromise = mQuery.exec();

@@ -144,3 +205,5 @@

docs.forEach((doc) => {
doc.id = String(doc._id);
if (doc._id) {
doc.id = String(doc._id);
}
});

@@ -150,3 +213,2 @@ return docs;

}
}

@@ -156,6 +218,5 @@

.then((values) => {
const [count, docs] = values;
const meta = {
[labelTotal]: count
[labelTotal]: count,
};

@@ -170,3 +231,3 @@

const pages = (limit > 0) ? (Math.ceil(count / limit) || 1) : null;
const pages = limit > 0 ? Math.ceil(count / limit) || 1 : null;

@@ -177,3 +238,3 @@ // Setting default values

meta[labelPage] = page;
meta[labelPagingCounter] = ((page - 1) * limit) + 1;
meta[labelPagingCounter] = (page - 1) * limit + 1;

@@ -186,3 +247,2 @@ meta[labelHasPrevPage] = false;

if (pagination) {
meta[labelLimit] = limit;

@@ -194,5 +254,3 @@ meta[labelTotalPages] = pages;

meta[labelHasPrevPage] = true;
meta[labelPrevPage] = (page - 1);
} else {
meta[labelPrevPage] = null;
meta[labelPrevPage] = page - 1;
}

@@ -203,7 +261,4 @@

meta[labelHasNextPage] = true;
meta[labelNextPage] = (page + 1);
} else {
meta[labelNextPage] = null;
meta[labelNextPage] = page + 1;
}
}

@@ -216,5 +271,5 @@

meta[labelLimit] = 0;
meta[labelTotalPages] = null;
meta[labelPage] = null;
meta[labelPagingCounter] = null;
meta[labelTotalPages] = 1;
meta[labelPage] = 1;
meta[labelPagingCounter] = 1;
meta[labelPrevPage] = null;

@@ -229,3 +284,3 @@ meta[labelNextPage] = null;

[labelDocs]: docs,
[labelMeta]: meta
[labelMeta]: meta,
};

@@ -235,8 +290,11 @@ } else {

[labelDocs]: docs,
...meta
...meta,
};
}
return isCallbackSpecified ? callback(null, result) : Promise.resolve(result);
}).catch((error) => {
return isCallbackSpecified
? callback(null, result)
: Promise.resolve(result);
})
.catch((error) => {
return isCallbackSpecified ? callback(error) : Promise.reject(error);

@@ -253,2 +311,2 @@ });

module.exports.paginate = paginate;
module.exports.paginate = paginate;

@@ -5,2 +5,3 @@ 'use strict';

let expect = require('chai').expect;
let assert = require('chai').assert;
let mongoosePaginate = require('../dist/index');

@@ -11,3 +12,3 @@

let AuthorSchema = new mongoose.Schema({
name: String
name: String,
});

@@ -22,9 +23,9 @@ let Author = mongoose.model('Author', AuthorSchema);

type: mongoose.Schema.ObjectId,
ref: 'Author'
ref: 'Author',
},
loc: Object
loc: Object,
});
BookSchema.index({
loc: "2dsphere"
loc: '2dsphere',
});

@@ -37,7 +38,11 @@

describe('mongoose-paginate', function () {
before(function (done) {
mongoose.connect(MONGO_URI, {
useNewUrlParser: true
}, done);
mongoose.connect(
MONGO_URI,
{
useUnifiedTopology: true,
useNewUrlParser: true,
},
done
);
});

@@ -50,7 +55,8 @@

before(function () {
let book, books = [];
let book,
books = [];
let date = new Date();
return Author.create({
name: 'Arthur Conan Doyle'
name: 'Arthur Conan Doyle',
}).then(function (author) {

@@ -60,3 +66,3 @@ for (let i = 1; i <= 100; i++) {

// price: Math.floor(Math.random() * (1000 - 50) ) + 50,
price: (i * 5) + i,
price: i * 5 + i,
title: 'Book #' + i,

@@ -66,4 +72,4 @@ date: new Date(date.getTime() + i),

loc: {
type: "Point",
coordinates: [-10.97, 20.77]
type: 'Point',
coordinates: [-10.97, 20.77],
},

@@ -76,11 +82,7 @@ });

});
});
afterEach(function () {
afterEach(function () {});
});
it('promise return test', function () {
let promise = Book.paginate();

@@ -101,4 +103,4 @@ expect(promise.then).to.be.an.instanceof(Function);

title: {
$in: [/Book/i]
}
$in: [/Book/i],
},
};

@@ -109,3 +111,3 @@

page: 5,
lean: true
lean: true,
};

@@ -127,7 +129,88 @@

it('first page with page and limit, limit > doc.length', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
limit: 200,
page: 1,
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(100);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(200);
expect(result.page).to.equal(1);
expect(result.pagingCounter).to.equal(1);
expect(result.hasPrevPage).to.equal(false);
expect(result.hasNextPage).to.equal(false);
expect(result.prevPage).to.equal(null);
expect(result.nextPage).to.equal(null);
expect(result.totalPages).to.equal(1);
});
});
it('first page with page and limit', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
limit: 10,
page: 1,
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(10);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(10);
expect(result.page).to.equal(1);
expect(result.pagingCounter).to.equal(1);
expect(result.hasPrevPage).to.equal(false);
expect(result.hasNextPage).to.equal(true);
expect(result.prevPage).to.equal(null);
expect(result.nextPage).to.equal(2);
expect(result.totalPages).to.equal(10);
});
});
it('last page with page and limit', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
limit: 10,
page: 10,
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(10);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(10);
expect(result.page).to.equal(10);
expect(result.pagingCounter).to.equal(91);
expect(result.hasPrevPage).to.equal(true);
expect(result.hasNextPage).to.equal(false);
expect(result.prevPage).to.equal(9);
expect(result.nextPage).to.equal(null);
expect(result.totalPages).to.equal(10);
});
});
it('with offset and limit (not page)', function () {
var query = {
title: {
$in: [/Book/i]
}
$in: [/Book/i],
},
};

@@ -139,9 +222,8 @@

sort: {
_id: 1
_id: 1,
},
lean: true
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(2);

@@ -160,7 +242,37 @@ expect(result.totalDocs).to.equal(100);

it('with offset and limit (not page) condition: offset > 0 < limit', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
limit: 10,
offset: 5,
sort: {
_id: 1,
},
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(10);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(10);
expect(result.page).to.equal(1);
expect(result.pagingCounter).to.equal(1);
expect(result.hasPrevPage).to.equal(false);
expect(result.hasNextPage).to.equal(true);
expect(result.prevPage).to.equal(null);
expect(result.nextPage).to.equal(2);
expect(result.totalPages).to.equal(10);
});
});
it('with limit=0 (metadata only)', function () {
var query = {
title: {
$in: [/Book #1/i]
}
$in: [/Book #1/i],
},
};

@@ -171,18 +283,17 @@

sort: {
_id: 1
_id: 1,
},
collation: {
locale: 'en',
strength: 2
strength: 2,
},
lean: true
lean: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(0);
expect(result.totalDocs).to.equal(12);
expect(result.limit).to.equal(0);
expect(result.page).to.equal(null);
expect(result.pagingCounter).to.equal(null);
expect(result.page).to.equal(1);
expect(result.pagingCounter).to.equal(1);
expect(result.hasPrevPage).to.equal(false);

@@ -192,3 +303,3 @@ expect(result.hasNextPage).to.equal(false);

expect(result.nextPage).to.equal(null);
expect(result.totalPages).to.equal(null);
expect(result.totalPages).to.equal(1);
});

@@ -229,4 +340,4 @@ });

title: {
$in: [/Book/i]
}
$in: [/Book/i],
},
};

@@ -241,3 +352,3 @@

sort: {
_id: 1
_id: 1,
},

@@ -248,8 +359,7 @@ limit: 10,

title: 1,
price: 1
price: 1,
},
customLabels: myCustomLabels
customLabels: myCustomLabels,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(10);

@@ -272,4 +382,4 @@ expect(result.docs[0].title).to.equal('Book #41');

title: {
$in: [/Book/i]
}
$in: [/Book/i],
},
};

@@ -287,3 +397,3 @@

hasPrevPage: 'hasPrevious',
hasNextPage: 'hasNext'
hasNextPage: 'hasNext',
};

@@ -293,3 +403,3 @@

sort: {
_id: 1
_id: 1,
},

@@ -300,5 +410,5 @@ limit: 10,

title: 1,
price: 1
price: 1,
},
customLabels: myCustomLabels
customLabels: myCustomLabels,
};

@@ -323,4 +433,4 @@ return Book.paginate(query, options).then((result) => {

title: {
$in: [/Book/i]
}
$in: [/Book/i],
},
};

@@ -331,3 +441,3 @@

docs: 'itemsList',
totalDocs: 'total'
totalDocs: 'total',
};

@@ -337,3 +447,3 @@

sort: {
_id: 1
_id: 1,
},

@@ -344,5 +454,5 @@ limit: 10,

title: 1,
price: 1
price: 1,
},
customLabels: myCustomLabels
customLabels: myCustomLabels,
};

@@ -360,8 +470,4 @@ return Book.paginate(query, options).then((result) => {

loc: {
$geoWithin: {
$center: [
[-10, 20], 999
]
}
}
$nearSphere: [50, 50],
},
};

@@ -372,3 +478,3 @@

docs: 'itemsList',
totalDocs: 'total'
totalDocs: 'total',
};

@@ -378,3 +484,3 @@

sort: {
_id: 1
_id: 1,
},

@@ -385,5 +491,6 @@ limit: 10,

title: 1,
price: 1
price: 1,
},
customLabels: myCustomLabels
forceCountFn: true,
customLabels: myCustomLabels,
};

@@ -398,8 +505,80 @@ return Book.paginate(query, options).then((result) => {

title: {
$in: [/Book/i]
$in: [/Book/i],
},
};
var options = {
pagination: false,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(100);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(100);
expect(result.page).to.equal(1);
expect(result.pagingCounter).to.equal(1);
expect(result.hasPrevPage).to.equal(false);
expect(result.hasNextPage).to.equal(false);
expect(result.prevPage).to.equal(null);
expect(result.nextPage).to.equal(null);
expect(result.totalPages).to.equal(1);
});
});
it('estimated count works', function (done) {
Book.paginate({}, { useEstimatedCount: true }, function (err, result) {
expect(err).to.be.null;
expect(result).to.be.an.instanceOf(Object);
assert.isNumber(result.totalDocs, 'totalDocs is a number');
done();
});
});
it('count Custom Fn works', function (done) {
Book.paginate(
{},
{
useCustomCountFn: function () {
return 100;
},
},
function (err, result) {
expect(err).to.be.null;
expect(result).to.be.an.instanceOf(Object);
assert.isNumber(result.totalDocs, 'totalDocs is a number');
expect(result.totalDocs).to.equal(100);
done();
}
);
});
it('count Custom Fn with Promise return works', function (done) {
Book.paginate(
{},
{
useCustomCountFn: function () {
return Promise.resolve(100);
},
},
function (err, result) {
expect(err).to.be.null;
expect(result).to.be.an.instanceOf(Object);
assert.isNumber(result.totalDocs, 'totalDocs is a number');
expect(result.totalDocs).to.equal(100);
done();
}
);
});
it('pagination=false, limit/page=undefined -> return all docs', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
pagination: false
pagination: false,
page: undefined,
limit: undefined,
};

@@ -418,3 +597,30 @@

expect(result.totalPages).to.equal(1);
});
});
it('with allowDiskUse=true', function () {
var query = {
title: {
$in: [/Book/i],
},
};
var options = {
limit: 10,
page: 5,
lean: true,
allowDiskUse: true,
};
return Book.paginate(query, options).then((result) => {
expect(result.docs).to.have.length(10);
expect(result.totalDocs).to.equal(100);
expect(result.limit).to.equal(10);
expect(result.page).to.equal(5);
expect(result.pagingCounter).to.equal(41);
expect(result.hasPrevPage).to.equal(true);
expect(result.hasNextPage).to.equal(true);
expect(result.prevPage).to.equal(4);
expect(result.nextPage).to.equal(6);
expect(result.totalPages).to.equal(10);
});

@@ -430,3 +636,2 @@ });

});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc