mongoose-paginate-v2
Advanced tools
Comparing version 1.3.52 to 1.4.0
@@ -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; |
154
package.json
{ | ||
"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" | ||
} | ||
} |
248
README.md
![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) |
130
src/index.js
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
287938
17
1051
373
0
28