Skip to content

Commit ed55335

Browse files
committed
Added initial version.
1 parent 3bbbb1b commit ed55335

File tree

5 files changed

+143
-42
lines changed

5 files changed

+143
-42
lines changed

.babelrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": [
3+
"es2015",
4+
"stage-0"
5+
]
6+
}

.gitignore

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,18 @@
22
logs
33
*.log
44
npm-debug.log*
5-
yarn-debug.log*
6-
yarn-error.log*
75

86
# Runtime data
97
pids
108
*.pid
119
*.seed
1210
*.pid.lock
1311

14-
# Directory for instrumented libs generated by jscoverage/JSCover
15-
lib-cov
16-
17-
# Coverage directory used by tools like istanbul
18-
coverage
19-
20-
# nyc test coverage
21-
.nyc_output
22-
23-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24-
.grunt
25-
26-
# Bower dependency directory (https://bower.io/)
27-
bower_components
28-
29-
# node-waf configuration
30-
.lock-wscript
31-
32-
# Compiled binary addons (http://nodejs.org/api/addons.html)
33-
build/Release
34-
3512
# Dependency directories
3613
node_modules/
37-
jspm_packages/
38-
39-
# Typescript v1 declaration files
40-
typings/
41-
42-
# Optional npm cache directory
43-
.npm
44-
45-
# Optional eslint cache
46-
.eslintcache
47-
48-
# Optional REPL history
49-
.node_repl_history
50-
51-
# Output of 'npm pack'
52-
*.tgz
53-
54-
# Yarn Integrity file
55-
.yarn-integrity
5614

5715
# dotenv environment variables file
5816
.env
5917

18+
# Output directories
19+
lib/

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: node_js
2+
3+
node_js:
4+
- "4"
5+
- "5"
6+
- "6"
7+
8+
services:
9+
- mongodb

package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "mongoose-cursor-pagination",
3+
"version": "0.1.0",
4+
"description": "Mongoose cursor-based pagination.",
5+
"main": "lib/index.js",
6+
"files": [
7+
"lib"
8+
],
9+
"scripts": {
10+
"build": "babel src --out-dir lib",
11+
"test": "standard"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/enkidevs/mongoose-cursor-pagination.git"
16+
},
17+
"keywords": [
18+
"mongoose",
19+
"paginate",
20+
"pagination",
21+
"cursor",
22+
"mongodb",
23+
"javascript"
24+
],
25+
"author": "Pedro da Rocha Pinto <[email protected]>",
26+
"license": "MIT",
27+
"bugs": {
28+
"url": "https://github.com/enkidevs/mongoose-cursor-pagination/issues"
29+
},
30+
"homepage": "https://github.com/enkidevs/mongoose-cursor-pagination",
31+
"devDependencies": {
32+
"babel-cli": "^6.26.0",
33+
"babel-preset-es2015": "^6.24.1",
34+
"babel-preset-stage-0": "^6.24.1",
35+
"mongoose": "^4.12.3",
36+
"standard": "*"
37+
}
38+
}

src/index.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
export default function paginationPlugin (schema, pluginOptions) {
2+
pluginOptions = pluginOptions || {}
3+
4+
const minLimit = +pluginOptions.minLimit || 1
5+
const maxLimit = +pluginOptions.maxLimit || 100
6+
7+
const defaultOptions = {
8+
key: pluginOptions.key || '_id',
9+
lean: pluginOptions.lean || false,
10+
limit: +pluginOptions.limit || 20,
11+
sort: {}
12+
}
13+
14+
schema.statics.paginate = function (query, options, callback) {
15+
query = query || {}
16+
options = options || {}
17+
options.limit = +options.limit || defaultOptions.limit
18+
options = { ...defaultOptions, ...options }
19+
20+
if (options.limit > maxLimit || options.limit < minLimit) {
21+
options.limit = defaultOptions.limit
22+
}
23+
24+
const { key, select, populate, lean, limit, sort } = options
25+
let reverse = false
26+
27+
if (options.startingAfter || options.endingBefore) {
28+
query[key] = {}
29+
30+
if (options.endingBefore) {
31+
query[key] = { $lt: options.endingBefore }
32+
33+
if (sort[key] > 0) {
34+
sort[key] = -1
35+
reverse = true
36+
}
37+
} else {
38+
query[key] = { $gt: options.startingAfter }
39+
40+
if (sort[key] <= 0) {
41+
sort[key] = 1
42+
reverse = true
43+
}
44+
}
45+
}
46+
47+
const promise = this.find()
48+
.where(query)
49+
.select(select)
50+
.sort(sort)
51+
.limit(limit + 1)
52+
.lean(lean)
53+
54+
if (populate) {
55+
[].concat(populate).forEach(item => promise.populate(item))
56+
}
57+
58+
return new Promise((resolve, reject) => promise.exec((error, items) => {
59+
if (error) {
60+
if (typeof callback === 'function') {
61+
setImmediate(() => callback(error))
62+
}
63+
64+
return reject(error)
65+
}
66+
67+
items = items || []
68+
const hasMore = items.length === limit + 1
69+
70+
if (hasMore) {
71+
items.pop()
72+
}
73+
74+
items = reverse ? items.reverse() : items
75+
76+
const results = {
77+
items,
78+
hasMore
79+
}
80+
81+
if (typeof callback === 'function') {
82+
setImmediate(() => callback(null, results))
83+
}
84+
85+
return resolve(results)
86+
}))
87+
}
88+
}

0 commit comments

Comments
 (0)